From 76a06ca4cdba29ca54e418a61e8efc811ac608aa Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 14 Dec 2010 23:50:55 +0100 Subject: [PATCH] libmount: use separate buffer for userspace options, add mount attributes Signed-off-by: Karel Zak --- shlibs/mount/src/context.c | 67 ++- shlibs/mount/src/context_mount.c | 59 +- shlibs/mount/src/context_umount.c | 23 +- shlibs/mount/src/fs.c | 533 +++++++++++++++--- shlibs/mount/src/mount.h.in | 55 +- shlibs/mount/src/mount.sym | 58 +- shlibs/mount/src/mountP.h | 7 +- shlibs/mount/src/optmap.c | 2 +- shlibs/mount/src/optstr.c | 111 ++-- shlibs/mount/src/tab_parse.c | 91 +-- shlibs/mount/src/tab_update.c | 71 ++- tests/expected/libmount/tabfiles-copy | 4 +- tests/expected/libmount/tabfiles-find-pair | 2 +- tests/expected/libmount/tabfiles-find-source | 2 +- tests/expected/libmount/tabfiles-find-target | 2 +- tests/expected/libmount/tabfiles-parse-fstab | 16 +- .../libmount/tabfiles-parse-fstab-broken | 16 +- .../libmount/tabfiles-parse-mountinfo | 96 ++-- tests/expected/libmount/tabfiles-parse-mtab | 24 +- tests/expected/libmount/update-mtab-mount | 4 +- tests/expected/libmount/update-mtab-move | 4 +- 21 files changed, 800 insertions(+), 447 deletions(-) diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c index 4fe2eabf..59e8bd92 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 fb593c3f..b5a339f5 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. 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 ec571300..b4da7373 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 bcc53762..b8e9085d 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 081cfe59..02acddd1 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 07259d27..5d51cded 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 7eebb209..3403ab70 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 d96da986..d5f64109 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 475c4cf1..62c5701d 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 @@ -554,54 +562,6 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags, return 0; } -/** - * 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 @@ -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=" -- in this case the @value has to pointer behind the - * "user" option name; in case you want to replace already defined - * then the @valsz must be greater than zero. +/* + * Converts "user" to "user=". * * 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 d7c27e65..a6c14fff 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 e9f6609e..ad7c19d7 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); diff --git a/tests/expected/libmount/tabfiles-copy b/tests/expected/libmount/tabfiles-copy index ff962cc8..bc477826 100644 --- a/tests/expected/libmount/tabfiles-copy +++ b/tests/expected/libmount/tabfiles-copy @@ -3,7 +3,7 @@ ORIGINAL: source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0 target: / fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 1 COPY: @@ -11,6 +11,6 @@ COPY: source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0 target: / fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 1 diff --git a/tests/expected/libmount/tabfiles-find-pair b/tests/expected/libmount/tabfiles-find-pair index 4b1134cb..ce8f957d 100644 --- a/tests/expected/libmount/tabfiles-find-pair +++ b/tests/expected/libmount/tabfiles-find-pair @@ -2,4 +2,4 @@ source: /dev/mapper/kzak-home target: /home/kzak fstype: ext4 -optstr: rw,noatime +VFS-optstr: rw,noatime diff --git a/tests/expected/libmount/tabfiles-find-source b/tests/expected/libmount/tabfiles-find-source index deebbf4c..a49fdae2 100644 --- a/tests/expected/libmount/tabfiles-find-source +++ b/tests/expected/libmount/tabfiles-find-source @@ -2,6 +2,6 @@ source: UUID=fef7ccb3-821c-4de8-88dc-71472be5946f target: /boot fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 2 diff --git a/tests/expected/libmount/tabfiles-find-target b/tests/expected/libmount/tabfiles-find-target index 8be992bc..8d48723f 100644 --- a/tests/expected/libmount/tabfiles-find-target +++ b/tests/expected/libmount/tabfiles-find-target @@ -2,4 +2,4 @@ source: /dev/mapper/foo target: /home/foo fstype: ext4 -optstr: noatime,defaults +VFS-optstr: noatime diff --git a/tests/expected/libmount/tabfiles-parse-fstab b/tests/expected/libmount/tabfiles-parse-fstab index 8d358627..3cdcc5d4 100644 --- a/tests/expected/libmount/tabfiles-parse-fstab +++ b/tests/expected/libmount/tabfiles-parse-fstab @@ -2,53 +2,49 @@ source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0 target: / fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 1 ------ fs: source: UUID=fef7ccb3-821c-4de8-88dc-71472be5946f target: /boot fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 2 ------ fs: source: UUID=1f2aa318-9c34-462e-8d29-260819ffd657 target: swap fstype: swap -optstr: defaults ------ fs: source: tmpfs target: /dev/shm fstype: tmpfs -optstr: defaults ------ fs: source: devpts target: /dev/pts fstype: devpts -optstr: gid=5,mode=620 +FS-opstr: gid=5,mode=620 ------ fs: source: sysfs target: /sys fstype: sysfs -optstr: defaults ------ fs: source: proc target: /proc fstype: proc -optstr: defaults ------ fs: source: /dev/mapper/foo target: /home/foo fstype: ext4 -optstr: noatime,defaults +VFS-optstr: noatime ------ fs: source: foo.com:/mnt/share target: /mnt/remote fstype: nfs -optstr: noauto +user-optstr: noauto ------ fs: source: //bar.com/gogogo target: /mnt/gogogo fstype: cifs -optstr: user=SRGROUP/baby,noauto +user-optstr: user=SRGROUP/baby,noauto diff --git a/tests/expected/libmount/tabfiles-parse-fstab-broken b/tests/expected/libmount/tabfiles-parse-fstab-broken index f048e440..bf756616 100644 --- a/tests/expected/libmount/tabfiles-parse-fstab-broken +++ b/tests/expected/libmount/tabfiles-parse-fstab-broken @@ -4,54 +4,50 @@ source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0 target: / fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 1 ------ fs: source: UUID=fef7ccb3-821c-4de8-88dc-71472be5946f target: /boot fstype: ext3 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 pass: 2 ------ fs: source: UUID=1f2aa318-9c34-462e-8d29-260819ffd657 target: swap fstype: swap -optstr: defaults ------ fs: source: tmpfs target: /dev/shm fstype: tmpfs -optstr: defaults ------ fs: source: devpts target: /dev/pts fstype: devpts -optstr: gid=5,mode=620 +FS-opstr: gid=5,mode=620 ------ fs: source: sysfs target: /sys fstype: sysfs -optstr: defaults ------ fs: source: proc target: /proc fstype: proc -optstr: defaults ------ fs: source: /dev/mapper/foo target: /home/foo fstype: ext4 -optstr: noatime,defaults +VFS-optstr: noatime freq: 1 ------ fs: source: foo.com:/mnt/share target: /mnt/remote fstype: nfs -optstr: noauto +user-optstr: noauto ------ fs: source: //bar.com/gogogo target: /mnt/gogogo fstype: cifs -optstr: user=SRGROUP/baby,noauto +user-optstr: user=SRGROUP/baby,noauto diff --git a/tests/expected/libmount/tabfiles-parse-mountinfo b/tests/expected/libmount/tabfiles-parse-mountinfo index a2de2ae7..aac3591e 100644 --- a/tests/expected/libmount/tabfiles-parse-mountinfo +++ b/tests/expected/libmount/tabfiles-parse-mountinfo @@ -2,7 +2,8 @@ source: /proc target: /proc fstype: proc -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 15 parent: 20 @@ -11,7 +12,8 @@ devno: 0:3 source: /sys target: /sys fstype: sysfs -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 16 parent: 20 @@ -20,7 +22,8 @@ devno: 0:15 source: udev target: /dev fstype: devtmpfs -optstr: rw,relatime,size=1983516k,nr_inodes=495879,mode=755 +VFS-optstr: rw,relatime +FS-opstr: rw,size=1983516k,nr_inodes=495879,mode=755 root: / id: 17 parent: 20 @@ -29,7 +32,8 @@ devno: 0:5 source: devpts target: /dev/pts fstype: devpts -optstr: rw,relatime,gid=5,mode=620,ptmxmode=000 +VFS-optstr: rw,relatime +FS-opstr: rw,gid=5,mode=620,ptmxmode=000 root: / id: 18 parent: 17 @@ -38,7 +42,8 @@ devno: 0:10 source: tmpfs target: /dev/shm fstype: tmpfs -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 19 parent: 17 @@ -47,7 +52,8 @@ devno: 0:16 source: /dev/sda4 target: / fstype: ext3 -optstr: rw,noatime,errors=continue,user_xattr,acl,barrier=0,data=ordered +VFS-optstr: rw,noatime +FS-opstr: rw,errors=continue,user_xattr,acl,barrier=0,data=ordered root: / id: 20 parent: 1 @@ -56,7 +62,8 @@ devno: 8:4 source: tmpfs target: /sys/fs/cgroup fstype: tmpfs -optstr: rw,nosuid,nodev,noexec,relatime,mode=755 +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,mode=755 root: / id: 21 parent: 16 @@ -65,7 +72,8 @@ devno: 0:17 source: cgroup target: /sys/fs/cgroup/systemd fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd root: / id: 22 parent: 21 @@ -74,7 +82,8 @@ devno: 0:18 source: cgroup target: /sys/fs/cgroup/cpuset fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,cpuset +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,cpuset root: / id: 23 parent: 21 @@ -83,7 +92,8 @@ devno: 0:19 source: cgroup target: /sys/fs/cgroup/ns fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,ns +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,ns root: / id: 24 parent: 21 @@ -92,7 +102,8 @@ devno: 0:20 source: cgroup target: /sys/fs/cgroup/cpu fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,cpu +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,cpu root: / id: 25 parent: 21 @@ -101,7 +112,8 @@ devno: 0:21 source: cgroup target: /sys/fs/cgroup/cpuacct fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,cpuacct +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,cpuacct root: / id: 26 parent: 21 @@ -110,7 +122,8 @@ devno: 0:22 source: cgroup target: /sys/fs/cgroup/memory fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,memory +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,memory root: / id: 27 parent: 21 @@ -119,7 +132,8 @@ devno: 0:23 source: cgroup target: /sys/fs/cgroup/devices fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,devices +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,devices root: / id: 28 parent: 21 @@ -128,7 +142,8 @@ devno: 0:24 source: cgroup target: /sys/fs/cgroup/freezer fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,freezer +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,freezer root: / id: 29 parent: 21 @@ -137,7 +152,8 @@ devno: 0:25 source: cgroup target: /sys/fs/cgroup/net_cls fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,net_cls +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,net_cls root: / id: 30 parent: 21 @@ -146,7 +162,8 @@ devno: 0:26 source: cgroup target: /sys/fs/cgroup/blkio fstype: cgroup -optstr: rw,nosuid,nodev,noexec,relatime,blkio +VFS-optstr: rw,nosuid,nodev,noexec,relatime +FS-opstr: rw,blkio root: / id: 31 parent: 21 @@ -155,7 +172,8 @@ devno: 0:27 source: systemd-1 target: /sys/kernel/security fstype: autofs -optstr: rw,relatime,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct +VFS-optstr: rw,relatime +FS-opstr: rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct root: / id: 32 parent: 16 @@ -164,7 +182,8 @@ devno: 0:28 source: systemd-1 target: /dev/hugepages fstype: autofs -optstr: rw,relatime,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct +VFS-optstr: rw,relatime +FS-opstr: rw,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct root: / id: 33 parent: 17 @@ -173,7 +192,8 @@ devno: 0:29 source: systemd-1 target: /sys/kernel/debug fstype: autofs -optstr: rw,relatime,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct +VFS-optstr: rw,relatime +FS-opstr: rw,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct root: / id: 34 parent: 16 @@ -182,7 +202,8 @@ devno: 0:30 source: systemd-1 target: /proc/sys/fs/binfmt_misc fstype: autofs -optstr: rw,relatime,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct +VFS-optstr: rw,relatime +FS-opstr: rw,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct root: / id: 35 parent: 15 @@ -191,7 +212,8 @@ devno: 0:31 source: systemd-1 target: /dev/mqueue fstype: autofs -optstr: rw,relatime,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct +VFS-optstr: rw,relatime +FS-opstr: rw,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct root: / id: 36 parent: 17 @@ -200,7 +222,8 @@ devno: 0:32 source: /proc/bus/usb target: /proc/bus/usb fstype: usbfs -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 37 parent: 15 @@ -209,7 +232,8 @@ devno: 0:14 source: hugetlbfs target: /dev/hugepages fstype: hugetlbfs -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 38 parent: 33 @@ -218,7 +242,8 @@ devno: 0:33 source: mqueue target: /dev/mqueue fstype: mqueue -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 39 parent: 36 @@ -227,7 +252,8 @@ devno: 0:12 source: /dev/sda6 target: /boot fstype: ext3 -optstr: rw,noatime,errors=continue,barrier=0,data=ordered +VFS-optstr: rw,noatime +FS-opstr: rw,errors=continue,barrier=0,data=ordered root: / id: 40 parent: 20 @@ -236,7 +262,8 @@ devno: 8:6 source: /dev/mapper/kzak-home target: /home/kzak fstype: ext4 -optstr: rw,noatime,barrier=1,data=ordered +VFS-optstr: rw,noatime +FS-opstr: rw,barrier=1,data=ordered root: / id: 41 parent: 20 @@ -245,7 +272,8 @@ devno: 253:0 source: (null) target: /proc/sys/fs/binfmt_misc fstype: binfmt_misc -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 42 parent: 35 @@ -254,7 +282,8 @@ devno: 0:34 source: fusectl target: /sys/fs/fuse/connections fstype: fusectl -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 43 parent: 16 @@ -263,7 +292,8 @@ devno: 0:35 source: gvfs-fuse-daemon target: /home/kzak/.gvfs fstype: fuse.gvfs-fuse-daemon -optstr: rw,nosuid,nodev,relatime,user_id=500,group_id=500 +VFS-optstr: rw,nosuid,nodev,relatime +FS-opstr: rw,user_id=500,group_id=500 root: / id: 44 parent: 41 @@ -272,7 +302,8 @@ devno: 0:36 source: sunrpc target: /var/lib/nfs/rpc_pipefs fstype: rpc_pipefs -optstr: rw,relatime +VFS-optstr: rw,relatime +FS-opstr: rw root: / id: 45 parent: 20 @@ -281,7 +312,8 @@ devno: 0:37 source: //foo.home/bar/ target: /mnt/sounds fstype: cifs -optstr: rw,relatime,unc=\\foo.home\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344 +VFS-optstr: rw,relatime +FS-opstr: rw,unc=\\foo.home\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344 root: / id: 47 parent: 20 diff --git a/tests/expected/libmount/tabfiles-parse-mtab b/tests/expected/libmount/tabfiles-parse-mtab index b8ea0cfd..9838a9cd 100644 --- a/tests/expected/libmount/tabfiles-parse-mtab +++ b/tests/expected/libmount/tabfiles-parse-mtab @@ -2,54 +2,56 @@ source: /dev/sda4 target: / fstype: ext3 -optstr: rw,noatime +VFS-optstr: rw,noatime ------ fs: source: proc target: /proc fstype: proc -optstr: rw +VFS-optstr: rw ------ fs: source: sysfs target: /sys fstype: sysfs -optstr: rw +VFS-optstr: rw ------ fs: source: devpts target: /dev/pts fstype: devpts -optstr: rw,gid=5,mode=620 +VFS-optstr: rw +FS-opstr: gid=5,mode=620 ------ fs: source: tmpfs target: /dev/shm fstype: tmpfs -optstr: rw +VFS-optstr: rw ------ fs: source: /dev/sda6 target: /boot fstype: ext3 -optstr: rw,noatime +VFS-optstr: rw,noatime ------ fs: source: /dev/mapper/kzak-home target: /home/kzak fstype: ext4 -optstr: rw,noatime +VFS-optstr: rw,noatime ------ fs: source: (null) target: /proc/sys/fs/binfmt_misc fstype: binfmt_misc -optstr: rw +VFS-optstr: rw ------ fs: source: fusectl target: /sys/fs/fuse/connections fstype: fusectl -optstr: rw +VFS-optstr: rw ------ fs: source: gvfs-fuse-daemon target: /home/kzak/.gvfs fstype: fuse.gvfs-fuse-daemon -optstr: rw,nosuid,nodev,user=kzak +VFS-optstr: rw,nosuid,nodev +user-optstr: user=kzak ------ fs: source: sunrpc target: /var/lib/nfs/rpc_pipefs fstype: rpc_pipefs -optstr: rw +VFS-optstr: rw diff --git a/tests/expected/libmount/update-mtab-mount b/tests/expected/libmount/update-mtab-mount index 6744e8c0..271d86bc 100644 --- a/tests/expected/libmount/update-mtab-mount +++ b/tests/expected/libmount/update-mtab-mount @@ -1,4 +1,4 @@ -/dev/sda1 /mnt/foo ext3 rw,bbb,ccc,fff=FFF,ddd,noexec 0 0 -/dev/sdb1 /mnt/bar ext3 gg=G,ffff=f,ro,noatime 0 0 +/dev/sda1 /mnt/foo ext3 rw,noexec,bbb,ccc,fff=FFF,ddd 0 0 +/dev/sdb1 /mnt/bar ext3 ro,noatime,gg=G,ffff=f 0 0 /dev/sda2 /mnt/bar ext3 rw,noatime 0 0 /dev/sda1 /mnt/gogo ext3 rw,noatime,nosuid 0 0 diff --git a/tests/expected/libmount/update-mtab-move b/tests/expected/libmount/update-mtab-move index 6c6ec666..c6dffdbe 100644 --- a/tests/expected/libmount/update-mtab-move +++ b/tests/expected/libmount/update-mtab-move @@ -1,4 +1,4 @@ -/dev/sda1 /mnt/newfoo ext3 rw,bbb,ccc,fff=FFF,ddd,noexec 0 0 -/dev/sdb1 /mnt/bar ext3 gg=G,ffff=f,ro,noatime 0 0 +/dev/sda1 /mnt/newfoo ext3 rw,noexec,bbb,ccc,fff=FFF,ddd 0 0 +/dev/sdb1 /mnt/bar ext3 ro,noatime,gg=G,ffff=f 0 0 /dev/sda2 /mnt/newbar ext3 rw,noatime 0 0 /dev/sda1 /mnt/gogo ext3 rw,noatime,nosuid 0 0 -- 2.39.5