]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: save current FS setting as template
authorKarel Zak <kzak@redhat.com>
Thu, 31 Oct 2019 09:31:53 +0000 (10:31 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 31 Oct 2019 11:25:08 +0000 (12:25 +0100)
This commit adds new functions to save and reuse the current FS
setting (mount options from command line, etc) after context reset.
It's usable for example in "mount --all" when we use the same context
for more times for more mount operations.

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

index fd6cfc8369daa87dcffe69ddcd673247da7356da..f925bfaf05c1d3dc393937292e8bef7855fbbea8 100644 (file)
@@ -99,6 +99,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_context_clear_loopdev(cxt);
        mnt_free_lock(cxt->lock);
@@ -191,9 +193,75 @@ int mnt_reset_context(struct libmnt_context *cxt)
        cxt->flags |= (fl & MNT_FL_NOSWAPMATCH);
        cxt->flags |= (fl & MNT_FL_TABPATHS_CHECKED);
 
+       mnt_context_apply_template(cxt);
+
+       return 0;
+}
+
+/*
+ * Saves the current context FS 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.
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+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"));
+
+       if (cxt->fs) {
+               fs = mnt_copy_fs(NULL, cxt->fs);
+               if (!fs)
+                       return -ENOMEM;
+       }
+
+       mnt_unref_fs(cxt->fs_template);
+       cxt->fs_template = fs;
+
        return 0;
 }
 
+/*
+ * Restores context FS setting from previously saved template (see
+ * mnt_context_save_template()).
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+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;
+       }
+
+       return rc;
+}
+
+int mnt_context_has_template(struct libmnt_context *cxt)
+{
+       return cxt && cxt->fs_template ? 1 : 0;
+}
+
 struct libmnt_context *mnt_copy_context(struct libmnt_context *o)
 {
        struct libmnt_context *n;
@@ -823,6 +891,7 @@ int mnt_context_set_fs(struct libmnt_context *cxt, struct libmnt_fs *fs)
        if (!cxt)
                return -EINVAL;
 
+       DBG(CXT, ul_debugobj(cxt, "setting new FS"));
        mnt_ref_fs(fs);                 /* new */
        mnt_unref_fs(cxt->fs);          /* old */
        cxt->fs = fs;
index 4ba1308796359c4e5bb7538f7d46274ace47c543..cba6ff92fc959a55e7c18034949e85e848fb4e04 100644 (file)
@@ -295,6 +295,7 @@ 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 (or mtab for some remounts) entries */
        struct libmnt_table *mtab;      /* mtab entries */
@@ -456,6 +457,10 @@ extern int mnt_context_get_generic_excode(int rc, char *buf, size_t bufsz, char
 extern int mnt_context_get_mount_excode(struct libmnt_context *cxt, int mntrc, char *buf, size_t bufsz);
 extern int mnt_context_get_umount_excode(struct libmnt_context *cxt, int mntrc, char *buf, size_t bufsz);
 
+extern int mnt_context_has_template(struct libmnt_context *cxt);
+extern int mnt_context_apply_template(struct libmnt_context *cxt);
+extern int mnt_context_save_template(struct libmnt_context *cxt);
+
 /* tab_update.c */
 extern int mnt_update_set_filename(struct libmnt_update *upd,
                                   const char *filename, int userspace_only);