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);
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;
}
/*
- * 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.
*/
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;
}
*/
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)
*/
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;
}
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!"));
}
+ 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",
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 */
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 */
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);
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;