summaryrefslogtreecommitdiffstats
path: root/shlibs
diff options
context:
space:
mode:
authorKarel Zak2010-12-14 23:50:55 +0100
committerKarel Zak2011-01-03 12:28:47 +0100
commit76a06ca4cdba29ca54e418a61e8efc811ac608aa (patch)
tree5832716e31d32aa10ad46f33c72a5ea7af2fa810 /shlibs
parentmount: read mtab by libmount (diff)
downloadkernel-qcow2-util-linux-76a06ca4cdba29ca54e418a61e8efc811ac608aa.tar.gz
kernel-qcow2-util-linux-76a06ca4cdba29ca54e418a61e8efc811ac608aa.tar.xz
kernel-qcow2-util-linux-76a06ca4cdba29ca54e418a61e8efc811ac608aa.zip
libmount: use separate buffer for userspace options, add mount attributes
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs')
-rw-r--r--shlibs/mount/src/context.c67
-rw-r--r--shlibs/mount/src/context_mount.c59
-rw-r--r--shlibs/mount/src/context_umount.c23
-rw-r--r--shlibs/mount/src/fs.c533
-rw-r--r--shlibs/mount/src/mount.h.in55
-rw-r--r--shlibs/mount/src/mount.sym58
-rw-r--r--shlibs/mount/src/mountP.h7
-rw-r--r--shlibs/mount/src/optmap.c2
-rw-r--r--shlibs/mount/src/optstr.c111
-rw-r--r--shlibs/mount/src/tab_parse.c91
-rw-r--r--shlibs/mount/src/tab_update.c71
11 files changed, 702 insertions, 375 deletions
diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c
index 4fe2eabf4..59e8bd920 100644
--- a/shlibs/mount/src/context.c
+++ b/shlibs/mount/src/context.c
@@ -93,7 +93,8 @@ void mnt_free_context(mnt_context *cxt)
* mnt_context_set_fstab(cxt, NULL);
* mnt_context_set_cache(cxt, NULL);
* mnt_context_set_fstype_pattern(cxt, NULL);
- * mnt_context_set_optstr_pattern(cxt, NULL);
+ * mnt_context_set_options_pattern(cxt, NULL);
+ *
*
* to reset these stuff.
*
@@ -358,8 +359,8 @@ int mnt_context_enable_loopdel(mnt_context *cxt, int enable)
* overwrite the private @fs with an external instance. Note that the external
* @fs instance is not deallocated by mnt_free_context() or mnt_reset_context().
*
- * The @fs will be modified by mnt_context_set_{source,target,optstr,fstype}
- * functions, Ft the @fs is NULL then all current FS specific setting (source,
+ * The @fs will be modified by mnt_context_set_{source,target,options,fstype}
+ * functions, If the @fs is NULL then all current FS specific setting (source,
* target, etc., exclude spec) is reseted.
*
* Returns: 0 on success, negative number in case of error.
@@ -376,6 +377,16 @@ int mnt_context_set_fs(mnt_context *cxt, mnt_fs *fs)
return 0;
}
+/**
+ * mnt_context_get_fs:
+ * @cxt: mount context
+ *
+ * The FS contains the basic description of mountpoint, fs type and so on.
+ * Note that the FS is modified by mnt_context_set_{source,target,options,fstype}
+ * functions.
+ *
+ * Returns: pointer to FS description or NULL in case of calloc() errrr.
+ */
mnt_fs *mnt_context_get_fs(mnt_context *cxt)
{
if (!cxt)
@@ -429,27 +440,27 @@ int mnt_context_set_fstype(mnt_context *cxt, const char *fstype)
}
/**
- * mnt_context_set_optstr:
+ * mnt_context_set_options:
* @cxt: mount context
- * @optstr: comma delimited mount options
+ * @options: comma delimited mount options
*
* Returns: 0 on success, negative number in case of error.
*/
-int mnt_context_set_optstr(mnt_context *cxt, const char *optstr)
+int mnt_context_set_options(mnt_context *cxt, const char *optstr)
{
- return mnt_fs_set_optstr(mnt_context_get_fs(cxt), optstr);
+ return mnt_fs_set_options(mnt_context_get_fs(cxt), optstr);
}
/**
- * mnt_context_append_optstr:
+ * mnt_context_append_options:
* @cxt: mount context
* @optstr: comma delimited mount options
*
* Returns: 0 on success, negative number in case of error.
*/
-int mnt_context_append_optstr(mnt_context *cxt, const char *optstr)
+int mnt_context_append_options(mnt_context *cxt, const char *optstr)
{
- return mnt_fs_append_optstr(mnt_context_get_fs(cxt), optstr);
+ return mnt_fs_append_options(mnt_context_get_fs(cxt), optstr);
}
/**
@@ -478,7 +489,7 @@ int mnt_context_set_fstype_pattern(mnt_context *cxt, const char *pattern)
}
/**
- * mnt_context_set_optstr_pattern:
+ * mnt_context_set_options_pattern:
* @cxt: mount context
* @pattern: options pattern (or NULL to reset the current setting)
*
@@ -486,7 +497,7 @@ int mnt_context_set_fstype_pattern(mnt_context *cxt, const char *pattern)
*
* Returns: 0 on success, negative number in case of error.
*/
-int mnt_context_set_optstr_pattern(mnt_context *cxt, const char *pattern)
+int mnt_context_set_options_pattern(mnt_context *cxt, const char *pattern)
{
char *p = NULL;
@@ -693,7 +704,7 @@ mnt_lock *mnt_context_get_lock(mnt_context *cxt)
*
* rather than
*
- * mnt_context_set_optstr(cxt, "noexec,nosuid");
+ * mnt_context_set_options(cxt, "noexec,nosuid");
*
* these both calls have the same effect.
*
@@ -725,9 +736,10 @@ int mnt_context_get_mountflags(mnt_context *cxt, unsigned long *flags)
*flags = 0;
if (!(cxt->flags & MNT_FL_MOUNTFLAGS_MERGED) && cxt->fs) {
- const char *o = mnt_fs_get_optstr(cxt->fs);
+ const char *o = mnt_fs_get_vfs_options(cxt->fs);
if (o)
- rc = mnt_optstr_get_mountflags(o, flags);
+ rc = mnt_optstr_get_flags(o, flags,
+ mnt_get_builtin_optmap(MNT_LINUX_MAP));
}
if (!rc)
*flags |= cxt->mountflags;
@@ -769,9 +781,10 @@ int mnt_context_get_userspace_mountflags(mnt_context *cxt, unsigned long *flags)
*flags = 0;
if (!(cxt->flags & MNT_FL_MOUNTFLAGS_MERGED) && cxt->fs) {
- const char *o = mnt_fs_get_optstr(cxt->fs);
+ const char *o = mnt_fs_get_userspace_options(cxt->fs);
if (o)
- rc = mnt_optstr_get_userspace_mountflags(o, flags);
+ rc = mnt_optstr_get_flags(o, flags,
+ mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
}
if (!rc)
*flags |= cxt->user_mountflags;
@@ -1025,6 +1038,11 @@ int mnt_context_merge_mountflags(mnt_context *cxt)
return rc;
cxt->mountflags = fl;
+ /* TODO: if cxt->fs->fs_optstr contains 'ro' then set the MS_RDONLY to
+ * mount flags, it's possible that superblock is read-only, but VFS is
+ * read-write.
+ */
+
fl = 0;
rc = mnt_context_get_userspace_mountflags(cxt, &fl);
if (rc)
@@ -1172,9 +1190,16 @@ static int apply_tab(mnt_context *cxt, mnt_tab *tb, int direction)
if (!rc && !mnt_fs_get_fstype(cxt->fs))
rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs));
- if (!rc && cxt->optsmode != MNT_OPTSMODE_IGNORE)
- rc = mnt_fs_prepend_optstr(cxt->fs, mnt_fs_get_optstr(fs));
-
+ if (!rc && cxt->optsmode != MNT_OPTSMODE_IGNORE) {
+ rc = mnt_fs_prepend_vfs_options(cxt->fs,
+ mnt_fs_get_vfs_options(fs));
+ if (!rc)
+ rc = mnt_fs_prepend_fs_options(cxt->fs,
+ mnt_fs_get_fs_options(fs));
+ if (!rc)
+ rc = mnt_fs_prepend_userspace_options(cxt->fs,
+ mnt_fs_get_userspace_options(fs));
+ }
if (!rc)
cxt->flags |= MNT_FL_TAB_APPLIED;
@@ -1293,7 +1318,7 @@ int test_mount(struct mtest *ts, int argc, char *argv[])
return -ENOMEM;
if (!strcmp(argv[idx], "-o")) {
- mnt_context_set_optstr(cxt, argv[idx + 1]);
+ mnt_context_set_options(cxt, argv[idx + 1]);
idx += 2;
}
if (!strcmp(argv[idx], "-t")) {
diff --git a/shlibs/mount/src/context_mount.c b/shlibs/mount/src/context_mount.c
index fb593c3fd..b5a339f5f 100644
--- a/shlibs/mount/src/context_mount.c
+++ b/shlibs/mount/src/context_mount.c
@@ -30,9 +30,10 @@
static int fix_optstr(mnt_context *cxt)
{
int rc = 0, rem_se = 0;
- char *next, **optstr;
+ char *next;
char *name, *val;
size_t namesz, valsz;
+ mnt_fs *fs;
assert(cxt);
assert(cxt->fs);
@@ -45,18 +46,16 @@ static int fix_optstr(mnt_context *cxt)
DBG(CXT, mnt_debug_h(cxt, "mount: fixing optstr"));
- /*
- * we directly work with optstr pointer here
- */
- optstr = &cxt->fs->optstr;
- if (!optstr)
+ fs = cxt->fs;
+
+ if (!mnt_fs_get_vfs_options(fs) && !mnt_fs_get_userspace_options(fs))
return 0;
/* The propagation flags should not be used together with any other flags */
if (cxt->mountflags & MS_PROPAGATION)
cxt->mountflags &= MS_PROPAGATION;
- if (*optstr && !mnt_optstr_get_option(*optstr, "user", &val, &valsz)) {
+ if (!mnt_optstr_get_option(fs->user_optstr, "user", &val, &valsz)) {
if (val) {
cxt->orig_user = strndup(val, valsz);
if (!cxt->orig_user) {
@@ -70,29 +69,27 @@ static int fix_optstr(mnt_context *cxt)
/*
* Sync mount options with mount flags
*/
- rc = mnt_optstr_apply_flags(optstr, cxt->mountflags,
+ rc = mnt_optstr_apply_flags(&fs->vfs_optstr, cxt->mountflags,
mnt_get_builtin_optmap(MNT_LINUX_MAP));
if (rc)
goto done;
- rc = mnt_optstr_apply_flags(optstr, cxt->user_mountflags,
+ rc = mnt_optstr_apply_flags(&fs->user_optstr, cxt->user_mountflags,
mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
if (rc)
goto done;
- next = *optstr;
+ next = fs->fs_optstr;
#ifdef HAVE_LIBSELINUX
rem_se = (cxt->mountflags & MS_REMOUNT) || !is_selinux_enabled();
#endif
- DBG(CXT, mnt_debug_h(cxt, "fixing mount options: '%s'", *optstr));
-
while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) {
if (namesz == 3 && !strncmp(name, "uid", 3))
- rc = mnt_optstr_fix_uid(optstr, val, valsz, &next);
+ rc = mnt_optstr_fix_uid(&fs->fs_optstr, val, valsz, &next);
else if (namesz == 3 && !strncmp(name, "gid", 3))
- rc = mnt_optstr_fix_gid(optstr, val, valsz, &next);
+ rc = mnt_optstr_fix_gid(&fs->fs_optstr, val, valsz, &next);
#ifdef HAVE_LIBSELINUX
else if (namesz >= 7 && (!strncmp(name, "context", 7) ||
!strncmp(name, "fscontext", 9) ||
@@ -101,51 +98,44 @@ static int fix_optstr(mnt_context *cxt)
if (rem_se) {
/* remove context= option */
next = name;
- rc = mnt_optstr_remove_option_at(optstr,
+ rc = mnt_optstr_remove_option_at(&fs->fs_optstr,
name, val + valsz);
} else
- rc = mnt_optstr_fix_secontext(optstr,
+ rc = mnt_optstr_fix_secontext(&fs->fs_optstr,
val, valsz, &next);
}
#endif
- else if (namesz == 4 && (cxt->user_mountflags && MNT_MS_USER) &&
- !strncmp(name, "user", 4)) {
-
- rc = mnt_optstr_fix_user(optstr,
- val ? val : name + namesz,
- valsz, &next);
- }
if (rc)
goto done;
}
+ if (!rc && cxt->user_mountflags && MNT_MS_USER)
+ rc = mnt_optstr_fix_user(&fs->fs_optstr);
+
done:
- __mnt_fs_set_optstr_ptr(cxt->fs, *optstr, TRUE);
- DBG(CXT, mnt_debug_h(cxt, "fixed options [rc=%d]: '%s'", rc, *optstr));
+ DBG(CXT, mnt_debug_h(cxt, "fixed options [rc=%d]: "
+ "vfs='%s' fs='%s' user='%s'", rc,
+ fs->vfs_optstr, fs->fs_optstr, fs->user_optstr));
return rc;
}
/*
* Converts already evalulated and fixed options to the form that is compatible
* with /sbin/mount.<type> helpers.
- *
- * Retursn newly allocated string.
*/
static int generate_helper_optstr(mnt_context *cxt, char **optstr)
{
- const char *o;
int rc = 0;
assert(cxt);
assert(cxt->fs);
assert(optstr);
- *optstr = NULL;
- o = mnt_fs_get_optstr(cxt->fs);
+ *optstr = mnt_fs_strdup_options(cxt->fs);
+ if (!*optstr)
+ return -ENOMEM;
- if (o)
- rc = mnt_optstr_append_option(optstr, o, NULL);
- if (!rc && (cxt->flags & MNT_FL_SAVED_USER))
+ if (cxt->flags & MNT_FL_SAVED_USER)
rc = mnt_optstr_set_option(optstr, "user", cxt->orig_user);
if (rc) {
free(*optstr);
@@ -323,7 +313,6 @@ static int do_mount(mnt_context *cxt, const char *try_type)
assert(cxt->fs);
assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
-
if (try_type && !cxt->helper) {
rc = mnt_context_prepare_helper(cxt, "mount", try_type);
if (!rc)
@@ -477,7 +466,7 @@ int mnt_context_do_mount(mnt_context *cxt)
DBG(CXT, mnt_debug_h(cxt, "mount: do mount"));
if (!(cxt->flags & MNT_FL_MOUNTDATA))
- cxt->mountdata = (char *) mnt_fs_get_fs_optstr(cxt->fs);
+ cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs);
type = mnt_fs_get_fstype(cxt->fs);
if (type)
diff --git a/shlibs/mount/src/context_umount.c b/shlibs/mount/src/context_umount.c
index ec5713004..b4da7373a 100644
--- a/shlibs/mount/src/context_umount.c
+++ b/shlibs/mount/src/context_umount.c
@@ -81,8 +81,14 @@ static int lookup_umount_fs(mnt_context *cxt)
if (!rc && !mnt_fs_get_fstype(cxt->fs))
rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs));
+
+ if (!rc)
+ rc = mnt_fs_set_vfs_options(cxt->fs, mnt_fs_get_vfs_options(fs));
if (!rc)
- rc = mnt_fs_set_optstr(cxt->fs, mnt_fs_get_optstr(fs));
+ rc = mnt_fs_set_fs_options(cxt->fs, mnt_fs_get_fs_options(fs));
+ if (!rc)
+ rc = mnt_fs_set_userspace_options(cxt->fs, mnt_fs_get_userspace_options(fs));
+
if (!rc && mnt_fs_get_bindsrc(fs))
rc = mnt_fs_set_bindsrc(cxt->fs, mnt_fs_get_bindsrc(fs));
@@ -112,7 +118,7 @@ static int mnt_loopdev_associated_fs(const char *devname, mnt_fs *fs)
return 0;
/* check for offset option in @fs */
- optstr = (char *) mnt_fs_get_optstr(fs);
+ optstr = (char *) mnt_fs_get_userspace_options(fs);
if (optstr && !mnt_optstr_get_option(optstr, "offset=", &val, &valsz)) {
int rc;
@@ -166,7 +172,7 @@ static int evaluate_permissions(mnt_context *cxt)
(cxt->user_mountflags & MNT_MS_UHELPER)) {
char *suffix = NULL;
- char *o = (char *) mnt_fs_get_optstr(cxt->fs);
+ char *o = (char *) mnt_fs_get_userspace_options(cxt->fs);
size_t valsz;
rc = mnt_optstr_get_option(o, "uhelper", &suffix, &valsz);
@@ -236,11 +242,12 @@ static int evaluate_permissions(mnt_context *cxt)
* The options `user', `owner' and `group' only allow unmounting by the
* user that mounted (visible in mtab).
*/
- optstr = mnt_fs_get_optstr(fs); /* FSTAB mount options! */
+ optstr = mnt_fs_get_userspace_options(fs); /* FSTAB mount options! */
if (!optstr)
goto eperm;
- if (mnt_optstr_get_userspace_mountflags(optstr, &u_flags))
+ if (mnt_optstr_get_flags(optstr, &u_flags,
+ mnt_get_builtin_optmap(MNT_USERSPACE_MAP)))
goto eperm;
if (u_flags & MNT_MS_USERS) {
@@ -271,7 +278,7 @@ static int evaluate_permissions(mnt_context *cxt)
}
/* get options from mtab */
- optstr = mnt_fs_get_optstr(cxt->fs);
+ optstr = mnt_fs_get_userspace_options(cxt->fs);
if (optstr && !mnt_optstr_get_option((char *) optstr,
"user", &mtab_user, &sz) && sz)
ok = !strncmp(curr_user, mtab_user, sz);
@@ -491,7 +498,7 @@ int mnt_context_do_umount(mnt_context *cxt)
/*
* update options to handle remount to read-only
*/
- const char *o = mnt_fs_get_optstr(cxt->fs);
+ const char *o = mnt_fs_get_vfs_options(cxt->fs);
char *n = o ? strdup(o) : NULL;
DBG(CXT, mnt_debug_h(cxt, "fix remount-on-umount update"));
@@ -500,7 +507,7 @@ int mnt_context_do_umount(mnt_context *cxt)
mnt_optstr_remove_option(&n, "rw");
rc = mnt_optstr_prepend_option(&n, "ro", NULL);
if (!rc)
- rc = __mnt_fs_set_optstr_ptr(cxt->fs, n, FALSE);
+ rc = mnt_fs_set_vfs_options(cxt->fs, n);
/* refresh options in /etc/mtab as well */
if (!rc && cxt->update && cxt->mtab_writable)
diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c
index bcc537628..b8e9085d1 100644
--- a/shlibs/mount/src/fs.c
+++ b/shlibs/mount/src/fs.c
@@ -56,9 +56,10 @@ void mnt_free_fs(mnt_fs *fs)
free(fs->root);
free(fs->target);
free(fs->fstype);
- free(fs->optstr);
free(fs->vfs_optstr);
free(fs->fs_optstr);
+ free(fs->user_optstr);
+ free(fs->attrs);
free(fs);
}
@@ -125,12 +126,15 @@ mnt_fs *mnt_copy_fs(const mnt_fs *fs)
goto err;
if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, fstype)))
goto err;
- if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, optstr)))
- goto err;
if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, vfs_optstr)))
goto err;
if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, fs_optstr)))
goto err;
+ if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, user_optstr)))
+ goto err;
+ if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, attrs)))
+ goto err;
+
n->freq = fs->freq;
n->passno = fs->passno;
n->flags = fs->flags;
@@ -403,178 +407,499 @@ int mnt_fs_set_fstype(mnt_fs *fs, const char *fstype)
return rc;
}
+/*
+ * Merges @vfs and @fs options strings into a new string.
+ * This function cares about 'ro/rw' options. The 'ro' is
+ * always used if @vfs or @fs is read-only.
+ * For example:
+ *
+ * mnt_merge_optstr("rw,noexec", "ro,journal=update")
+ *
+ * returns: "ro,noexec,journal=update"
+ *
+ * mnt_merge_optstr("rw,noexec", "rw,journal=update")
+ *
+ * returns: "rw,noexec,journal=update"
+ */
+static char *merge_optstr(const char *vfs, const char *fs)
+{
+ char *res, *p;
+ size_t sz;
+ int ro = 0, rw = 0;
+
+ if (!vfs && !fs)
+ return NULL;
+ if (!vfs || !fs)
+ return strdup(fs ? fs : vfs);
+ if (!strcmp(vfs, fs))
+ return strdup(vfs); /* e.g. "aaa" and "aaa" */
+
+ /* leave space for leading "r[ow],", "," and trailing zero */
+ sz = strlen(vfs) + strlen(fs) + 5;
+ res = malloc(sz);
+ if (!res)
+ return NULL;
+ p = res + 3; /* make a room for rw/ro flag */
+
+ snprintf(p, sz - 3, "%s,%s", vfs, fs);
+
+ /* remove 'rw' flags */
+ rw += !mnt_optstr_remove_option(&p, "rw"); /* from vfs */
+ rw += !mnt_optstr_remove_option(&p, "rw"); /* from fs */
+
+ /* remove 'ro' flags if necessary */
+ if (rw != 2) {
+ ro += !mnt_optstr_remove_option(&p, "ro");
+ if (ro + rw < 2)
+ ro += !mnt_optstr_remove_option(&p, "ro");
+ }
+
+ if (!strlen(p))
+ memcpy(res, ro ? "ro" : "rw", 3);
+ else
+ memcpy(res, ro ? "ro," : "rw,", 3);
+ return res;
+}
+
/**
- * mnt_fs_get_optstr:
+ * mnt_fs_strdup_options:
* @fs: fstab/mtab/mountinfo entry pointer
*
- * Returns: pointer to mount option string with all options (FS and VFS)
+ * Merges all mount options (VFS, FS and userspace) to the one options string
+ * and returns the result. This function does not modigy @fs.
+ *
+ * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
*/
-const char *mnt_fs_get_optstr(mnt_fs *fs)
+char *mnt_fs_strdup_options(mnt_fs *fs)
{
+ char *res;
+
assert(fs);
- return fs ? fs->optstr : NULL;
+
+ errno = 0;
+ res = merge_optstr(fs->vfs_optstr, fs->fs_optstr);
+ if (errno)
+ return NULL;
+ if (fs->user_optstr) {
+ if (mnt_optstr_append_option(&res, fs->user_optstr, NULL)) {
+ free(res);
+ res = NULL;
+ }
+ }
+ return res;
}
-int __mnt_fs_set_optstr_ptr(mnt_fs *fs, char *ptr, int split)
+/**
+ * mnt_fs_set_options:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Splits @optstr to VFS, FS and userspace mount options and update relevat
+ * parts of @fs.
+ *
+ * Returns: 0 on success, or negative number icase of error.
+ */
+int mnt_fs_set_options(mnt_fs *fs, const char *optstr)
{
- char *v = NULL, *f = NULL;
+ char *v = NULL, *f = NULL, *u = NULL;
assert(fs);
if (!fs)
return -EINVAL;
- if (ptr) {
- int rc = 0;
-
- if (split)
- rc = mnt_split_optstr((char *) ptr, NULL, &v, &f, 0, 0);
+ if (optstr) {
+ int rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
if (rc)
return rc;
}
- if (ptr != fs->optstr)
- free(fs->optstr);
-
free(fs->fs_optstr);
free(fs->vfs_optstr);
+ free(fs->user_optstr);
- fs->optstr = ptr;
fs->fs_optstr = f;
fs->vfs_optstr = v;
+ fs->user_optstr = u;
return 0;
}
-int __mnt_fs_set_optstr(mnt_fs *fs, const char *optstr, int split)
+/**
+ * mnt_fs_append_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: mount options
+ *
+ * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
+ * of options.
+ *
+ * If @optstr is NULL then @fs is not modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_options(mnt_fs *fs, const char *optstr)
{
- char *p;
+ char *v = NULL, *f = NULL, *u = NULL;
int rc;
assert(fs);
- p = strdup(optstr);
- if (!p)
- return -ENOMEM;
- rc = __mnt_fs_set_optstr_ptr(fs, p, split);
- if (rc)
- free(p); /* error, deallocate */
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
+
+ rc = mnt_split_optstr((char *) optstr, &u, &v, &f, 0, 0);
+ if (!rc && v)
+ rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL);
+ if (!rc && f)
+ rc = mnt_optstr_append_option(&fs->fs_optstr, f, NULL);
+ if (!rc && u)
+ rc = mnt_optstr_append_option(&fs->user_optstr, u, NULL);
+
return rc;
}
/**
- * mnt_fs_set_optstr:
+ * mnt_fs_prepend_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: mount options
+ *
+ * Parses (splits) @optstr and prepands results to VFS, FS and userspace lists
+ * of options.
+ *
+ * If @optstr is NULL then @fs is not modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_options(mnt_fs *fs, const char *optstr)
+{
+ char *v = NULL, *f = NULL, *u = NULL;
+ int rc;
+
+ assert(fs);
+
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
+
+ rc = mnt_split_optstr((char *) optstr, &u, &v, &f, 0, 0);
+ if (!rc && v)
+ rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL);
+ if (!rc && f)
+ rc = mnt_optstr_prepend_option(&fs->fs_optstr, f, NULL);
+ if (!rc && u)
+ rc = mnt_optstr_prepend_option(&fs->user_optstr, u, NULL);
+
+ return rc;
+}
+
+/*
+ * mnt_fs_get_fs_options:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns: pointer to superblock (fs-depend) mount option string or NULL.
+ */
+const char *mnt_fs_get_fs_options(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->fs_optstr : NULL;
+}
+
+/**
+ * mnt_fs_set_fs_options:
* @fs: fstab/mtab/mountinfo entry
* @optstr: options string
*
- * This function creates a private copy of @optstr. The function also updates
- * VFS and FS mount options.
+ * Sets FS specific mount options.
*
* Returns: 0 on success or negative number in case of error.
*/
-int mnt_fs_set_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_set_fs_options(mnt_fs *fs, const char *optstr)
{
- return __mnt_fs_set_optstr(fs, optstr, TRUE);
+ char *p = NULL;
+
+ if (!fs)
+ return -EINVAL;
+ if (optstr) {
+ p = strdup(optstr);
+ if (!p)
+ return -ENOMEM;
+ }
+ free(fs->fs_optstr);
+ fs->fs_optstr = p;
+
+ return 0;
}
/**
- * mnt_fs_append_userspace_optstr:
+ * mnt_fs_append_fs_options:
* @fs: fstab/mtab/mountinfo entry
* @optstr: options string
*
- * This function appends @optstr to the current list of the mount options. The VFS and
- * FS mount options are not modified.
+ * Appends FS specific mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
*
* Returns: 0 on success or negative number in case of error.
*/
-int mnt_fs_append_userspace_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_append_fs_options(mnt_fs *fs, const char *optstr)
{
- assert(fs);
- if (!fs || !optstr)
+ if (!fs)
return -EINVAL;
- return mnt_optstr_append_option(&fs->optstr, optstr, NULL);
+ if (!optstr)
+ return 0;
+ return mnt_optstr_append_option(&fs->fs_optstr, optstr, NULL);
}
/**
- * mnt_fs_append_optstr:
+ * mnt_fs_prepend_fs_options:
* @fs: fstab/mtab/mountinfo entry
- * @optstr: mount options
+ * @optstr: options string
+ *
+ * Prepends FS specific mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
*
* Returns: 0 on success or negative number in case of error.
*/
-int mnt_fs_append_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_prepend_fs_options(mnt_fs *fs, const char *optstr)
{
- char *v = NULL, *f = NULL;
- int rc;
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
+ return mnt_optstr_prepend_option(&fs->fs_optstr, optstr, NULL);
+}
+
+/**
+ * mnt_fs_get_vfs_options:
+ * @fs: fstab/mtab entry pointer
+ *
+ * Returns: pointer to fs-independent (VFS) mount option string or NULL.
+ */
+const char *mnt_fs_get_vfs_options(mnt_fs *fs)
+{
assert(fs);
+ return fs ? fs->vfs_optstr : NULL;
+}
+
+/**
+ * mnt_fs_set_vfs_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Sets VFS mount options.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_set_vfs_options(mnt_fs *fs, const char *optstr)
+{
+ char *p = NULL;
+
+ if (!fs)
+ return -EINVAL;
+ if (optstr) {
+ p = strdup(optstr);
+ if (!p)
+ return -ENOMEM;
+ }
+ free(fs->vfs_optstr);
+ fs->vfs_optstr = p;
+
+ return 0;
+}
+/**
+ * mnt_fs_append_vfs_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Appends VFS mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_vfs_options(mnt_fs *fs, const char *optstr)
+{
if (!fs)
return -EINVAL;
if (!optstr)
return 0;
+ return mnt_optstr_append_option(&fs->vfs_optstr, optstr, NULL);
+}
- rc = mnt_split_optstr((char *) optstr, NULL, &v, &f, 0, 0);
- if (!rc)
- rc = mnt_optstr_append_option(&fs->optstr, optstr, NULL);
- if (!rc && v)
- rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL);
- if (!rc && f)
- rc = mnt_optstr_append_option(&fs->fs_optstr, f, NULL);
+/**
+ * mnt_fs_prepend_vfs_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Prepends VFS mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_vfs_options(mnt_fs *fs, const char *optstr)
+{
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
+ return mnt_optstr_prepend_option(&fs->vfs_optstr, optstr, NULL);
+}
- return rc;
+/**
+ * mnt_fs_get_userspace_options:
+ * @fs: fstab/mtab entry pointer
+ *
+ * Returns: pointer to userspace mount option string or NULL.
+ */
+const char *mnt_fs_get_userspace_options(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->user_optstr : NULL;
}
/**
- * mnt_fs_prepend_optstr:
+ * mnt_fs_set_userspace_options:
* @fs: fstab/mtab/mountinfo entry
- * @optstr: mount options
+ * @optstr: options string
+ *
+ * Sets userspace mount options.
*
* Returns: 0 on success or negative number in case of error.
*/
-int mnt_fs_prepend_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_set_userspace_options(mnt_fs *fs, const char *optstr)
{
- char *v = NULL, *f = NULL;
- int rc;
+ char *p = NULL;
- assert(fs);
+ if (!fs)
+ return -EINVAL;
+ if (optstr) {
+ p = strdup(optstr);
+ if (!p)
+ return -ENOMEM;
+ }
+ free(fs->user_optstr);
+ fs->user_optstr = p;
+
+ return 0;
+}
+/**
+ * mnt_fs_append_userspace_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Appends userspace mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_userspace_options(mnt_fs *fs, const char *optstr)
+{
if (!fs)
return -EINVAL;
if (!optstr)
return 0;
+ return mnt_optstr_append_option(&fs->user_optstr, optstr, NULL);
+}
- rc = mnt_split_optstr((char *) optstr, NULL, &v, &f, 0, 0);
- if (!rc)
- rc = mnt_optstr_prepend_option(&fs->optstr, optstr, NULL);
- if (!rc && v)
- rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL);
- if (!rc && f)
- rc = mnt_optstr_prepend_option(&fs->fs_optstr, f, NULL);
+/**
+ * mnt_fs_prepend_userspace_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Prepends userspace mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_userspace_options(mnt_fs *fs, const char *optstr)
+{
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
- return rc;
+ return mnt_optstr_prepend_option(&fs->user_optstr, optstr, NULL);
}
/**
- * mnt_fs_get_fs_optstr:
- * @fs: fstab/mtab/mountinfo entry pointer
+ * mnt_fs_get_attributes:
+ * @fs: fstab/mtab entry pointer
*
- * Returns: pointer to superblock (fs-depend) mount option string or NULL.
+ * Returns: pointer to attributes string or NULL.
*/
-const char *mnt_fs_get_fs_optstr(mnt_fs *fs)
+const char *mnt_fs_get_attributes(mnt_fs *fs)
{
assert(fs);
- return fs ? fs->fs_optstr : NULL;
+ return fs ? fs->attrs : NULL;
}
/**
- * mnt_fs_get_vfs_optstr:
- * @fs: fstab/mtab entry pointer
+ * mnt_fs_set_attributes:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
*
- * Returns: pointer to fs-independent (VFS) mount option string or NULL.
+ * Sets mount attributes. The attributes are mount(2) and mount(8) independent
+ * options, these options are not send to kernel and are not interpreted by
+ * libmount. The attributes are stored in /dev/.mount/utab only.
+ *
+ * The atrtributes are managed by libmount in userspace only. It's possible
+ * that information stored in userspace will not be available for libmount
+ * after CLONE_FS unshare. Be carefull, and don't use attributes if possible.
+ *
+ * Returns: 0 on success or negative number in case of error.
*/
-const char *mnt_fs_get_vfs_optstr(mnt_fs *fs)
+int mnt_fs_set_attributes(mnt_fs *fs, const char *optstr)
{
- assert(fs);
- return fs ? fs->vfs_optstr : NULL;
+ char *p = NULL;
+
+ if (!fs)
+ return -EINVAL;
+ if (optstr) {
+ p = strdup(optstr);
+ if (!p)
+ return -ENOMEM;
+ }
+ free(fs->attrs);
+ fs->attrs = p;
+
+ return 0;
+}
+
+/**
+ * mnt_fs_append_attributes
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Appends mount attributes. (See mnt_fs_set_attributes()).
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_attributes(mnt_fs *fs, const char *optstr)
+{
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
+ return mnt_optstr_append_option(&fs->attrs, optstr, NULL);
+}
+
+/**
+ * mnt_fs_prepend_attributes
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Prepends mount attributes. (See mnt_fs_set_attributes()).
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_attributes(mnt_fs *fs, const char *optstr)
+{
+ if (!fs)
+ return -EINVAL;
+ if (!optstr)
+ return 0;
+ return mnt_optstr_prepend_option(&fs->attrs, optstr, NULL);
}
@@ -754,8 +1079,34 @@ dev_t mnt_fs_get_devno(mnt_fs *fs)
int mnt_fs_get_option(mnt_fs *fs, const char *name,
char **value, size_t *valsz)
{
- char *optstr = (char *) mnt_fs_get_optstr(fs);
- return optstr ? mnt_optstr_get_option(optstr, name, value, valsz) : 1;
+ char rc = 1;
+
+ if (fs->fs_optstr)
+ rc = mnt_optstr_get_option(fs->fs_optstr, name, value, valsz);
+ if (rc == 1 && fs->vfs_optstr)
+ rc = mnt_optstr_get_option(fs->vfs_optstr, name, value, valsz);
+ if (rc == 1 && fs->user_optstr)
+ rc = mnt_optstr_get_option(fs->user_optstr, name, value, valsz);
+ return rc;
+}
+
+/**
+ * mnt_fs_get_attribute:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @name: option name
+ * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
+ * @valsz: returns size of options value or 0
+ *
+ * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
+ */
+int mnt_fs_get_attribute(mnt_fs *fs, const char *name,
+ char **value, size_t *valsz)
+{
+ char rc = 1;
+
+ if (fs->attrs)
+ rc = mnt_optstr_get_option(fs->attrs, name, value, valsz);
+ return rc;
}
/**
@@ -901,7 +1252,13 @@ int mnt_fs_match_fstype(mnt_fs *fs, const char *types)
*/
int mnt_fs_match_options(mnt_fs *fs, const char *options)
{
- return mnt_match_options(fs->optstr, options);
+ char *o = mnt_fs_strdup_options(fs);
+ int rc = 0;
+
+ if (o)
+ rc = mnt_match_options(o, options);
+ free(o);
+ return rc;
}
/**
@@ -919,7 +1276,15 @@ int mnt_fs_print_debug(mnt_fs *fs, FILE *file)
fprintf(file, "source: %s\n", mnt_fs_get_source(fs));
fprintf(file, "target: %s\n", mnt_fs_get_target(fs));
fprintf(file, "fstype: %s\n", mnt_fs_get_fstype(fs));
- fprintf(file, "optstr: %s\n", mnt_fs_get_optstr(fs));
+
+ if (mnt_fs_get_vfs_options(fs))
+ fprintf(file, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs));
+ if (mnt_fs_get_fs_options(fs))
+ fprintf(file, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs));
+ if (mnt_fs_get_userspace_options(fs))
+ fprintf(file, "user-optstr: %s\n", mnt_fs_get_userspace_options(fs));
+ if (mnt_fs_get_attributes(fs))
+ fprintf(file, "attributes: %s\n", mnt_fs_get_attributes(fs));
if (mnt_fs_get_root(fs))
fprintf(file, "root: %s\n", mnt_fs_get_root(fs));
@@ -988,8 +1353,14 @@ int mnt_fs_to_mntent(mnt_fs *fs, struct mntent **mnt)
goto err;
if ((rc = cpy_str(&m->mnt_type, mnt_fs_get_fstype(fs))))
goto err;
- if ((rc = cpy_str(&m->mnt_opts, mnt_fs_get_optstr(fs))))
+
+ errno = 0;
+ m->mnt_opts = mnt_fs_strdup_options(fs);
+ if (!m->mnt_opts && errno) {
+ rc = -errno;
goto err;
+ }
+
m->mnt_freq = mnt_fs_get_freq(fs);
m->mnt_passno = mnt_fs_get_passno(fs);
diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in
index 081cfe59e..02acddd12 100644
--- a/shlibs/mount/src/mount.h.in
+++ b/shlibs/mount/src/mount.h.in
@@ -168,16 +168,9 @@ extern int mnt_split_optstr(const char *optstr,
extern int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
const struct mnt_optmap *map);
-extern int mnt_optstr_get_mountflags(const char *optstr, unsigned long *flags);
-extern int mnt_optstr_get_userspace_mountflags(const char *optstr, unsigned long *flags);
extern int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
const struct mnt_optmap *map);
-extern int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next);
-extern int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next);
-extern int mnt_optstr_fix_secontext(char **optstr, char *value, size_t valsz, char **next);
-extern int mnt_optstr_fix_user(char **optstr, char *value, size_t valsz, char **next);
-
/* iter.c */
enum {
@@ -220,13 +213,38 @@ extern const char *mnt_fs_get_target(mnt_fs *ent);
extern int mnt_fs_set_target(mnt_fs *ent, const char *target);
extern const char *mnt_fs_get_fstype(mnt_fs *ent);
extern int mnt_fs_set_fstype(mnt_fs *ent, const char *fstype);
-extern const char *mnt_fs_get_optstr(mnt_fs *ent);
-extern int mnt_fs_set_optstr(mnt_fs *ent, const char *optstr);
-extern int mnt_fs_append_optstr(mnt_fs *fs, const char *optstr);
-extern int mnt_fs_prepend_optstr(mnt_fs *fs, const char *optstr);
-extern int mnt_fs_append_userspace_optstr(mnt_fs *fs, const char *optstr);
-extern const char *mnt_fs_get_vfs_optstr(mnt_fs *ent);
-extern const char *mnt_fs_get_fs_optstr(mnt_fs *ent);
+
+extern char *mnt_fs_strdup_options(mnt_fs *fs);
+extern int mnt_fs_set_options(mnt_fs *fs, const char *optstr);
+
+extern int mnt_fs_get_option(mnt_fs *ent, const char *name,
+ char **value, size_t *valsz);
+
+extern int mnt_fs_append_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_fs_options(mnt_fs *fs);
+extern int mnt_fs_set_fs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_append_fs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_fs_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_vfs_options(mnt_fs *fs);
+extern int mnt_fs_set_vfs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_append_vfs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_vfs_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_userspace_options(mnt_fs *fs);
+extern int mnt_fs_set_userspace_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_append_userspace_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_userspace_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_attributes(mnt_fs *fs);
+extern int mnt_fs_set_attributes(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_get_attribute(mnt_fs *fs, const char *name,
+ char **value, size_t *valsz);
+extern int mnt_fs_append_attributes(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_attributes(mnt_fs *fs, const char *optstr);
+
extern int mnt_fs_get_freq(mnt_fs *ent);
extern int mnt_fs_set_freq(mnt_fs *ent, int freq);
extern int mnt_fs_get_passno(mnt_fs *ent);
@@ -238,8 +256,6 @@ extern int mnt_fs_set_bindsrc(mnt_fs *fs, const char *src);
extern int mnt_fs_get_id(mnt_fs *fs);
extern int mnt_fs_get_parent_id(mnt_fs *fs);
extern dev_t mnt_fs_get_devno(mnt_fs *fs);
-extern int mnt_fs_get_option(mnt_fs *ent, const char *name,
- char **value, size_t *valsz);
extern int mnt_fs_match_target(mnt_fs *fs, const char *target, mnt_cache *cache);
extern int mnt_fs_match_source(mnt_fs *fs, const char *source, mnt_cache *cache);
@@ -326,10 +342,10 @@ extern int mnt_context_set_fs(mnt_context *cxt, mnt_fs *fs);
extern int mnt_context_set_source(mnt_context *cxt, const char *source);
extern int mnt_context_set_target(mnt_context *cxt, const char *target);
extern int mnt_context_set_fstype(mnt_context *cxt, const char *fstype);
-extern int mnt_context_set_optstr(mnt_context *cxt, const char *optstr);
-extern int mnt_context_append_optstr(mnt_context *cxt, const char *optstr);
+extern int mnt_context_set_options(mnt_context *cxt, const char *optstr);
+extern int mnt_context_append_options(mnt_context *cxt, const char *optstr);
extern int mnt_context_set_fstype_pattern(mnt_context *cxt, const char *pattern);
-extern int mnt_context_set_optstr_pattern(mnt_context *cxt, const char *pattern);
+extern int mnt_context_set_options_pattern(mnt_context *cxt, const char *pattern);
extern int mnt_context_set_fstab(mnt_context *cxt, mnt_tab *tb);
extern int mnt_context_get_fstab(mnt_context *cxt, mnt_tab **tb);
extern int mnt_context_get_mtab(mnt_context *cxt, mnt_tab **tb);
@@ -350,7 +366,6 @@ extern int mnt_context_do_umount(mnt_context *cxt);
/*
* mount(8) userspace options masks (MNT_MAP_USERSPACE map)
*/
-#define MNT_MS_DFLTS (1 << 1)
#define MNT_MS_NOAUTO (1 << 2)
#define MNT_MS_USER (1 << 3)
#define MNT_MS_USERS (1 << 4)
diff --git a/shlibs/mount/src/mount.sym b/shlibs/mount/src/mount.sym
index 07259d27b..5d51cded1 100644
--- a/shlibs/mount/src/mount.sym
+++ b/shlibs/mount/src/mount.sym
@@ -15,18 +15,23 @@ global:
mnt_free_fs;
mnt_free_iter;
mnt_free_lock;
- mnt_free_update;
+ mnt_free_mntent;
mnt_free_optls;
mnt_free_tab;
- mnt_fs_append_optstr;
- mnt_fs_append_userspace_optstr;
+ mnt_free_update;
+ mnt_fs_append_attributes;
+ mnt_fs_append_fs_options;
+ mnt_fs_append_options;
+ mnt_fs_append_userspace_options;
+ mnt_fs_append_vfs_options;
+ mnt_fs_get_attributes;
+ mnt_fs_get_attribute;
mnt_fs_get_devno;
mnt_fs_get_freq;
- mnt_fs_get_fs_optstr;
+ mnt_fs_get_fs_options;
mnt_fs_get_fstype;
mnt_fs_get_id;
mnt_fs_get_option;
- mnt_fs_get_optstr;
mnt_fs_get_parent_id;
mnt_fs_get_passno;
mnt_fs_get_root;
@@ -35,28 +40,40 @@ global:
mnt_fs_get_tag;
mnt_fs_get_target;
mnt_fs_get_userdata;
- mnt_fs_get_vfs_optstr;
+ mnt_fs_get_userspace_options;
+ mnt_fs_get_vfs_options;
+ mnt_fs_set_vfs_options;
mnt_fs_match_fstype;
mnt_fs_match_options;
mnt_fs_match_source;
mnt_fs_match_target;
- mnt_fs_prepend_optstr;
+ mnt_fs_prepend_attributes;
+ mnt_fs_prepend_fs_options;
+ mnt_fs_prepend_options;
+ mnt_fs_prepend_userspace_options;
+ mnt_fs_prepend_vfs_options;
mnt_fs_print_debug;
+ mnt_fs_set_attributes;
mnt_fs_set_freq;
+ mnt_fs_set_fs_options;
mnt_fs_set_fstype;
- mnt_fs_set_optstr;
+ mnt_fs_set_options;
mnt_fs_set_passno;
mnt_fs_set_root;
mnt_fs_set_source;
mnt_fs_set_target;
mnt_fs_set_userdata;
+ mnt_fs_set_userspace_options;
+ mnt_fs_strdup_options;
+ mnt_fs_to_mntent;
mnt_fstype_is_netfs;
mnt_fstype_is_pseudofs;
mnt_get_builtin_optmap;
- mnt_get_library_version;
- mnt_get_writable_mtab_path;
mnt_get_fstab_path;
+ mnt_get_fstype;
+ mnt_get_library_version;
mnt_get_mtab_path;
+ mnt_get_writable_mtab_path;
mnt_init_debug;
mnt_iter_get_direction;
mnt_lock_file;
@@ -69,30 +86,23 @@ global:
mnt_new_fs;
mnt_new_iter;
mnt_new_lock;
- mnt_new_update;
mnt_new_optls;
mnt_new_tab;
mnt_new_tab_from_file;
+ mnt_new_update;
mnt_optstr_append_option;
- mnt_optstr_get_mountflags;
+ mnt_optstr_apply_flags;
+ mnt_optstr_get_flags;
mnt_optstr_get_option;
- mnt_optstr_get_userspace_mountflags;
mnt_optstr_next_option;
mnt_optstr_prepend_option;
mnt_optstr_remove_option;
mnt_optstr_set_option;
- mnt_optstr_fix_gid;
- mnt_optstr_fix_selinux;
- mnt_optstr_fix_uid;
- mnt_optstr_fix_user;
- mnt_optstr_apply_flags;
- mnt_optstr_get_flags;
mnt_parse_version_string;
mnt_reset_iter;
mnt_resolve_path;
mnt_resolve_spec;
mnt_resolve_tag;
- mnt_get_fstype;
mnt_split_optstr;
mnt_tab_add_fs;
mnt_tab_find_next_fs;
@@ -119,8 +129,10 @@ global:
mnt_unlock_file;
mnt_unmangle;
mnt_update_disable_lock;
- mnt_update_get_lock;
mnt_update_file;
+ mnt_update_get_filename;
+ mnt_update_get_format;
+ mnt_update_get_lock;
mnt_update_prepare_update;
mnt_update_set_action;
mnt_update_set_filename;
@@ -128,10 +140,6 @@ global:
mnt_update_set_fs;
mnt_update_set_mountflags;
mnt_update_set_old_target;
- mnt_update_get_format;
- mnt_update_get_filename;
- mnt_fs_to_mntent;
- mnt_free_mntent;
local:
*;
};
diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h
index 7eebb2094..3403ab705 100644
--- a/shlibs/mount/src/mountP.h
+++ b/shlibs/mount/src/mountP.h
@@ -172,9 +172,10 @@ struct _mnt_fs {
char *target; /* mountinfo[5], fstab[2]: mountpoint */
char *fstype; /* mountinfo[9], fstab[3]: filesystem type */
- char *optstr; /* mountinfo[6,11], fstab[4]: option string */
char *vfs_optstr; /* mountinfo[6]: fs-independent (VFS) options */
char *fs_optstr; /* mountinfo[11]: fs-depend options */
+ char *user_optstr; /* userspace mount options */
+ char *attrs; /* mount attributes */
int freq; /* fstab[5]: dump frequency in days */
int passno; /* fstab[6]: pass number on parallel fsck */
@@ -299,6 +300,10 @@ extern int mnt_optmap_require_value(const struct mnt_optmap *mapent);
/* optstr.c */
extern int mnt_optstr_remove_option_at(char **optstr, char *begin, char *end);
+extern int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next);
+extern int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next);
+extern int mnt_optstr_fix_secontext(char **optstr, char *value, size_t valsz, char **next);
+extern int mnt_optstr_fix_user(char **optstr);
/* fs.c */
extern int __mnt_fs_set_source_ptr(mnt_fs *fs, char *source);
diff --git a/shlibs/mount/src/optmap.c b/shlibs/mount/src/optmap.c
index d96da986c..d5f641096 100644
--- a/shlibs/mount/src/optmap.c
+++ b/shlibs/mount/src/optmap.c
@@ -144,7 +144,7 @@ static const struct mnt_optmap linux_flags_map[] =
*/
static const struct mnt_optmap userspace_opts_map[] =
{
- { "defaults", MNT_MS_DFLTS, MNT_NOMTAB }, /* default options */
+ { "defaults", 0, 0 }, /* default options */
{ "auto", MNT_MS_NOAUTO, MNT_INVERT | MNT_NOMTAB }, /* Can be mounted using -a */
{ "noauto", MNT_MS_NOAUTO, MNT_NOMTAB }, /* Can only be mounted explicitly */
diff --git a/shlibs/mount/src/optstr.c b/shlibs/mount/src/optstr.c
index 475c4cf1f..62c5701dd 100644
--- a/shlibs/mount/src/optstr.c
+++ b/shlibs/mount/src/optstr.c
@@ -125,6 +125,9 @@ static int mnt_optstr_locate_option(char *optstr, const char *name,
size_t namesz, nsz;
int rc;
+ if (!optstr)
+ return 1;
+
assert(name);
assert(optstr);
@@ -223,7 +226,7 @@ int mnt_optstr_append_option(char **optstr, const char *name, const char *value)
size_t vsz, nsz;
if (!name)
- return -EINVAL;
+ return 0;
nsz = strlen(name);
vsz = value ? strlen(value) : 0;
@@ -480,6 +483,9 @@ int mnt_split_optstr(const char *optstr, char **user, char **vfs, char **fs,
const struct mnt_optmap *m =
mnt_optmap_get_entry(maps, 2, name, namesz, &ent);
+ if (ent && !ent->id)
+ continue; /* ignore undefined options (comments) */
+
if (m && m == maps[0] && vfs) {
if (ignore_vfs && (ent->mask & ignore_vfs))
continue;
@@ -544,6 +550,8 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
const struct mnt_optmap *ent;
if (mnt_optmap_get_entry(maps, 1, name, namesz, &ent)) {
+ if (!ent->id)
+ continue;
if (ent->mask & MNT_INVERT)
*flags &= ~ent->id;
else
@@ -555,54 +563,6 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
}
/**
- * mnt_optstr_get_mountflags:
- * @optstr: string with comma separated list of options
- * @flags: returns mount flags
- *
- * For more details about mountflags see mount(2) syscall. The flags are
- * generated according to MNT_LINUX_MAP.
- *
- * For example:
- *
- * "bind,exec,foo,bar" --returns-> MS_BIND
- *
- * "bind,noexec,foo,bar" --returns-> MS_BIND|MS_NOEXEC
- *
- * Note that @flags are not zeroized by this function! This function set/unset
- * bites in the @flags only.
- *
- * Returns: 0 on success or negative number in case of error
- */
-int mnt_optstr_get_mountflags(const char *optstr, unsigned long *flags)
-{
- return mnt_optstr_get_flags(optstr, flags,
- mnt_get_builtin_optmap(MNT_LINUX_MAP));
-}
-
-/**
- * mnt_optstr_get_userspace_mountflags:
- * @optstr: string with comma separated list of options
- * @flags: returns mount flags
- *
- * The mountflags are IDs from all MNT_USERSPACE_MAP options
- * map. See "struct mnt_optmap". These flags are not used for mount(2) syscall.
- *
- * For example:
- *
- * "bind,exec,loop" --returns-> MNT_MS_LOOP
- *
- * Note that @flags are not zeroized by this function! This function set/unset
- * bites in the @flags only.
- *
- * Returns: 0 on success or negative number in case of error
- */
-int mnt_optstr_get_userspace_mountflags(const char *optstr, unsigned long *flags)
-{
- return mnt_optstr_get_flags(optstr, flags,
- mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
-}
-
-/**
* mnt_optstr_apply_mountflags:
* @optstr: string with comma separated list of options
* @flags: returns mount flags
@@ -672,6 +632,8 @@ int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
/*
* remove unwanted option (rw/ro is already set)
*/
+ if (!ent->id)
+ continue;
if (ent->id == MS_RDONLY ||
(ent->mask & MNT_INVERT) ||
!(fl & ent->id)) {
@@ -725,8 +687,7 @@ err:
return rc;
}
-/**
- * mnt_optstr_fix_selinux:
+/*
* @optstr: string with comma separated list of options
* @value: pointer to the begin of the context value
* @valsz: size of the value
@@ -814,8 +775,7 @@ static int set_uint_value(char **optstr, unsigned int num,
return insert_value(optstr, begin, buf, next);
}
-/**
- * mnt_optstr_fix_uid:
+/*
* @optstr: string with comma separated list of options
* @value: pointer to the begin of the uid value
* @valsz: size of the value
@@ -866,8 +826,7 @@ int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next)
return rc;
}
-/**
- * mnt_optstr_fix_gid:
+/*
* @optstr: string with comma separated list of options
* @value: pointer to the begin of the uid value
* @valsz: size of the value
@@ -913,40 +872,35 @@ int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next)
return rc;
}
-/**
- * mnt_optstr_fix_user:
- * @optstr: string with comma separated list of options
- * @value: pointer to place where has to start the value
- * @valsz: size of the value or zero if value not define
- * @next: returns pointer to the next option (optional argument)
-
- * Add/replace username. This is usually used to convert "user" (without value)
- * to to "user=<username>" -- in this case the @value has to pointer behind the
- * "user" option name; in case you want to replace already defined <username>
- * then the @valsz must be greater than zero.
+/*
+ * Converts "user" to "user=<username>".
*
* Returns: 0 on success, negative number in case of error.
*/
-int mnt_optstr_fix_user(char **optstr, char *value, size_t valsz, char **next)
+int mnt_optstr_fix_user(char **optstr)
{
char *username;
+ struct mnt_optloc ol;
int rc = 0;
- if (!optstr || !value)
- return -EINVAL;
-
DBG(CXT, mnt_debug("fixing user"));
+ mnt_init_optloc(&ol);
+
+ rc = mnt_optstr_locate_option(*optstr, "user", &ol);
+ if (rc)
+ return rc == 1 ? 0 : rc; /* 1: user= not found */
+
username = mnt_get_username(getuid());
if (!username)
return -ENOMEM;
- if (!valsz || strncmp(value, username, valsz)) {
- if (valsz)
+ if (!ol.valsz || strncmp(ol.value, username, ol.valsz)) {
+ if (ol.valsz)
/* remove old value */
- mnt_optstr_remove_option_at(optstr, value, value + valsz);
+ mnt_optstr_remove_option_at(optstr, ol.value, ol.end);
- rc = insert_value(optstr, value, username, next);
+ rc = insert_value(optstr, ol.value, username, NULL);
}
free(username);
@@ -1030,13 +984,13 @@ int test_flags(struct mtest *ts, int argc, char *argv[])
optstr = strdup(argv[1]);
- rc = mnt_optstr_get_mountflags(optstr, &fl);
+ rc = mnt_optstr_get_flags(optstr, &fl, mnt_get_builtin_optmap(MNT_LINUX_MAP));
if (rc)
return rc;
printf("mountflags: 0x%08lx\n", fl);
fl = 0;
- rc = mnt_optstr_get_userspace_mountflags(optstr, &fl);
+ rc = mnt_optstr_get_flags(optstr, &fl, mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
if (rc)
return rc;
printf("userspace-mountflags: 0x%08lx\n", fl);
@@ -1164,12 +1118,11 @@ int test_fix(struct mtest *ts, int argc, char *argv[])
rc = mnt_optstr_fix_gid(&optstr, val, valsz, &next);
else if (!strncmp(name, "context", 7))
rc = mnt_optstr_fix_secontext(&optstr, val, valsz, &next);
- else if (!strncmp(name, "user", 4))
- rc = mnt_optstr_fix_user(&optstr,
- val ? val : name + namesz, valsz, &next);
if (rc)
break;
}
+ if (rc)
+ rc = mnt_optstr_fix_user(&optstr);
printf("fixed: %s\n", optstr);
diff --git a/shlibs/mount/src/tab_parse.c b/shlibs/mount/src/tab_parse.c
index d7c27e65f..a6c14ffff 100644
--- a/shlibs/mount/src/tab_parse.c
+++ b/shlibs/mount/src/tab_parse.c
@@ -81,7 +81,8 @@ static int mnt_parse_tab_line(mnt_fs *fs, char *s)
if (!rc)
rc = __mnt_fs_set_fstype_ptr(fs, fstype);
if (!rc)
- rc = __mnt_fs_set_optstr_ptr(fs, optstr, TRUE);
+ rc = mnt_fs_set_options(fs, optstr);
+ free(optstr);
} else {
DBG(TAB, mnt_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
rc = -EINVAL;
@@ -210,10 +211,16 @@ static int mnt_parse_utab_line(mnt_fs *fs, const char *s)
if (!fs->bindsrc)
goto enomem;
- } else if (!fs->optstr && !strncmp(p, "OPTS=", 5)) {
- fs->optstr = unmangle(p + 5, &end);
- if (!fs->optstr)
+ } else if (!fs->user_optstr && !strncmp(p, "OPTS=", 5)) {
+ fs->user_optstr = unmangle(p + 5, &end);
+ if (!fs->user_optstr)
goto enomem;
+
+ } else if (!fs->attrs && !strncmp(p, "ATTRS=", 6)) {
+ fs->attrs = unmangle(p + 6, &end);
+ if (!fs->attrs)
+ goto enomem;
+
} else {
/* unknown variable */
while (*p && *p != ' ') p++;
@@ -246,63 +253,6 @@ static int guess_tab_format(char *line)
return MNT_FMT_FSTAB;
}
-
-/*
- * Merges @vfs and @fs options strings into a new string.
- * This function cares about 'ro/rw' options. The 'ro' is
- * always used if @vfs or @fs is read-only.
- * For example:
- *
- * mnt_merge_optstr("rw,noexec", "ro,journal=update")
- *
- * returns: "ro,noexec,journal=update"
- *
- * mnt_merge_optstr("rw,noexec", "rw,journal=update")
- *
- * returns: "rw,noexec,journal=update"
-
- * We need this function for /proc/self/mountinfo parsing.
- */
-static char *merge_optstr(const char *vfs, const char *fs)
-{
- char *res, *p;
- size_t sz;
- int ro = 0, rw = 0;
-
- if (!vfs && !fs)
- return NULL;
- if (!vfs || !fs)
- return strdup(fs ? fs : vfs);
- if (!strcmp(vfs, fs))
- return strdup(vfs); /* e.g. "aaa" and "aaa" */
-
- /* leave space for leading "r[ow],", "," and trailing zero */
- sz = strlen(vfs) + strlen(fs) + 5;
- res = malloc(sz);
- if (!res)
- return NULL;
- p = res + 3; /* make a room for rw/ro flag */
-
- snprintf(p, sz - 3, "%s,%s", vfs, fs);
-
- /* remove 'rw' flags */
- rw += !mnt_optstr_remove_option(&p, "rw"); /* from vfs */
- rw += !mnt_optstr_remove_option(&p, "rw"); /* from fs */
-
- /* remove 'ro' flags if necessary */
- if (rw != 2) {
- ro += !mnt_optstr_remove_option(&p, "ro");
- if (ro + rw < 2)
- ro += !mnt_optstr_remove_option(&p, "ro");
- }
-
- if (!strlen(p))
- memcpy(res, ro ? "ro" : "rw", 3);
- else
- memcpy(res, ro ? "ro," : "rw,", 3);
- return res;
-}
-
/*
* Read and parse the next line from {fs,m}tab or mountinfo
*/
@@ -359,15 +309,6 @@ static int mnt_tab_parse_next(mnt_tab *tb, FILE *f, mnt_fs *fs,
}
- /* merge fs_optstr and vfs_optstr into optstr (necessary for "mountinfo") */
- if (!fs->optstr && (fs->vfs_optstr || fs->fs_optstr)) {
- fs->optstr = merge_optstr(fs->vfs_optstr, fs->fs_optstr);
- if (!fs->optstr) {
- DBG(TAB, mnt_debug_h(tb, "failed to merge optstr"));
- return -ENOMEM;
- }
- }
-
/*DBG(TAB, mnt_fs_print_debug(fs, stderr));*/
return 0;
@@ -665,7 +606,7 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
{
mnt_fs *fs;
mnt_iter itr;
- const char *optstr, *src, *target, *root;
+ const char *optstr, *src, *target, *root, *attrs;
assert(tb);
assert(uf);
@@ -676,10 +617,11 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
src = mnt_fs_get_srcpath(uf);
target = mnt_fs_get_target(uf);
- optstr = mnt_fs_get_optstr(uf);
+ optstr = mnt_fs_get_userspace_options(uf);
+ attrs = mnt_fs_get_attributes(uf);
root = mnt_fs_get_root(uf);
- if (!src || !target || !optstr || !root)
+ if (!src || !target || !root || (!attrs && !optstr))
return NULL;
mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
@@ -696,7 +638,8 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
if (fs) {
DBG(TAB, mnt_debug_h(tb, "found fs -- appending userspace optstr"));
- mnt_fs_append_userspace_optstr(fs, optstr);
+ mnt_fs_append_userspace_options(fs, optstr);
+ mnt_fs_append_attributes(fs, attrs);
mnt_fs_set_bindsrc(fs, mnt_fs_get_bindsrc(uf));
DBG(TAB, mnt_debug_h(tb, "found fs:"));
diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c
index e9f6609ea..ad7c19d74 100644
--- a/shlibs/mount/src/tab_update.c
+++ b/shlibs/mount/src/tab_update.c
@@ -204,8 +204,7 @@ mnt_fs *mnt_update_get_fs(mnt_update *upd)
static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
{
int rc = 0;
- const char *o = NULL;
- char *u = NULL;
+ const char *o = NULL, *a = NULL;
assert(fs);
assert(ent);
@@ -217,20 +216,10 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
DBG(UPDATE, mnt_debug("prepare utab entry"));
- o = mnt_fs_get_optstr(fs);
- if (o) {
- rc = mnt_split_optstr(o, &u, NULL, NULL, MNT_NOMTAB, 0);
- if (rc)
- return rc; /* parse error or so... */
- }
- /* TODO
- if (extra_opts) {
- rc = mnt_optstr_append_option(&u, extra_opts, NULL);
- if (rc)
- goto err;
- }
- */
- if (!u)
+ o = mnt_fs_get_userspace_options(fs);
+ a = mnt_fs_get_attributes(fs);
+
+ if (!o && !a)
return 1; /* don't have mount options */
/* allocate the entry */
@@ -240,10 +229,12 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
goto err;
}
- rc = __mnt_fs_set_optstr_ptr(*ent, u, FALSE);
+ rc = mnt_fs_set_userspace_options(*ent, o);
+ if (rc)
+ goto err;
+ rc = mnt_fs_set_attributes(*ent, a);
if (rc)
goto err;
- u = NULL;
if (!(mountflags & MS_REMOUNT)) {
rc = set_fs_root(*ent, fs, mountflags);
@@ -254,15 +245,15 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
DBG(UPDATE, mnt_debug("utab entry OK"));
return 0;
err:
- free(u);
mnt_free_fs(*ent);
+ *ent = NULL;
return rc;
}
static int set_fs_root(mnt_fs *result, mnt_fs *fs, unsigned long mountflags)
{
char *root = NULL, *mnt = NULL;
- const char *fstype, *optstr;
+ const char *fstype;
mnt_tab *tb = NULL;
int rc = -ENOMEM;
@@ -271,7 +262,6 @@ static int set_fs_root(mnt_fs *result, mnt_fs *fs, unsigned long mountflags)
DBG(UPDATE, mnt_debug("setting FS root"));
- optstr = mnt_fs_get_optstr(fs);
fstype = mnt_fs_get_fstype(fs);
/*
@@ -334,7 +324,7 @@ static int set_fs_root(mnt_fs *result, mnt_fs *fs, unsigned long mountflags)
char *vol = NULL, *p;
size_t sz, volsz = 0;
- if (mnt_optstr_get_option((char *) optstr, "subvol", &vol, &volsz))
+ if (mnt_fs_get_option(fs, "subvol", &vol, &volsz))
goto dflt;
sz = volsz;
@@ -371,16 +361,21 @@ err:
/* mtab and fstab update */
static int fprintf_mtab_fs(FILE *f, mnt_fs *fs)
{
+ char *o;
char *m1, *m2, *m3, *m4;
int rc;
assert(fs);
assert(f);
+ o = mnt_fs_strdup_options(fs);
+ if (!o)
+ return -ENOMEM;
+
m1 = mangle(mnt_fs_get_source(fs));
m2 = mangle(mnt_fs_get_target(fs));
m3 = mangle(mnt_fs_get_fstype(fs));
- m4 = mangle(mnt_fs_get_optstr(fs));
+ m4 = mangle(o);
if (m1 && m2 && m3 && m4)
rc = !fprintf(f, "%s %s %s %s %d %d\n",
@@ -390,6 +385,7 @@ static int fprintf_mtab_fs(FILE *f, mnt_fs *fs)
else
rc = -ENOMEM;
+ free(o);
free(m1);
free(m2);
free(m3);
@@ -428,12 +424,16 @@ static int fprintf_utab_fs(FILE *f, mnt_fs *fs)
fprintf(f, "BINDSRC=%s ", p);
free(p);
}
- p = mangle(mnt_fs_get_optstr(fs));
+ p = mangle(mnt_fs_get_attributes(fs));
+ if (p) {
+ fprintf(f, "ATTRS=%s ", p);
+ free(p);
+ }
+ p = mangle(mnt_fs_get_userspace_options(fs));
if (p) {
fprintf(f, "OPTS=%s", p);
free(p);
}
-
fputc('\n', f);
return 0;
@@ -620,12 +620,15 @@ static int update_modify_options(mnt_update *upd, mnt_lock *lc)
{
mnt_tab *tb = NULL;
int rc = 0, u_lc = -1;
+ mnt_fs *fs;
assert(upd);
assert(upd->fs);
DBG(UPDATE, mnt_debug_h(upd, "%s: modify options", upd->filename));
+ fs = upd->fs;
+
if (lc)
mnt_lock_file(lc);
else if (upd->userspace_only)
@@ -635,20 +638,28 @@ static int update_modify_options(mnt_update *upd, mnt_lock *lc)
upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
if (tb) {
mnt_fs *cur = mnt_tab_find_target(tb,
- mnt_fs_get_target(upd->fs),
+ mnt_fs_get_target(fs),
MNT_ITER_BACKWARD);
if (cur) {
- rc = mnt_fs_set_optstr(cur, mnt_fs_get_optstr(upd->fs));
+ if (upd->userspace_only)
+ rc = mnt_fs_set_attributes(cur, mnt_fs_get_attributes(fs));
+ if (!rc && !upd->userspace_only)
+ rc = mnt_fs_set_vfs_options(cur, mnt_fs_get_vfs_options(fs));
+ if (!rc && !upd->userspace_only)
+ rc = mnt_fs_set_fs_options(cur, mnt_fs_get_fs_options(fs));
+ if (!rc)
+ rc = mnt_fs_set_userspace_options(cur,
+ mnt_fs_get_userspace_options(fs));
if (!rc)
rc = update_tab(upd, tb);
}
mnt_free_tab(tb);
}
+
if (lc)
mnt_unlock_file(lc);
else if (u_lc != -1)
utab_unlock(u_lc);
-
return rc;
}
@@ -747,7 +758,7 @@ static int test_add(struct mtest *ts, int argc, char *argv[])
mnt_fs_set_source(fs, argv[1]);
mnt_fs_set_target(fs, argv[2]);
mnt_fs_set_fstype(fs, argv[3]);
- mnt_fs_set_optstr(fs, argv[4]);
+ mnt_fs_set_options(fs, argv[4]);
rc = update(NULL, fs, 0);
mnt_free_fs(fs);
@@ -783,7 +794,7 @@ static int test_remount(struct mtest *ts, int argc, char *argv[])
if (argc < 3)
return -1;
mnt_fs_set_target(fs, argv[1]);
- mnt_fs_set_optstr(fs, argv[2]);
+ mnt_fs_set_options(fs, argv[2]);
rc = update(NULL, fs, MS_REMOUNT);
mnt_free_fs(fs);