]> err.no Git - util-linux/commitdiff
libmount: use better format for utab, improve bind mounts
authorKarel Zak <kzak@redhat.com>
Thu, 25 Nov 2010 22:22:53 +0000 (23:22 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Jan 2011 11:28:46 +0000 (12:28 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
12 files changed:
include/mangle.h
lib/mangle.c
mount/mount_mntent.c
mount/swapon.c
shlibs/mount/src/context_mount.c
shlibs/mount/src/context_umount.c
shlibs/mount/src/fs.c
shlibs/mount/src/mount.h.in
shlibs/mount/src/mountP.h
shlibs/mount/src/tab_parse.c
shlibs/mount/src/tab_update.c
shlibs/mount/src/utils.c

index 5dda902f7c433dfc0ee5532de6dbbdbdf2b73959..76d29bfaebc53513ccd11150710a8d36a9422652 100644 (file)
@@ -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)
 {
index 938dd8e55e311c7b0366e91d110ff03e5a622671..398323a371a1dd44b4b1cffb19156cfd59991622 100644 (file)
@@ -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);
index 08e5bf482d39b6367089c48f71a1a2ee6426230f..9e31d12fe78b72dffe3b22c4ccb24cfc67ae65ac 100644 (file)
@@ -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)) {
index f0577bbb8387f3f4d2ec39a7c1959efcd8ddbee6..e9ccc94a3ae977fa939ee79f6bf8fbd9171f77b1 100644 (file)
@@ -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);
index 960126d688bba819ae734f91117a55f2f6ffe8ee..cb681e0dd4b7b03ae6ea08476b51889f0187a59e 100644 (file)
@@ -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;
                }
index 00bad1091270c07e921a4db84909732614fd48a9..7cb4a2a44c148577a47b207951f8fe34e3d9ab0c 100644 (file)
@@ -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
index 140bdb19a29b9e519e7985064d5f98966848ef04..a11061d91a220a1d4e0de3a49cb42c9e8cc98c5c 100644 (file)
@@ -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);
@@ -653,6 +654,42 @@ int mnt_fs_set_root(mnt_fs *fs, const char *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
@@ -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;
 }
index 1123171941127c99228547f2451322bd4b22cd7f..03753f785f19ec1d62af322bf353698ac5e5f484 100644 (file)
@@ -100,15 +100,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
  */
@@ -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);
index a277d61eb5d227192ae757559a113dd85cd0f943..df451b771ded02bd3603a84d6996bfaca5a030dc 100644 (file)
@@ -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
index 21f64336c667e5be707e1f5d7ec700573f80d97d..c69a064fff46619987151f48485bf31be8f724e7 100644 (file)
@@ -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;
index f9d4e5f0699735742f12d6115c4d76366fc9fec2..7a39c1b06f6f19a3ca7d74388f2e323ffdd39245 100644 (file)
@@ -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),
index 468b0bb3dce9756327c50168ed20dcb33897c0ac..2f62313c542f901e8e69d5816baaab9abcce05a5 100644 (file)
@@ -124,7 +124,7 @@ char *mnt_mangle(const char *str)
  */
 char *mnt_unmangle(const char *str)
 {
-       return unmangle(str);
+       return unmangle(str, NULL);
 }
 
 /**