extern char *mangle(const char *s);
extern void unmangle_to_buffer(const char *s, char *buf, size_t len);
-extern char *unmangle(const char *s);
+extern char *unmangle(const char *s, const char **end);
static inline void unmangle_string(char *s)
{
/*
* Returns mallocated buffer or NULL in case of error.
*/
-char *unmangle(const char *s)
+char *unmangle(const char *s, const char **end)
{
char *buf;
- const char *end;
+ const char *e;
size_t sz;
if (!s)
return NULL;
- end = skip_nonspaces(s);
- sz = end - s + 1;
+ e = skip_nonspaces(s);
+ sz = e - s + 1;
+
+ if (end)
+ *end = e;
buf = malloc(sz);
if (!buf)
printf("mangled: '%s'\n", mangle(argv[2]));
else if (!strcmp(argv[1], "--unmangle")) {
- char *x = unmangle(argv[2]);
+ char *x = unmangle(argv[2], NULL);
if (x) {
printf("unmangled: '%s'\n", x);
s = skip_spaces(buf);
} while (*s == '\0' || *s == '#');
- me.mnt_fsname = unmangle(s);
- s = skip_nonspaces(s);
+ me.mnt_fsname = unmangle(s, &s);
s = skip_spaces(s);
- me.mnt_dir = unmangle(s);
- s = skip_nonspaces(s);
+ me.mnt_dir = unmangle(s, &s);
s = skip_spaces(s);
- me.mnt_type = unmangle(s);
- s = skip_nonspaces(s);
+ me.mnt_type = unmangle(s, &s);
s = skip_spaces(s);
- me.mnt_opts = unmangle(s);
- s = skip_nonspaces(s);
+ me.mnt_opts = unmangle(s, &s);
s = skip_spaces(s);
if (isdigit(*s)) {
break;
swapFiles = q;
- if ((p = unmangle(line)) == NULL)
+ if ((p = unmangle(line, NULL)) == NULL)
break;
swapFiles[numSwaps++] = canonicalize_path(p);
*p = '\0';
for (++p; *p && isblank((unsigned int) *p); p++);
- dev = unmangle(line);
+ dev = unmangle(line, NULL);
if (!dev)
continue;
cn = canonicalize_path(dev);
if (!(cxt->flags & MNT_FL_FAKE)) {
if (mount(src, target, type, flags, cxt->mountdata)) {
cxt->syscall_status = -errno;
- DBG(CXT, mnt_debug_h(cxt, "mount(2) failed [errno=%d]",
+ DBG(CXT, mnt_debug_h(cxt, "mount(2) failed [errno=%d %m]",
-cxt->syscall_status));
return cxt->syscall_status;
}
rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs));
if (!rc)
rc = mnt_fs_set_optstr(cxt->fs, mnt_fs_get_optstr(fs));
+ if (!rc && mnt_fs_get_bindsrc(fs))
+ rc = mnt_fs_set_bindsrc(cxt->fs, mnt_fs_get_bindsrc(fs));
+ DBG(CXT, mnt_debug_h(cxt, "umount: mtab applied"));
cxt->flags |= MNT_FL_TAB_APPLIED;
return rc;
}
if (!mnt_context_is_restricted(cxt))
return 0; /* superuser mount */
+ DBG(CXT, mnt_debug_h(cxt, "umount: evaluating permissions"));
+
if (!(cxt->flags & MNT_FL_TAB_APPLIED)) {
DBG(CXT, mnt_debug_h(cxt,
"cannot found %s in mtab and you are not root",
tgt = mnt_fs_get_target(cxt->fs);
src = mnt_fs_get_source(cxt->fs);
+ if (mnt_fs_get_bindsrc(cxt->fs)) {
+ src = mnt_fs_get_bindsrc(cxt->fs);
+ DBG(CXT, mnt_debug_h(cxt,
+ "umount: using bind source: %s", src));
+ }
+
/* If fstab contains the two lines
* /dev/sda1 /mnt/zip auto user,noauto 0 0
* /dev/sda4 /mnt/zip auto user,noauto 0 0
list_del(&fs->ents);
free(fs->source);
+ free(fs->bindsrc);
free(fs->tagname);
free(fs->tagval);
free(fs->root);
return 0;
}
+/**
+ * mnt_fs_get_bindsrc:
+ * @fs: /dev/.mount/utab entry
+ *
+ * Returns: full path that was used for mount(2) on MS_BIND
+ */
+const char *mnt_fs_get_bindsrc(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->bindsrc : NULL;
+}
+
+/**
+ * mnt_fs_set_bindsrc:
+ * @fs: filesystem
+ * @src: path
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_set_bindsrc(mnt_fs *fs, const char *src)
+{
+ char *p = NULL;
+
+ assert(fs);
+ if (!fs)
+ return -EINVAL;
+ if (src) {
+ p = strdup(src);
+ if (!p)
+ return -ENOMEM;
+ }
+ free(fs->bindsrc);
+ fs->bindsrc = p;
+ return 0;
+}
+
/**
* mnt_fs_get_id:
* @fs: /proc/self/mountinfo entry
if (!fs)
return -EINVAL;
fprintf(file, "------ fs: %p\n", fs);
- 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));
+ 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_root(fs))
+ fprintf(file, "root: %s\n", mnt_fs_get_root(fs));
+ if (mnt_fs_get_bindsrc(fs))
+ fprintf(file, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs));
if (mnt_fs_get_freq(fs))
- fprintf(file, "freq: %d\n", mnt_fs_get_freq(fs));
+ fprintf(file, "freq: %d\n", mnt_fs_get_freq(fs));
if (mnt_fs_get_passno(fs))
- fprintf(file, "pass: %d\n", mnt_fs_get_passno(fs));
+ fprintf(file, "pass: %d\n", mnt_fs_get_passno(fs));
if (mnt_fs_get_id(fs))
- fprintf(file, "id: %d\n", mnt_fs_get_id(fs));
+ fprintf(file, "id: %d\n", mnt_fs_get_id(fs));
if (mnt_fs_get_parent_id(fs))
- fprintf(file, "parent: %d\n", mnt_fs_get_parent_id(fs));
+ fprintf(file, "parent: %d\n", mnt_fs_get_parent_id(fs));
if (mnt_fs_get_devno(fs))
- fprintf(file, "devno: %d:%d\n", major(mnt_fs_get_devno(fs)),
+ fprintf(file, "devno: %d:%d\n", major(mnt_fs_get_devno(fs)),
minor(mnt_fs_get_devno(fs)));
return 0;
}
*/
typedef struct _mnt_context mnt_context;
-/*
- * Tab file format
- */
-enum {
- MNT_FMT_FSTAB = 1, /* /etc/{fs,m}tab */
- MNT_FMT_MTAB = MNT_FMT_FSTAB, /* alias */
- MNT_FMT_MOUNTINFO /* /proc/#/mountinfo */
-};
-
/*
* Actions
*/
extern int mnt_fs_set_passno(mnt_fs *ent, int passno);
extern const char *mnt_fs_get_root(mnt_fs *fs);
extern int mnt_fs_set_root(mnt_fs *fs, const char *root);
+extern const char *mnt_fs_get_bindsrc(mnt_fs *fs);
+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);
/* library private paths */
#define MNT_PATH_UTAB "/dev/.mount/utab"
+#define MNT_UTAB_HEADER "# libmount utab file\n"
+
#ifdef TEST_PROGRAM
struct mtest {
const char *name;
/*
* This struct represents one entry in mtab/fstab/mountinfo file.
+ * (note that fstab[1] means the first column from fstab, and so on...)
*/
struct _mnt_fs {
struct list_head ents;
int parent; /* moutninfo[2]: parent */
dev_t devno; /* moutninfo[3]: st_dev */
- char *source; /* fstab[1]: mountinfo[10]:
+ char *bindsrc; /* utab, full path from fstab[1] for bind mounts */
+
+ char *source; /* fstab[1], mountinfo[10]:
* source dev, file, dir or TAG */
char *tagname; /* fstab[1]: tag name - "LABEL", "UUID", ..*/
char *tagval; /* tag value */
struct list_head ents; /* list of entries (mentry) */
};
+extern mnt_tab *__mnt_new_tab_from_file(const char *filename, int fmt);
+
+/*
+ * Tab file format
+ */
+enum {
+ MNT_FMT_GUESS,
+ MNT_FMT_FSTAB, /* /etc/{fs,m}tab */
+ MNT_FMT_MTAB = MNT_FMT_FSTAB, /* alias */
+ MNT_FMT_MOUNTINFO, /* /proc/#/mountinfo */
+ MNT_FMT_UTAB /* /dev/.mount/utab */
+};
+
/*
* Mount context -- high-level API
/*
* Parses one line from {fs,m}tab
*/
-static int mnt_tab_parse_file_line(mnt_fs *fs, char *s)
+static int mnt_parse_tab_line(mnt_fs *fs, char *s)
{
int rc, n = 0;
char *src, *fstype, *optstr;
if (!rc)
rc = __mnt_fs_set_optstr_ptr(fs, optstr, TRUE);
} else {
- DBG(TAB, mnt_debug( "parse error: [sscanf rc=%d]: '%s'", rc, s));
+ DBG(TAB, mnt_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
rc = -EINVAL;
}
s = skip_spaces(s + n);
if (*s) {
if (next_number(&s, &fs->freq) != 0) {
- if (*s)
+ if (*s) {
+ DBG(TAB, mnt_debug("tab parse error: [freq]"));
rc = -EINVAL;
- } else if (next_number(&s, &fs->passno) != 0 && *s)
+ }
+ } else if (next_number(&s, &fs->passno) != 0 && *s) {
+ DBG(TAB, mnt_debug("tab parse error: [passno]"));
rc = -EINVAL;
+ }
}
return rc;
if (!rc)
rc = __mnt_fs_set_source_ptr(fs, src);
} else {
- DBG(TAB, mnt_debug("parse error [field=%d]: '%s'", rc, s));
+ DBG(TAB, mnt_debug(
+ "mountinfo parse error [sscanf rc=%d]: '%s'", rc, s));
rc = -EINVAL;
}
return rc;
}
+/*
+ * Parses one line from utab file
+ */
+static int mnt_parse_utab_line(mnt_fs *fs, const char *s)
+{
+ const char *p = s;
+
+ assert(fs);
+ assert(s);
+ assert(!fs->source);
+ assert(!fs->target);
+
+ while (p && *p) {
+ while (*p == ' ') p++;
+ if (!*p)
+ break;
+
+ if (!fs->source && !strncmp(p, "SRC=", 4)) {
+ char *v = unmangle(p + 4, &p);
+ if (!v)
+ goto enomem;
+ if (strcmp(v, "none"))
+ __mnt_fs_set_source_ptr(fs, v);
+
+ } else if (!fs->target && !strncmp(p, "TARGET=", 7)) {
+ fs->target = unmangle(p + 7, &p);
+ if (!fs->target)
+ goto enomem;
+
+ } else if (!fs->root && !strncmp(p, "ROOT=", 5)) {
+ fs->root = unmangle(p + 5, &p);
+ if (!fs->root)
+ goto enomem;
+
+ } else if (!fs->bindsrc && !strncmp(p, "BINDSRC=", 8)) {
+ fs->bindsrc = unmangle(p + 8, &p);
+ if (!fs->bindsrc)
+ goto enomem;
+
+ } else if (!fs->optstr && !strncmp(p, "OPTS=", 5)) {
+ fs->optstr = unmangle(p + 5, &p);
+ if (!fs->optstr)
+ goto enomem;
+ } else {
+ /* unknown variable */
+ while (*p && *p != ' ') p++;
+ }
+ }
+
+ return 0;
+enomem:
+ DBG(TAB, mnt_debug("utab parse error: ENOMEM"));
+ return -ENOMEM;
+}
+
/*
* Returns {m,fs}tab or mountinfo file format (MNT_FMT_*)
*
- * The "mountinfo" format is always: "<number> <number> ... "
+ * Note that we aren't tring to guess utab file format, because this file has
+ * to be always parsed by private libmount routines with explicitly defined
+ * format.
+ *
+ * mountinfo: "<number> <number> ... "
*/
-static int detect_fmt(char *line)
+static int guess_tab_format(char *line)
{
unsigned int a, b;
- return sscanf(line, "%u %u", &a, &b) == 2 ?
- MNT_FMT_MOUNTINFO : MNT_FMT_FSTAB;
+ if (sscanf(line, "%u %u", &a, &b) == 2)
+ return MNT_FMT_MOUNTINFO;
+ return MNT_FMT_FSTAB;
}
s = skip_spaces(buf);
} while (*s == '\0' || *s == '#');
- /*DBG(TAB, mnt_debug_h(tb, "%s:%d: %s", filename, *nlines, s));*/
-
- if (!tb->fmt)
- tb->fmt = detect_fmt(s);
+ if (tb->fmt == MNT_FMT_GUESS)
+ tb->fmt = guess_tab_format(s);
if (tb->fmt == MNT_FMT_FSTAB) {
- if (mnt_tab_parse_file_line(fs, s) != 0)
+ if (mnt_parse_tab_line(fs, s) != 0)
goto err;
} else if (tb->fmt == MNT_FMT_MOUNTINFO) {
if (mnt_parse_mountinfo_line(fs, s) != 0)
goto err;
+
+ } else if (tb->fmt == MNT_FMT_UTAB) {
+ if (mnt_parse_utab_line(fs, s) != 0)
+ goto err;
}
+
/* 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)
+ if (!fs->optstr) {
+ DBG(TAB, mnt_debug_h(tb, "failed to merge optstr"));
return -ENOMEM;
+ }
}
-/*
- DBG(TAB, mnt_debug_h(tb, "%s:%d: SOURCE:%s, MNTPOINT:%s, TYPE:%s, "
- "OPTS:%s, FREQ:%d, PASSNO:%d",
- filename, *nlines,
- fs->source, fs->target, fs->fstype,
- fs->optstr, fs->freq, fs->passno));
-*/
+
+ /*DBG(TAB, mnt_fs_print_debug(fs, stderr));*/
+
return 0;
err:
- DBG(TAB, mnt_debug_h(tb, "%s:%d: parse error", filename, *nlines));
+ DBG(TAB, mnt_debug_h(tb, "%s:%d: %s parse error", filename, *nlines,
+ tb->fmt == MNT_FMT_MOUNTINFO ? "mountinfo" :
+ tb->fmt == MNT_FMT_FSTAB ? "fstab" : "utab"));
/* by default all errors are recoverable, otherwise behavior depends on
* errcb() function. See mnt_tab_set_parser_errcb().
return 0;
}
+mnt_tab *__mnt_new_tab_from_file(const char *filename, int fmt)
+{
+ mnt_tab *tb;
+ struct stat st;
+
+ assert(filename);
+
+ if (!filename)
+ return NULL;
+ if (stat(filename, &st) || st.st_size == 0)
+ return NULL;
+ tb = mnt_new_tab();
+ if (tb) {
+ tb->fmt = fmt;
+ if (mnt_tab_parse_file(tb, filename) != 0) {
+ mnt_free_tab(tb);
+ tb = NULL;
+ }
+ }
+ return tb;
+}
/**
* mnt_new_tab_from_file:
*/
mnt_tab *mnt_new_tab_from_file(const char *filename)
{
- mnt_tab *tb;
-
- assert(filename);
-
- if (!filename)
- return NULL;
- tb = mnt_new_tab();
- if (tb && mnt_tab_parse_file(tb, filename) != 0) {
- mnt_free_tab(tb);
- tb = NULL;
- }
- return tb;
+ return __mnt_new_tab_from_file(filename, MNT_FMT_GUESS);
}
/**
if (!filename)
filename = mnt_get_fstab_path();
+ tb->fmt = MNT_FMT_FSTAB;
+
f = fopen(filename, "r");
if (f) {
int rc = mnt_tab_parse_stream(tb, f, filename);
if (!tb || !uf)
return NULL;
+ DBG(TAB, mnt_debug_h(tb, "merging userspace fs"));
+
src = mnt_fs_get_srcpath(uf);
target = mnt_fs_get_target(uf);
- optstr = mnt_fs_get_vfs_optstr(uf);
+ optstr = mnt_fs_get_optstr(uf);
root = mnt_fs_get_root(uf);
if (!src || !target || !optstr || !root)
break;
}
- if (fs)
+ if (fs) {
+ DBG(TAB, mnt_debug_h(tb, "found fs -- appending userspace optstr"));
mnt_fs_append_userspace_optstr(fs, optstr);
+ mnt_fs_set_bindsrc(fs, mnt_fs_get_bindsrc(uf));
+
+ DBG(TAB, mnt_debug_h(tb, "found fs:"));
+ DBG(TAB, mnt_fs_print_debug(fs, stderr));
+ }
return fs;
}
* useless /etc/mtab
* -- read kernel information from /proc/self/mountinfo
*/
+ tb->fmt = MNT_FMT_MOUNTINFO;
rc = mnt_tab_parse_file(tb, _PATH_PROC_MOUNTINFO);
- if (rc)
+ if (rc) {
/* hmm, old kernel? ...try /proc/mounts */
+ tb->fmt = MNT_FMT_MTAB;
return mnt_tab_parse_file(tb, _PATH_PROC_MOUNTS);
+ }
/*
* try to read userspace specific information from /dev/.mount/utabs
*/
utab = mnt_get_utab_path();
if (utab) {
- mnt_tab *u_tb = mnt_new_tab_from_file(utab);
+ mnt_tab *u_tb = __mnt_new_tab_from_file(utab, MNT_FMT_UTAB);
if (u_tb) {
mnt_fs *u_fs;
};
static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent);
-static int get_fs_root(mnt_fs *fs, unsigned long mountflags, char **result);
+static int set_fs_root(mnt_fs *fs, unsigned long mountflags);
/**
* mnt_new_update:
u = NULL;
if (!(mountflags & MS_REMOUNT)) {
- rc = get_fs_root(fs, mountflags, &(*ent)->root);
+ rc = set_fs_root(*ent, mountflags);
if (rc)
goto err;
}
return rc;
}
-static int get_fs_root(mnt_fs *fs, unsigned long mountflags, char **result)
+static int set_fs_root(mnt_fs *fs, unsigned long mountflags)
{
char *root = NULL, *mnt = NULL;
const char *fstype, *optstr;
int rc = -ENOMEM;
assert(fs);
- assert(result);
DBG(UPDATE, mnt_debug("setting FS root"));
mnt_fs *src_fs;
src = mnt_fs_get_srcpath(fs);
- if (src)
+ if (src) {
+ rc = mnt_fs_set_bindsrc(fs, src);
+ if (rc)
+ goto err;
mnt = mnt_get_mountpoint(src);
+ }
if (!mnt) {
rc = -EINVAL;
goto err;
}
root = mnt_get_fs_root(src, mnt);
- tb = mnt_new_tab_from_file(_PATH_PROC_MOUNTINFO);
+ tb = __mnt_new_tab_from_file(_PATH_PROC_MOUNTINFO, MNT_FMT_MOUNTINFO);
if (!tb)
goto dflt;
src_fs = mnt_tab_find_target(tb, mnt, MNT_ITER_BACKWARD);
/* set device name and fs */
src = mnt_fs_get_srcpath(src_fs);
- mnt_fs_set_source(fs, src);
+ rc = mnt_fs_set_source(fs, src);
+ if (rc)
+ goto err;
mnt_fs_set_fstype(fs, mnt_fs_get_fstype(src_fs));
char *vol = NULL, *p;
size_t sz, volsz = 0;
- // TODO: remove this stupid cast...
if (mnt_optstr_get_option((char *) optstr, "subvol", &vol, &volsz))
goto dflt;
if (!root)
goto err;
}
- *result = root;
+ fs->root = root;
+
+ DBG(UPDATE, mnt_debug("FS root result: %s", root));
+
free(mnt);
return 0;
err:
static int fprintf_utab_fs(FILE *f, mnt_fs *fs)
{
- char *root = NULL, *target = NULL, *optstr = NULL,
- *fstype = NULL, *source = NULL;
- int rc = -1;
- dev_t devno;
+ char *p;
assert(fs);
assert(f);
if (!fs || !f)
return -EINVAL;
- devno = mnt_fs_get_devno(fs);
- source = mangle(mnt_fs_get_source(fs));
- root = mangle(mnt_fs_get_root(fs));
- target = mangle(mnt_fs_get_target(fs));
- fstype = mangle(mnt_fs_get_fstype(fs));
- optstr = mangle(mnt_fs_get_optstr(fs));
-
- if (!root || !target || !optstr)
- goto done;
- rc = fprintf(f, "%i %i %u:%u %s %s %s - %s %s %s\n",
- mnt_fs_get_id(fs),
- mnt_fs_get_parent_id(fs),
- major(devno), minor(devno),
- root,
- target,
- optstr,
- fstype ? fstype : "auto",
- source ? source : "none",
- "none");
- rc = 0;
-done:
- free(root);
- free(target);
- free(optstr);
- free(fstype);
- free(source);
- return rc;
+ p = mangle(mnt_fs_get_source(fs));
+ if (p) {
+ fprintf(f, "SRC=%s ", p);
+ free(p);
+ }
+ p = mangle(mnt_fs_get_target(fs));
+ if (p) {
+ fprintf(f, "TARGET=%s ", p);
+ free(p);
+ }
+ p = mangle(mnt_fs_get_root(fs));
+ if (p) {
+ fprintf(f, "ROOT=%s ", p);
+ free(p);
+ }
+ p = mangle(mnt_fs_get_bindsrc(fs));
+ if (p) {
+ fprintf(f, "BINDSRC=%s ", p);
+ free(p);
+ }
+ p = mangle(mnt_fs_get_optstr(fs));
+ if (p) {
+ fprintf(f, "OPTS=%s", p);
+ free(p);
+ }
+
+ fputc('\n', f);
+
+ return 0;
}
static int update_tab(mnt_update *upd, const char *filename, mnt_tab *tb)
static int update_remove_entry(mnt_update *upd, const char *filename, mnt_lock *lc)
{
mnt_tab *tb;
- int rc = -EINVAL, u_lc = -1;
+ int rc = 0, u_lc = -1;
assert(upd);
assert(upd->target);
else if (upd->userspace_only)
u_lc = utab_lock(filename);
- tb = mnt_new_tab_from_file(filename);
+ tb = __mnt_new_tab_from_file(filename,
+ upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
if (tb) {
mnt_fs *rem = mnt_tab_find_target(tb, upd->target, MNT_ITER_BACKWARD);
if (rem) {
static int update_modify_target(mnt_update *upd, const char *filename, mnt_lock *lc)
{
mnt_tab *tb = NULL;
- int rc = -EINVAL, u_lc = -1;
+ int rc = 0, u_lc = -1;
DBG(UPDATE, mnt_debug_h(upd, "%s: modify target", filename));
else if (upd->userspace_only)
u_lc = utab_lock(filename);
- tb = mnt_new_tab_from_file(filename);
+ tb = __mnt_new_tab_from_file(filename,
+ upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
if (tb) {
mnt_fs *cur = mnt_tab_find_target(tb, upd->target, MNT_ITER_BACKWARD);
if (cur) {
static int update_modify_options(mnt_update *upd, const char *filename, mnt_lock *lc)
{
mnt_tab *tb = NULL;
- int rc = -EINVAL, u_lc = -1;
+ int rc = 0, u_lc = -1;
assert(upd);
assert(upd->fs);
else if (upd->userspace_only)
u_lc = utab_lock(filename);
- tb = mnt_new_tab_from_file(filename);
+ tb = __mnt_new_tab_from_file(filename,
+ 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),
*/
char *mnt_unmangle(const char *str)
{
- return unmangle(str);
+ return unmangle(str, NULL);
}
/**