]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: fix mount -a to work with optlist
authorKarel Zak <kzak@redhat.com>
Thu, 6 Oct 2022 10:02:41 +0000 (12:02 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 3 Jan 2023 11:58:42 +0000 (12:58 +0100)
The original code uses libmnt_fs instance to store mount options. The
new uses libmnt_fs only for library API backward compatibility, but
internally it uses libmnt_optlist. Let's use optlist also to save
context template.

Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context.c
libmount/src/mountP.h
libmount/src/optlist.c

index e602ce54bc97996a1c7ec2cfdd4b8f6d4a242424..3551b0d77bcf889ce03aa8425e4c7bf7149fadf0 100644 (file)
@@ -102,7 +102,8 @@ void mnt_free_context(struct libmnt_context *cxt)
        mnt_unref_table(cxt->fstab);
        mnt_unref_cache(cxt->cache);
        mnt_unref_fs(cxt->fs);
-       mnt_unref_fs(cxt->fs_template);
+
+       mnt_unref_optlist(cxt->optlist_saved);
        mnt_unref_optlist(cxt->optlist);
 
        mnt_free_lock(cxt->lock);
@@ -152,11 +153,13 @@ int mnt_reset_context(struct libmnt_context *cxt)
        mnt_unref_fs(cxt->fs);
        mnt_unref_table(cxt->mountinfo);
        mnt_unref_table(cxt->utab);
+       mnt_unref_optlist(cxt->optlist);
 
        free(cxt->helper);
 
        cxt->fs = NULL;
        cxt->mountinfo = NULL;
+       cxt->optlist = NULL;
        cxt->utab = NULL;
        cxt->helper = NULL;
        cxt->mountdata = NULL;
@@ -194,7 +197,7 @@ int mnt_reset_context(struct libmnt_context *cxt)
 }
 
 /*
- * Saves the current context FS setting (mount options, etc) to make it usable after
+ * Saves the current context setting (mount options, etc) to make it usable after
  * mnt_reset_context() or by mnt_context_apply_template(). This is usable for
  * example for mnt_context_next_mount() where for the next mount operation we
  * need to restore to the original context setting.
@@ -203,21 +206,17 @@ int mnt_reset_context(struct libmnt_context *cxt)
  */
 int mnt_context_save_template(struct libmnt_context *cxt)
 {
-       struct libmnt_fs *fs = NULL;
-
        if (!cxt)
                return -EINVAL;
 
-       DBG(CXT, ul_debugobj(cxt, "save FS as template"));
+       DBG(CXT, ul_debugobj(cxt, "saving template"));
 
-       if (cxt->fs) {
-               fs = mnt_copy_fs(NULL, cxt->fs);
-               if (!fs)
-                       return -ENOMEM;
-       }
+       /* reset old saved data */
+       mnt_unref_optlist(cxt->optlist_saved);
+       cxt->optlist_saved = NULL;
 
-       mnt_unref_fs(cxt->fs_template);
-       cxt->fs_template = fs;
+       if (cxt->optlist)
+               cxt->optlist_saved = mnt_copy_optlist(cxt->optlist);
 
        return 0;
 }
@@ -230,31 +229,22 @@ int mnt_context_save_template(struct libmnt_context *cxt)
  */
 int mnt_context_apply_template(struct libmnt_context *cxt)
 {
-       struct libmnt_fs *fs = NULL;
-       int rc = 0;
-
        if (!cxt)
                return -EINVAL;
 
-       if (cxt->fs_template) {
-               DBG(CXT, ul_debugobj(cxt, "copy FS from template"));
-               fs = mnt_copy_fs(NULL, cxt->fs_template);
-               if (!fs)
-                       return -ENOMEM;
-               rc = mnt_context_set_fs(cxt, fs);
-               mnt_unref_fs(fs);
-       } else {
-               DBG(CXT, ul_debugobj(cxt, "no FS template, reset only"));
-               mnt_unref_fs(cxt->fs);
-               cxt->fs = NULL;
-       }
+       DBG(CXT, ul_debugobj(cxt, "restoring template"));
+       mnt_unref_optlist(cxt->optlist);
+       cxt->optlist = NULL;
 
-       return rc;
+       if (cxt->optlist_saved)
+               cxt->optlist = mnt_copy_optlist(cxt->optlist_saved);
+
+       return 0;
 }
 
 int mnt_context_has_template(struct libmnt_context *cxt)
 {
-       return cxt && cxt->fs_template ? 1 : 0;
+       return cxt && cxt->optlist_saved ? 1 : 0;
 }
 
 struct libmnt_context *mnt_copy_context(struct libmnt_context *o)
@@ -1163,13 +1153,10 @@ int mnt_context_append_options(struct libmnt_context *cxt, const char *optstr)
  */
 const char *mnt_context_get_options(struct libmnt_context *cxt)
 {
-       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
        const char *str = NULL;
 
-       if (!ls)
-               return NULL;
-
-       mnt_optlist_get_optstr(ls, &str, NULL, 0);
+       if (cxt->optlist && !mnt_optlist_is_empty(cxt->optlist))
+               mnt_optlist_get_optstr(cxt->optlist, &str, NULL, 0);
        return str;
 }
 
@@ -2199,6 +2186,8 @@ static int apply_fs(struct libmnt_context *cxt, struct libmnt_fs *fs, unsigned l
        struct libmnt_optlist *ls;
        int rc;
 
+
+
        if (!cxt->optsmode) {
                if (mnt_context_is_restricted(cxt)) {
                        DBG(CXT, ul_debugobj(cxt, "force fstab usage for non-root users!"));
@@ -2210,6 +2199,9 @@ static int apply_fs(struct libmnt_context *cxt, struct libmnt_fs *fs, unsigned l
 
        }
 
+       if (!mnt_context_get_fs(cxt))
+               return -ENOMEM;
+
        DBG(CXT, ul_debugobj(cxt, "apply entry:"));
        DBG(CXT, mnt_fs_print_debug(fs, stderr));
        DBG(CXT, ul_debugobj(cxt, "OPTSMODE (opt-part): ignore=%d, append=%d, prepend=%d, replace=%d",
index 3345a14decb80dfb4f0750185e807427aca81d74..e6ac6b6651b308d80a0f03b2ac5f0ec9245126d5 100644 (file)
@@ -371,7 +371,6 @@ struct libmnt_context
        char    *optstr_pattern;        /* for mnt_match_options() */
 
        struct libmnt_fs *fs;           /* filesystem description (type, mountpoint, device, ...) */
-       struct libmnt_fs *fs_template;  /* used for @fs on mnt_reset_context() */
 
        struct libmnt_table *fstab;     /* fstab entries */
        struct libmnt_table *mountinfo; /* already mounted filesystems */
@@ -393,7 +392,9 @@ struct libmnt_context
        struct libmnt_cache     *cache;         /* paths cache */
        struct libmnt_lock      *lock;          /* utab lock */
        struct libmnt_update    *update;        /* utab update */
+
        struct libmnt_optlist   *optlist;       /* parsed mount options */
+       struct libmnt_optlist   *optlist_saved; /* save/apply context template */
 
        const struct libmnt_optmap *map_linux;          /* system options map */
        const struct libmnt_optmap *map_userspace;      /* userspace options map */
@@ -484,6 +485,8 @@ struct libmnt_optlist;
 extern struct libmnt_optlist *mnt_new_optlist(void);
 extern void mnt_ref_optlist(struct libmnt_optlist *ls);
 extern void mnt_unref_optlist(struct libmnt_optlist *ls);
+extern struct libmnt_optlist *mnt_copy_optlist(struct libmnt_optlist *ls);
+extern int mnt_optlist_is_empty(struct libmnt_optlist *ls);
 extern unsigned int mnt_optlist_get_age(struct libmnt_optlist *ls);
 extern int mnt_optlist_register_map(struct libmnt_optlist *ls, const struct libmnt_optmap *map);
 extern int mnt_optlist_remove_opt(struct libmnt_optlist *ls, struct libmnt_opt *opt);
index edb9594912117dcffcaeae57239eb324d3ac0428..7b4033aaa7aaf7ae74fc97541e4640e07f6bd28f 100644 (file)
@@ -918,6 +918,48 @@ int mnt_optlist_get_optstr(struct libmnt_optlist *ls, const char **optstr,
        return 0;
 }
 
+struct libmnt_optlist *mnt_copy_optlist(struct libmnt_optlist *ls)
+{
+       struct libmnt_optlist *n = mnt_new_optlist();
+       struct libmnt_iter itr;
+       struct libmnt_opt *opt;
+       size_t i;
+
+       if (!n)
+               return NULL;
+
+       n->age = ls->age;
+       n->linux_map = ls->linux_map;
+
+       for (i = 0; i < ls->nmaps; i++)
+               n->maps[i] = ls->maps[i];
+       n->nmaps = ls->nmaps;
+
+       mnt_reset_iter(&itr, MNT_ITER_FORWARD);
+
+       while (mnt_optlist_next_opt(ls, &itr, &opt) == 0) {
+               struct libmnt_opt *no;
+
+               no = optlist_new_opt(n,
+                       opt->name, opt->name ? strlen(opt->name) : 0,
+                       opt->value, opt->value ? strlen(opt->value) : 0,
+                       opt->map, opt->ent, NULL);
+               if (no) {
+                       no->src = opt->src;
+                       no->external = opt->external;
+               }
+       }
+
+       n->merged = ls->merged;
+       return n;
+}
+
+
+int mnt_optlist_is_empty(struct libmnt_optlist *ls)
+{
+       return ls == NULL || list_empty(&ls->opts);
+}
+
 unsigned int mnt_optlist_get_age(struct libmnt_optlist *ls)
 {
        return ls ? ls->age : 0;