summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mangle.h2
-rw-r--r--lib/mangle.c13
-rw-r--r--mount/mount_mntent.c12
-rw-r--r--mount/swapon.c4
-rw-r--r--shlibs/mount/src/context_mount.c2
-rw-r--r--shlibs/mount/src/context_umount.c11
-rw-r--r--shlibs/mount/src/fs.c60
-rw-r--r--shlibs/mount/src/mount.h.in11
-rw-r--r--shlibs/mount/src/mountP.h20
-rw-r--r--shlibs/mount/src/tab_parse.c169
-rw-r--r--shlibs/mount/src/tab_update.c101
-rw-r--r--shlibs/mount/src/utils.c2
12 files changed, 285 insertions, 122 deletions
diff --git a/include/mangle.h b/include/mangle.h
index 5dda902f..76d29bfa 100644
--- a/include/mangle.h
+++ b/include/mangle.h
@@ -8,7 +8,7 @@
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)
{
diff --git a/lib/mangle.c b/lib/mangle.c
index 938dd8e5..398323a3 100644
--- a/lib/mangle.c
+++ b/lib/mangle.c
@@ -79,17 +79,20 @@ static inline const char *skip_nonspaces(const 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)
@@ -114,7 +117,7 @@ int main(int argc, char *argv[])
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);
diff --git a/mount/mount_mntent.c b/mount/mount_mntent.c
index 08e5bf48..9e31d12f 100644
--- a/mount/mount_mntent.c
+++ b/mount/mount_mntent.c
@@ -126,17 +126,13 @@ my_getmntent (mntFILE *mfp) {
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)) {
diff --git a/mount/swapon.c b/mount/swapon.c
index f0577bbb..e9ccc94a 100644
--- a/mount/swapon.c
+++ b/mount/swapon.c
@@ -179,7 +179,7 @@ read_proc_swaps(void) {
break;
swapFiles = q;
- if ((p = unmangle(line)) == NULL)
+ if ((p = unmangle(line, NULL)) == NULL)
break;
swapFiles[numSwaps++] = canonicalize_path(p);
@@ -220,7 +220,7 @@ display_summary(void)
*p = '\0';
for (++p; *p && isblank((unsigned int) *p); p++);
- dev = unmangle(line);
+ dev = unmangle(line, NULL);
if (!dev)
continue;
cn = canonicalize_path(dev);
diff --git a/shlibs/mount/src/context_mount.c b/shlibs/mount/src/context_mount.c
index 960126d6..cb681e0d 100644
--- a/shlibs/mount/src/context_mount.c
+++ b/shlibs/mount/src/context_mount.c
@@ -354,7 +354,7 @@ static int do_mount(mnt_context *cxt, const char *try_type)
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;
}
diff --git a/shlibs/mount/src/context_umount.c b/shlibs/mount/src/context_umount.c
index 00bad109..7cb4a2a4 100644
--- a/shlibs/mount/src/context_umount.c
+++ b/shlibs/mount/src/context_umount.c
@@ -83,7 +83,10 @@ static int lookup_umount_fs(mnt_context *cxt)
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;
}
@@ -150,6 +153,8 @@ static int evaluate_permissions(mnt_context *cxt)
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",
@@ -187,6 +192,12 @@ static int evaluate_permissions(mnt_context *cxt)
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
diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c
index 140bdb19..a11061d9 100644
--- a/shlibs/mount/src/fs.c
+++ b/shlibs/mount/src/fs.c
@@ -50,6 +50,7 @@ void mnt_free_fs(mnt_fs *fs)
list_del(&fs->ents);
free(fs->source);
+ free(fs->bindsrc);
free(fs->tagname);
free(fs->tagval);
free(fs->root);
@@ -654,6 +655,42 @@ int mnt_fs_set_root(mnt_fs *fs, const char *root)
}
/**
+ * 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
*
@@ -863,20 +900,25 @@ int mnt_fs_print_debug(mnt_fs *fs, FILE *file)
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;
}
diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in
index 11231719..03753f78 100644
--- a/shlibs/mount/src/mount.h.in
+++ b/shlibs/mount/src/mount.h.in
@@ -101,15 +101,6 @@ typedef struct _mnt_update mnt_update;
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
*/
enum {
@@ -243,6 +234,8 @@ extern int mnt_fs_get_passno(mnt_fs *ent);
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);
diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h
index a277d61e..df451b77 100644
--- a/shlibs/mount/src/mountP.h
+++ b/shlibs/mount/src/mountP.h
@@ -94,6 +94,8 @@ mnt_debug_h(void *handler, const char *mesg, ...)
/* 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;
@@ -148,6 +150,7 @@ struct _mnt_iter {
/*
* 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;
@@ -156,7 +159,9 @@ struct _mnt_fs {
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 */
@@ -198,6 +203,19 @@ struct _mnt_tab {
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
diff --git a/shlibs/mount/src/tab_parse.c b/shlibs/mount/src/tab_parse.c
index 21f64336..c69a064f 100644
--- a/shlibs/mount/src/tab_parse.c
+++ b/shlibs/mount/src/tab_parse.c
@@ -55,7 +55,7 @@ static int next_number(char **s, int *num)
/*
* 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;
@@ -83,7 +83,7 @@ static int mnt_tab_parse_file_line(mnt_fs *fs, char *s)
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;
}
@@ -94,10 +94,14 @@ static int mnt_tab_parse_file_line(mnt_fs *fs, char *s)
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;
@@ -158,23 +162,84 @@ static int mnt_parse_mountinfo_line(mnt_fs *fs, char *s)
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;
}
@@ -273,36 +338,39 @@ static int mnt_tab_parse_next(mnt_tab *tb, FILE *f, mnt_fs *fs,
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().
@@ -447,6 +515,27 @@ static int mnt_tab_parse_dir(mnt_tab *tb, const char *dirname)
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:
@@ -461,18 +550,7 @@ static int mnt_tab_parse_dir(mnt_tab *tb, const char *dirname)
*/
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);
}
/**
@@ -550,6 +628,8 @@ int mnt_tab_parse_fstab(mnt_tab *tb, const char *filename)
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);
@@ -588,9 +668,11 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
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)
@@ -608,8 +690,14 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
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;
}
@@ -644,17 +732,20 @@ int mnt_tab_parse_mtab(mnt_tab *tb, const char *filename)
* 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;
diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c
index f9d4e5f0..7a39c1b0 100644
--- a/shlibs/mount/src/tab_update.c
+++ b/shlibs/mount/src/tab_update.c
@@ -35,7 +35,7 @@ struct _mnt_update {
};
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:
@@ -212,7 +212,7 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
u = NULL;
if (!(mountflags & MS_REMOUNT)) {
- rc = get_fs_root(fs, mountflags, &(*ent)->root);
+ rc = set_fs_root(*ent, mountflags);
if (rc)
goto err;
}
@@ -225,7 +225,7 @@ 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;
@@ -233,7 +233,6 @@ static int get_fs_root(mnt_fs *fs, unsigned long mountflags, char **result)
int rc = -ENOMEM;
assert(fs);
- assert(result);
DBG(UPDATE, mnt_debug("setting FS root"));
@@ -248,15 +247,19 @@ static int get_fs_root(mnt_fs *fs, unsigned long mountflags, char **result)
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);
@@ -265,7 +268,9 @@ static int get_fs_root(mnt_fs *fs, unsigned long mountflags, char **result)
/* 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));
@@ -294,7 +299,6 @@ static int get_fs_root(mnt_fs *fs, unsigned long mountflags, char **result)
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;
@@ -317,7 +321,10 @@ dflt:
if (!root)
goto err;
}
- *result = root;
+ fs->root = root;
+
+ DBG(UPDATE, mnt_debug("FS root result: %s", root));
+
free(mnt);
return 0;
err:
@@ -358,44 +365,43 @@ static int fprintf_mtab_fs(FILE *f, mnt_fs *fs)
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)
@@ -515,7 +521,7 @@ static int update_add_entry(mnt_update *upd, const char *filename, mnt_lock *lc)
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);
@@ -527,7 +533,8 @@ static int update_remove_entry(mnt_update *upd, const char *filename, mnt_lock *
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) {
@@ -547,7 +554,7 @@ static int update_remove_entry(mnt_update *upd, const char *filename, mnt_lock *
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));
@@ -556,7 +563,8 @@ static int update_modify_target(mnt_update *upd, const char *filename, mnt_lock
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) {
@@ -576,7 +584,7 @@ static int update_modify_target(mnt_update *upd, const char *filename, mnt_lock
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);
@@ -588,7 +596,8 @@ static int update_modify_options(mnt_update *upd, const char *filename, mnt_lock
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),
diff --git a/shlibs/mount/src/utils.c b/shlibs/mount/src/utils.c
index 468b0bb3..2f62313c 100644
--- a/shlibs/mount/src/utils.c
+++ b/shlibs/mount/src/utils.c
@@ -124,7 +124,7 @@ char *mnt_mangle(const char *str)
*/
char *mnt_unmangle(const char *str)
{
- return unmangle(str);
+ return unmangle(str, NULL);
}
/**