From dd36965211907fd482db8966938334ede5ece089 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 25 Nov 2010 23:22:53 +0100 Subject: [PATCH] libmount: use better format for utab, improve bind mounts Signed-off-by: Karel Zak --- include/mangle.h | 2 +- lib/mangle.c | 13 ++- mount/mount_mntent.c | 12 +-- mount/swapon.c | 4 +- shlibs/mount/src/context_mount.c | 2 +- shlibs/mount/src/context_umount.c | 11 ++ shlibs/mount/src/fs.c | 60 +++++++++-- shlibs/mount/src/mount.h.in | 11 +- shlibs/mount/src/mountP.h | 20 +++- shlibs/mount/src/tab_parse.c | 169 +++++++++++++++++++++++------- shlibs/mount/src/tab_update.c | 101 ++++++++++-------- shlibs/mount/src/utils.c | 2 +- 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); @@ -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; } 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 @@ -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); 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: " ... " + * 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: " ... " */ -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); } /** -- 2.39.5