free(cxt->helper);
free(cxt->orig_user);
free(cxt->subdir);
- free(cxt->tmptgt);
cxt->fs = NULL;
cxt->mtab = NULL;
cxt->mountflags = 0;
cxt->user_mountflags = 0;
cxt->mountdata = NULL;
- cxt->tmptgt = NULL;
cxt->subdir = NULL;
cxt->flags = MNT_FL_DEFAULT;
goto failed;
if (strdup_between_structs(n, o, subdir))
goto failed;
- if (strdup_between_structs(n, o, tmptgt))
- goto failed;
n->mountflags = o->mountflags;
n->mountdata = o->mountdata;
cxt->subdir = strndup(dir, sz);
if (!cxt->subdir)
*rc = -ENOMEM;
- else if (asprintf(&cxt->tmptgt, "%s/mount.%d", MNT_TMPDIR, getpid()) < 0)
- *rc = -ENOMEM;
return *rc == 0;
}
&& (cxt->user_mountflags & MNT_MS_XFSTABCOMM)
&& is_subdir_required(cxt, &rc)) {
- DBG(CXT, ul_debugobj(cxt, "subdir %s required, temporary target: %s",
- cxt->subdir, cxt->tmptgt));
+ DBG(CXT, ul_debugobj(cxt, "subdir %s required", cxt->subdir));
}
/* create unhared temporary target */
if (cxt->subdir) {
- rc = mnt_unshared_mkdir(cxt->tmptgt,
- S_IRWXU, &old_ns_fd);
+ rc = mnt_tmptgt_unshare(&old_ns_fd);
if (rc)
return rc;
- target = cxt->tmptgt;
+ target = MNT_PATH_TMPTGT;
}
DBG(CXT, ul_debugobj(cxt, "mount(2) "
*/
if (cxt->subdir) {
target = mnt_fs_get_target(cxt->fs);
- rc = do_mount_subdir(cxt, cxt->tmptgt, cxt->subdir, target);
+ rc = do_mount_subdir(cxt, MNT_PATH_TMPTGT, cxt->subdir, target);
if (rc)
goto done;
- mnt_unshared_rmdir(cxt->tmptgt, old_ns_fd);
+ mnt_tmptgt_cleanup(old_ns_fd);
old_ns_fd = -1;
}
}
done:
if (old_ns_fd >= 0)
- mnt_unshared_rmdir(cxt->tmptgt, old_ns_fd);
+ mnt_tmptgt_cleanup(old_ns_fd);
return rc;
}
#define MNT_MNTTABDIR_EXT ".fstab"
/* library private paths */
-#define MNT_TMPDIR "/tmp/mount"
#define MNT_RUNTIME_TOPDIR "/run"
-
+/* private userspace mount table */
#define MNT_PATH_UTAB MNT_RUNTIME_TOPDIR "/mount/utab"
+/* temporary mount target */
+#define MNT_PATH_TMPTGT MNT_RUNTIME_TOPDIR "/mount/tmptgt"
#define MNT_UTAB_HEADER "# libmount utab file\n"
extern int mnt_stat_mountpoint(const char *target, struct stat *st);
extern int mnt_lstat_mountpoint(const char *target, struct stat *st);
-extern int mnt_unshared_mkdir(const char *path, mode_t mode, int *old_ns_fd);
-extern int mnt_unshared_rmdir(const char *path, int old_ns_fd);
+extern int mnt_tmptgt_unshare(int *old_ns_fd);
+extern int mnt_tmptgt_cleanup(int old_ns_fd);
/* tab.c */
extern int is_mountinfo(struct libmnt_table *tb);
char *optstr_pattern; /* for mnt_match_options() */
char *subdir; /* X-mount.subdir= */
- char *tmptgt; /* (unshared) private mount target */
struct libmnt_fs *fs; /* filesystem description (type, mountpoint, device, ...) */
struct libmnt_fs *fs_template; /* used for @fs on mnt_reset_context() */
}
/*
- * like ul_mkdir_p(), but create a new namespace and mark (bind mount)
- * the directory as private.
+ * Initialize MNT_PATH_TMPTGT; mkdir, create a new namespace and
+ * mark (bind mount) the directory as private.
*/
-int mnt_unshared_mkdir(const char *path, mode_t mode, int *old_ns_fd)
+int mnt_tmptgt_unshare(int *old_ns_fd)
{
int rc = 0, fd = -1, mounted = 0;
- *old_ns_fd = -1;
+ assert(old_ns_fd);
- if (!path || !old_ns_fd)
- return -EINVAL;
+ *old_ns_fd = -1;
/* create directory */
- rc = ul_mkdir_p(path, mode);
+ rc = ul_mkdir_p(MNT_PATH_TMPTGT, S_IRWXU);
if (rc)
goto fail;
goto fail;
/* make the directory private */
- mounted = mount(path, path, "none", MS_BIND, NULL) == 0;
+ mounted = mount(MNT_PATH_TMPTGT, MNT_PATH_TMPTGT, "none", MS_BIND, NULL) == 0;
if (!mounted)
goto fail;
- if (mount("none", path, NULL, MS_PRIVATE, NULL) != 0)
+ if (mount("none", MNT_PATH_TMPTGT, NULL, MS_PRIVATE, NULL) != 0)
goto fail;
- DBG(UTILS, ul_debug(" %s unshared", path));
+ DBG(UTILS, ul_debug(MNT_PATH_TMPTGT " unshared"));
*old_ns_fd = fd;
return 0;
fail:
if (rc == 0)
rc = errno ? -errno : -EINVAL;
if (mounted)
- umount(path);
+ umount(MNT_PATH_TMPTGT);
if (fd >= 0) {
setns(fd, CLONE_NEWNS); /* restore original NS */
close(fd);
}
- rmdir(path);
- DBG(UTILS, ul_debug(" %s unshare failed", path));
+ DBG(UTILS, ul_debug(MNT_PATH_TMPTGT " unshare failed"));
return rc;
}
/*
- * umount, rmdir and switch back to old namespace
+ * Clean up MNT_PATH_TMPTGT; umount and switch back to old namespace
*/
-int mnt_unshared_rmdir(const char *path, int old_ns_fd)
+int mnt_tmptgt_cleanup(int old_ns_fd)
{
- if (!path)
- return -EINVAL;
-
- umount(path);
- rmdir(path);
+ umount(MNT_PATH_TMPTGT);
if (old_ns_fd >= 0) {
setns(old_ns_fd, CLONE_NEWNS);
close(old_ns_fd);
}
- DBG(UTILS, ul_debug(" %s removed", path));
+ DBG(UTILS, ul_debug(MNT_PATH_TMPTGT " cleanup done"));
return 0;
}