static int context_init_paths(struct libmnt_context *cxt, int writable)
{
+ struct libmnt_ns *ns_old;
+
assert(cxt);
#ifdef USE_LIBMOUNT_SUPPORT_MTAB
cxt->mtab_writable = 0;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
#ifdef USE_LIBMOUNT_SUPPORT_MTAB
mnt_has_regular_mtab(&cxt->mtab_path, &cxt->mtab_writable);
if (!cxt->mtab_writable)
/* use /run/mount/utab if /etc/mtab is useless */
mnt_has_regular_utab(&cxt->utab_path, &cxt->utab_writable);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
cxt->flags |= MNT_FL_TABPATHS_CHECKED;
return 0;
}
*/
int mnt_context_get_fstab(struct libmnt_context *cxt, struct libmnt_table **tb)
{
+ struct libmnt_ns *ns_old;
+
if (!cxt)
return -EINVAL;
if (!cxt->fstab) {
return -ENOMEM;
if (cxt->table_errcb)
mnt_table_set_parser_errcb(cxt->fstab, cxt->table_errcb);
+
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
mnt_table_set_cache(cxt->fstab, mnt_context_get_cache(cxt));
rc = mnt_table_parse_fstab(cxt->fstab, NULL);
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (rc)
return rc;
}
*/
int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
{
+ int rc = 0;
+ struct libmnt_ns *ns_old = NULL;
+
if (!cxt)
return -EINVAL;
if (!cxt->mtab) {
- int rc;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
context_init_paths(cxt, 0);
cxt->mtab = mnt_new_table();
- if (!cxt->mtab)
- return -ENOMEM;
+ if (!cxt->mtab) {
+ rc = -ENOMEM;
+ goto end;
+ }
if (cxt->table_errcb)
mnt_table_set_parser_errcb(cxt->mtab, cxt->table_errcb);
else
rc = mnt_table_parse_mtab(cxt->mtab, cxt->mtab_path);
if (rc)
- return rc;
+ goto end;
}
if (tb)
DBG(CXT, ul_debugobj(cxt, "mtab requested [nents=%d]",
mnt_table_get_nents(cxt->mtab)));
- return 0;
+
+end:
+ if (ns_old && !mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
+ return rc;
}
/*
struct libmnt_cache *cache = NULL;
char *cn_tgt = NULL;
int rc;
+ struct libmnt_ns *ns_old;
+
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
if (mnt_context_is_nocanonicalize(cxt))
mnt_context_set_tabfilter(cxt, mtab_filter, (void *) tgt);
rc = mnt_context_get_mtab(cxt, mtab);
mnt_context_set_tabfilter(cxt, NULL, NULL);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (cn_tgt && !cache)
free(cn_tgt);
const char *filename, struct libmnt_table **tb)
{
int rc;
+ struct libmnt_ns *ns_old;
if (!cxt || !tb)
return -EINVAL;
if (cxt->table_errcb)
mnt_table_set_parser_errcb(*tb, cxt->table_errcb);
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = mnt_table_parse_file(*tb, filename);
+
if (rc) {
mnt_unref_table(*tb);
- return rc;
+ goto end;
}
mnt_table_set_cache(*tb, mnt_context_get_cache(cxt));
- return 0;
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
+ return rc;
}
/**
struct libmnt_cache *cache;
const char *t, *v, *src;
int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
DBG(CXT, ul_debugobj(cxt, "srcpath '%s'", src));
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
cache = mnt_context_get_cache(cxt);
if (!mnt_fs_get_tag(cxt->fs, &t, &v)) {
if (rc) {
DBG(CXT, ul_debugobj(cxt, "failed to prepare srcpath [rc=%d]", rc));
- return rc;
+ goto end;
}
if (!path)
if ((cxt->mountflags & (MS_BIND | MS_MOVE | MS_REMOUNT))
|| mnt_fs_is_pseudofs(cxt->fs)) {
DBG(CXT, ul_debugobj(cxt, "REMOUNT/BIND/MOVE/pseudo FS source: %s", path));
- return rc;
+ goto end;
}
/*
if (mnt_context_is_loopdev(cxt)) {
rc = mnt_context_setup_loopdev(cxt);
if (rc)
- return rc;
+ goto end;
}
DBG(CXT, ul_debugobj(cxt, "final srcpath '%s'",
mnt_fs_get_source(cxt->fs)));
- return 0;
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+ return rc;
}
/* create a mountpoint if X-mount.mkdir[=<mode>] specified */
const char *tgt;
struct libmnt_cache *cache;
int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
if (!tgt)
return 0;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
/* mkdir target */
if (cxt->action == MNT_ACT_MOUNT
&& !mnt_context_is_restricted(cxt)
cxt->user_mountflags & MNT_MS_XFSTABCOMM)) {
rc = mkdir_target(tgt, cxt->fs);
- if (rc)
+ if (rc) {
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc; /* mkdir or parse error */
+ }
}
/* canonicalize the path */
rc = mnt_fs_set_target(cxt->fs, path);
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (rc)
DBG(CXT, ul_debugobj(cxt, "failed to prepare target '%s'", tgt));
else
int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type)
{
int rc = 0;
+ struct libmnt_ns *ns_old;
const char *dev = mnt_fs_get_srcpath(cxt->fs);
*type = NULL;
if (!dev)
goto done;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
if (access(dev, F_OK) == 0) {
struct libmnt_cache *cache = mnt_context_get_cache(cxt);
int ambi = 0;
*type = strdup("cifs");
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
done:
return rc;
}
{
char search_path[] = FS_SEARCH_PATH; /* from config.h */
char *p = NULL, *path;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
|| mnt_fs_is_swaparea(cxt->fs))
return 0;
+ ns_old = mnt_context_switch_origin_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
path = strtok_r(search_path, ":", &p);
while (path) {
char helper[PATH_MAX];
if (rc)
continue;
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
free(cxt->helper);
cxt->helper = strdup(helper);
if (!cxt->helper)
return 0;
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return 0;
}
int mnt_context_update_tabs(struct libmnt_context *cxt)
{
unsigned long fl;
+ int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
return 0;
}
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
/* check utab update when external helper executed */
if (mnt_context_helper_executed(cxt)
&& mnt_context_get_helper_status(cxt) == 0
if (mnt_update_already_done(cxt->update, cxt->lock)) {
DBG(CXT, ul_debugobj(cxt, "don't update: error evaluate or already updated"));
- return 0;
+ goto end;
}
} else if (cxt->helper) {
DBG(CXT, ul_debugobj(cxt, "don't update: external helper"));
- return 0;
+ goto end;
}
if (cxt->syscall_status != 0
mnt_context_get_helper_status(cxt) == 0)) {
DBG(CXT, ul_debugobj(cxt, "don't update: syscall/helper failed/not called"));
- return 0;
+ goto end;
}
fl = mnt_update_get_mflags(cxt->update);
mnt_update_force_rdonly(cxt->update,
cxt->mountflags & MS_RDONLY);
- return mnt_update_table(cxt->update, cxt->lock);
+ rc = mnt_update_table(cxt->update, cxt->lock);
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+ return rc;
}
static int apply_table(struct libmnt_context *cxt, struct libmnt_table *tb,
int mnt_context_apply_fstab(struct libmnt_context *cxt)
{
int rc = -1, isremount = 0, iscmdbind = 0;
+ struct libmnt_ns *ns_old;
struct libmnt_table *tab = NULL;
const char *src = NULL, *tgt = NULL;
unsigned long mflags = 0;
/* let's initialize cxt->fs */
ignore_result( mnt_context_get_fs(cxt) );
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
/* try fstab */
if (cxt->optsmode & MNT_OMODE_FSTAB) {
DBG(CXT, ul_debugobj(cxt, "trying to apply fstab (src=%s, target=%s)", src, tgt));
if (!rc)
rc = apply_table(cxt, tab, MNT_ITER_BACKWARD);
}
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (rc) {
if (!mnt_context_is_restricted(cxt)
&& tgt && !src
{
struct libmnt_table *mtab, *orig;
int rc;
+ struct libmnt_ns *ns_old;
if (!cxt || !fs || !mounted)
return -EINVAL;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
orig = cxt->mtab;
rc = mnt_context_get_mtab(cxt, &mtab);
if (rc == -ENOENT && mnt_fs_streq_target(fs, "/proc") &&
return rc;
*mounted = mnt_table_is_fs_mounted(mtab, fs);
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return 0;
}
static int fix_optstr(struct libmnt_context *cxt)
{
int rc = 0;
+ struct libmnt_ns *ns_old;
char *next;
char *name, *val;
size_t namesz, valsz;
goto done;
}
- if (!rc && cxt->restricted && (cxt->user_mountflags & MNT_MS_USER))
+
+ if (!rc && cxt->restricted && (cxt->user_mountflags & MNT_MS_USER)) {
+ ns_old = mnt_context_switch_origin_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = mnt_optstr_fix_user(&fs->user_optstr);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+ }
+
/* refresh merged optstr */
free(fs->optstr);
fs->optstr = NULL;
if (setuid(getuid()) < 0)
_exit(EXIT_FAILURE);
+ if (!mnt_context_switch_origin_ns(cxt))
+ _exit(EXIT_FAILURE);
+
type = mnt_fs_get_fstype(cxt->fs);
args[i++] = cxt->helper; /* 1 */
int neg = pattern && strncmp(pattern, "no", 2) == 0;
int rc = -EINVAL;
char **filesystems, **fp;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
/*
* Apply pattern to /etc/filesystems and /proc/filesystems
*/
+ ns_old = mnt_context_switch_origin_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
rc = mnt_get_filesystems(&filesystems, neg ? pattern : NULL);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
if (rc)
return rc;
int mnt_context_prepare_mount(struct libmnt_context *cxt)
{
int rc = -EINVAL;
+ struct libmnt_ns *ns_old;
if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs))
return -EINVAL;
cxt->action = MNT_ACT_MOUNT;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
DBG(CXT, ul_debugobj(cxt, "mount: preparing"));
rc = mnt_context_apply_fstab(cxt);
rc = mnt_context_prepare_helper(cxt, "mount", NULL);
if (rc) {
DBG(CXT, ul_debugobj(cxt, "mount: preparing failed"));
- return rc;
+ goto end;
}
cxt->flags |= MNT_FL_PREPARED;
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}
{
const char *type;
int res;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
if (!(cxt->flags & MNT_FL_MOUNTDATA))
cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs);
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
type = mnt_fs_get_fstype(cxt->fs);
if (type) {
if (strchr(type, ','))
}
}
#endif
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return res;
}
int mnt_context_mount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
assert(cxt->helper_exec_status == 1);
assert(cxt->syscall_status == 1);
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
again:
rc = mnt_context_prepare_mount(cxt);
if (!rc)
goto again;
}
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc;
}
unsigned long mflags = 0;
char *mnt = NULL, *p;
int rc = 0;
+ struct libmnt_ns *ns_old;
+
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
if (!dir)
return 0;
&& (mflags & MS_SHARED);
done:
free(mnt);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc;
}
struct libmnt_fs **pfs)
{
int rc;
+ struct libmnt_ns *ns_old;
struct libmnt_table *mtab = NULL;
struct libmnt_fs *fs;
char *loopdev = NULL;
return 1;
}
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
try_loopdev:
fs = mnt_table_find_target(mtab, tgt, MNT_ITER_BACKWARD);
if (!fs && mnt_context_is_swapmatch(cxt)) {
if (pfs)
*pfs = fs;
free(loopdev);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
DBG(CXT, ul_debugobj(cxt, "umount fs: %s", fs ? mnt_fs_get_target(fs) :
"<not found>"));
return fs ? 0 : 1;
err:
free(loopdev);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc;
}
char *curr_user;
char *mtab_user = NULL;
size_t sz;
+ struct libmnt_ns *ns_old;
DBG(CXT, ul_debugobj(cxt,
"umount: checking user=<username> from mtab"));
+ ns_old = mnt_context_switch_origin_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
curr_user = mnt_get_username(getuid());
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (!curr_user) {
DBG(CXT, ul_debugobj(cxt, "umount %s: cannot "
"convert %d to username", tgt, getuid()));
if (setuid(getuid()) < 0)
_exit(EXIT_FAILURE);
+ if (!mnt_context_switch_origin_ns(cxt))
+ _exit(EXIT_FAILURE);
+
type = mnt_fs_get_fstype(cxt->fs);
args[i++] = cxt->helper; /* 1 */
int mnt_context_prepare_umount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs))
return -EINVAL;
cxt->helper = NULL;
cxt->action = MNT_ACT_UMOUNT;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = lookup_umount_fs(cxt);
if (!rc)
rc = mnt_context_merge_mflags(cxt);
return rc;
}
cxt->flags |= MNT_FL_PREPARED;
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}
int mnt_context_do_umount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
assert((cxt->action == MNT_ACT_UMOUNT));
assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = do_umount(cxt);
if (rc)
- return rc;
+ goto end;
if (mnt_context_get_status(cxt) && !mnt_context_is_fake(cxt)) {
/*
cxt->mountflags, NULL, cxt->fs);
}
}
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}
int mnt_context_umount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
DBG(CXT, ul_debugobj(cxt, "umount: %s", mnt_context_get_target(cxt)));
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = mnt_context_prepare_umount(cxt);
if (!rc)
rc = mnt_context_prepare_update(cxt);
rc = mnt_context_do_umount(cxt);
if (!rc)
rc = mnt_context_update_tabs(cxt);
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}