From: Karel Zak Date: Thu, 31 Oct 2019 09:31:53 +0000 (+0100) Subject: libmount: save current FS setting as template X-Git-Tag: v2.35-rc1~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e83c09d49e52eadf1715e682c547b0ff9744983e;p=thirdparty%2Futil-linux.git libmount: save current FS setting as template 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 --- diff --git a/libmount/src/context.c b/libmount/src/context.c index fd6cfc8369..f925bfaf05 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -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; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index 4ba1308796..cba6ff92fc 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -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);