diff options
author | Karel Zak | 2011-06-02 13:25:19 +0200 |
---|---|---|
committer | Karel Zak | 2011-06-02 13:25:19 +0200 |
commit | c4c6635582fb7ae9f68a58492e4bfb1f382ddd06 (patch) | |
tree | 109d8cae6e4da274c59534038e37968ecc429af3 /shlibs/mount/src | |
parent | docs: colcrt manual update (diff) | |
download | kernel-qcow2-util-linux-c4c6635582fb7ae9f68a58492e4bfb1f382ddd06.tar.gz kernel-qcow2-util-linux-c4c6635582fb7ae9f68a58492e4bfb1f382ddd06.tar.xz kernel-qcow2-util-linux-c4c6635582fb7ae9f68a58492e4bfb1f382ddd06.zip |
libmount: use mnt_table_get_fs_root() in utab code
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/mount/src')
-rw-r--r-- | shlibs/mount/src/fs.c | 2 | ||||
-rw-r--r-- | shlibs/mount/src/mountP.h | 6 | ||||
-rw-r--r-- | shlibs/mount/src/tab.c | 5 | ||||
-rw-r--r-- | shlibs/mount/src/tab_update.c | 159 |
4 files changed, 57 insertions, 115 deletions
diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c index 21b7ab95d..02f401d95 100644 --- a/shlibs/mount/src/fs.c +++ b/shlibs/mount/src/fs.c @@ -165,6 +165,8 @@ struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, goto err; if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, attrs))) goto err; + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, bindsrc))) + goto err; dest->freq = src->freq; dest->passno = src->passno; diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index ad271d08f..0a8c7522c 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -131,6 +131,12 @@ extern const char *mnt_get_utab_path(void); extern int mnt_get_filesystems(char ***filesystems, const char *pattern); extern void mnt_free_filesystems(char **filesystems); +/* tab.c */ +extern struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb, + struct libmnt_fs *fs, + unsigned long mountflags, + char **fsroot); + /* * Generic iterator */ diff --git a/shlibs/mount/src/tab.c b/shlibs/mount/src/tab.c index 38a5d5b12..227c5aa43 100644 --- a/shlibs/mount/src/tab.c +++ b/shlibs/mount/src/tab.c @@ -733,7 +733,6 @@ struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb, const char *fstype; struct libmnt_fs *src_fs = NULL; - assert(tb); assert(fs); assert(fsroot); @@ -741,7 +740,7 @@ struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb, fstype = mnt_fs_get_fstype(fs); - if (mountflags & MS_BIND) { + if (tb && (mountflags & MS_BIND)) { const char *src, *src_root; DBG(TAB, mnt_debug("fs-root for bind")); @@ -828,7 +827,7 @@ err: * @fstab_fs: /etc/fstab entry * * Checks if the @fstab_fs entry is already in the @tb table. The "swap" - * is ignored. + * is ignored. * * TODO: check for loopdev (see mount/mount.c is_fstab_entry_mounted(). * diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c index 9817f202b..88125bfbb 100644 --- a/shlibs/mount/src/tab_update.c +++ b/shlibs/mount/src/tab_update.c @@ -41,10 +41,12 @@ struct libmnt_update { unsigned long mountflags; int userspace_only; int ready; + + struct libmnt_table *mountinfo; }; -static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct libmnt_fs **ent); -static int set_fs_root(struct libmnt_fs *result, struct libmnt_fs *fs, unsigned long mountflags); +static int set_fs_root(struct libmnt_update *upd, struct libmnt_fs *fs, unsigned long mountflags); +static int utab_new_entry(struct libmnt_update *upd, struct libmnt_fs *fs, unsigned long mountflags); /** * mnt_new_update: @@ -77,6 +79,7 @@ void mnt_free_update(struct libmnt_update *upd) DBG(UPDATE, mnt_debug_h(upd, "free")); mnt_free_fs(upd->fs); + mnt_free_table(upd->mountinfo); free(upd->target); free(upd->filename); free(upd); @@ -205,7 +208,7 @@ int mnt_update_set_fs(struct libmnt_update *upd, unsigned long mountflags, } else if (fs) { if (upd->userspace_only && !(mountflags & MS_MOVE)) { - int rc = utab_new_entry(fs, mountflags, &upd->fs); + int rc = utab_new_entry(upd, fs, mountflags); if (rc) return rc; } else { @@ -285,30 +288,29 @@ int mnt_update_force_rdonly(struct libmnt_update *upd, int rdonly) } /* - * Allocates (but does not write) utab entry for mount/remount. This function - * should be called *before* mount(2) syscall. + * Allocates utab entry (upd->fs) for mount/remount. This function should be + * called *before* mount(2) syscall. The @fs is used as a read-only template. * * Returns: 0 on success, negative number on error, 1 if utabs update is * unnecessary. */ -static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct libmnt_fs **ent) +static int utab_new_entry(struct libmnt_update *upd, struct libmnt_fs *fs, + unsigned long mountflags) { int rc = 0; const char *o = NULL, *a = NULL; char *u = NULL; assert(fs); - assert(ent); + assert(upd); + assert(upd->fs == NULL); assert(!(mountflags & MS_MOVE)); - if (!fs || !ent) - return -EINVAL; - *ent = NULL; - DBG(UPDATE, mnt_debug("prepare utab entry")); o = mnt_fs_get_user_options(fs); a = mnt_fs_get_attributes(fs); + upd->fs = NULL; if (o) { /* remove non-mtab options */ @@ -325,21 +327,21 @@ static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct } /* allocate the entry */ - *ent = mnt_copy_fs(NULL, fs); - if (!*ent) { + upd->fs = mnt_copy_fs(NULL, fs); + if (!upd->fs) { rc = -ENOMEM; goto err; } - rc = mnt_fs_set_options(*ent, u); + rc = mnt_fs_set_options(upd->fs, u); if (rc) goto err; - rc = mnt_fs_set_attributes(*ent, a); + rc = mnt_fs_set_attributes(upd->fs, a); if (rc) goto err; if (!(mountflags & MS_REMOUNT)) { - rc = set_fs_root(*ent, fs, mountflags); + rc = set_fs_root(upd, fs, mountflags); if (rc) goto err; } @@ -348,125 +350,58 @@ static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct DBG(UPDATE, mnt_debug("utab entry OK")); return 0; err: - mnt_free_fs(*ent); free(u); - *ent = NULL; + mnt_free_fs(upd->fs); + upd->fs = NULL; return rc; } -static int set_fs_root(struct libmnt_fs *result, struct libmnt_fs *fs, unsigned long mountflags) +/* + * Sets fs-root and fs-type to @upd->fs according to the @fs template and + * @mountfalgs. For MS_BIND mountflag it reads information about source + * filesystem from /proc/self/mountinfo. + */ +static int set_fs_root(struct libmnt_update *upd, struct libmnt_fs *fs, + unsigned long mountflags) { - char *root = NULL, *mnt = NULL; - const char *fstype; - struct libmnt_table *tb = NULL; - int rc = -ENOMEM; - - assert(fs); - assert(result); + struct libmnt_fs *src_fs; + char *fsroot = NULL; + const char *src; + int rc = 0; DBG(UPDATE, mnt_debug("setting FS root")); - fstype = mnt_fs_get_fstype(fs); + assert(upd); + assert(upd->fs); + assert(fs); - /* - * bind-mount -- get fs-root and source device for the source filesystem - */ if (mountflags & MS_BIND) { - const char *src, *src_root; - struct libmnt_fs *src_fs; - - DBG(UPDATE, mnt_debug("setting FS root: bind")); + if (!upd->mountinfo) + upd->mountinfo = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO); src = mnt_fs_get_srcpath(fs); if (src) { - rc = mnt_fs_set_bindsrc(result, 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_table_from_file(_PATH_PROC_MOUNTINFO, MNT_FMT_MOUNTINFO); - if (!tb) { - DBG(UPDATE, mnt_debug("failed to parse mountinfo -- using default")); - goto dflt; - } - src_fs = mnt_table_find_target(tb, mnt, MNT_ITER_BACKWARD); - if (!src_fs) { - DBG(UPDATE, mnt_debug("not found '%s' in mountinfo -- using default", mnt)); - goto dflt; + rc = mnt_fs_set_bindsrc(upd->fs, src); + if (rc) + goto err; } + } - /* set device name and fs */ + src_fs = mnt_table_get_fs_root(upd->mountinfo, fs, + mountflags, &fsroot); + if (src_fs) { src = mnt_fs_get_srcpath(src_fs); - rc = mnt_fs_set_source(result, src); + rc = mnt_fs_set_source(upd->fs, src); if (rc) goto err; - mnt_fs_set_fstype(result, mnt_fs_get_fstype(src_fs)); - - /* on btrfs the subvolume is used as fs-root in - * /proc/self/mountinfo, so we have to get the original subvolume - * name from src_fs and prepend the subvolume name to the - * fs-root path - */ - src_root = mnt_fs_get_root(src_fs); - if (src_root && !startswith(root, src_root)) { - size_t sz = strlen(root) + strlen(src_root) + 1; - char *tmp = malloc(sz); - - if (!tmp) - goto err; - snprintf(tmp, sz, "%s%s", src_root, root); - free(root); - root = tmp; - } - } - - /* - * btrfs-subvolume mount -- get subvolume name and use it as a root-fs path - */ - else if (fstype && !strcmp(fstype, "btrfs")) { - char *vol = NULL, *p; - size_t sz, volsz = 0; - - if (mnt_fs_get_option(fs, "subvol", &vol, &volsz)) - goto dflt; - - DBG(UPDATE, mnt_debug("setting FS root: btrfs subvol")); - - sz = volsz; - if (*vol != '/') - sz++; - root = malloc(sz + 1); - if (!root) - goto err; - p = root; - if (*vol != '/') - *p++ = '/'; - memcpy(p, vol, volsz); - *(root + sz) = '\0'; + mnt_fs_set_fstype(upd->fs, mnt_fs_get_fstype(src_fs)); } -dflt: - mnt_free_table(tb); - if (!root) { - root = strdup("/"); - if (!root) - goto err; - } - result->root = root; - - DBG(UPDATE, mnt_debug("FS root result: %s", root)); - free(mnt); + upd->fs->root = fsroot; return 0; err: - free(root); - free(mnt); + free(fsroot); return rc; } |