diff options
-rw-r--r-- | shlibs/mount/src/context_umount.c | 27 | ||||
-rw-r--r-- | shlibs/mount/src/fs.c | 112 | ||||
-rw-r--r-- | shlibs/mount/src/libmount.h.in | 6 | ||||
-rw-r--r-- | shlibs/mount/src/libmount.sym | 4 | ||||
-rw-r--r-- | shlibs/mount/src/mountP.h | 6 | ||||
-rw-r--r-- | shlibs/mount/src/tab.c | 4 | ||||
-rw-r--r-- | shlibs/mount/src/tab_parse.c | 16 | ||||
-rw-r--r-- | shlibs/mount/src/tab_update.c | 2 |
8 files changed, 123 insertions, 54 deletions
diff --git a/shlibs/mount/src/context_umount.c b/shlibs/mount/src/context_umount.c index 122ef7f84..bd9be6956 100644 --- a/shlibs/mount/src/context_umount.c +++ b/shlibs/mount/src/context_umount.c @@ -25,7 +25,7 @@ static int lookup_umount_fs(struct libmnt_context *cxt) { int rc; const char *tgt; - struct libmnt_table *mtab; + struct libmnt_table *mtab = NULL; struct libmnt_fs *fs; assert(cxt); @@ -69,30 +69,19 @@ static int lookup_umount_fs(struct libmnt_context *cxt) } if (!fs) { - DBG(CXT, mnt_debug_h(cxt, "cannot found %s in mtab", tgt)); + DBG(CXT, mnt_debug_h(cxt, "umount: cannot found %s in mtab", tgt)); return 0; } /* copy from mtab to our FS description */ - rc = mnt_fs_set_source(cxt->fs, mnt_fs_get_source(fs)); - if (!rc) - rc = mnt_fs_set_target(cxt->fs, mnt_fs_get_target(fs)); - - if (!rc && !mnt_fs_get_fstype(cxt->fs)) - rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs)); - - if (!rc) - rc = mnt_fs_set_vfs_options(cxt->fs, mnt_fs_get_vfs_options(fs)); - if (!rc) - rc = mnt_fs_set_fs_options(cxt->fs, mnt_fs_get_fs_options(fs)); - if (!rc) - rc = mnt_fs_set_user_options(cxt->fs, mnt_fs_get_user_options(fs)); - if (!rc) - rc = mnt_fs_set_attributes(cxt->fs, mnt_fs_get_attributes(fs)); + mnt_fs_set_source(cxt->fs, NULL); + mnt_fs_set_target(cxt->fs, NULL); - if (!rc && mnt_fs_get_bindsrc(fs)) - rc = mnt_fs_set_bindsrc(cxt->fs, mnt_fs_get_bindsrc(fs)); + if (!mnt_copy_fs(cxt->fs, fs)) { + DBG(CXT, mnt_debug_h(cxt, "umount: failed to copy FS")); + return -errno; + } DBG(CXT, mnt_debug_h(cxt, "umount: mtab applied")); cxt->flags |= MNT_FL_TAB_APPLIED; diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c index 1477812f6..c2deff5f1 100644 --- a/shlibs/mount/src/fs.c +++ b/shlibs/mount/src/fs.c @@ -33,6 +33,7 @@ struct libmnt_fs *mnt_new_fs(void) if (!fs) return NULL; + /*DBG(FS, mnt_debug_h(fs, "alloc"));*/ INIT_LIST_HEAD(&fs->ents); return fs; } @@ -49,6 +50,8 @@ void mnt_free_fs(struct libmnt_fs *fs) return; list_del(&fs->ents); + /*DBG(FS, mnt_debug_h(fs, "free"));*/ + free(fs->source); free(fs->bindsrc); free(fs->tagname); @@ -64,7 +67,19 @@ void mnt_free_fs(struct libmnt_fs *fs) free(fs); } -static inline int cpy_str(char **dest, const char *src) +/** + * mnt_reset_fs: + * @fs: fs pointer + * + * Resets (zeroize) @fs. + */ +void mnt_reset_fs(struct libmnt_fs *fs) +{ + if (fs) + memset(fs, 0, sizeof(*fs)); +} + +static inline int update_str(char **dest, const char *src) { size_t sz; char *x; @@ -91,57 +106,71 @@ static inline int cpy_str_at_offset(void *new, const void *old, size_t offset) char **o = (char **) (old + offset); char **n = (char **) (new + offset); - return cpy_str(n, *o); + if (*n) + return 0; /* already set, not overwrite */ + + return update_str(n, *o); } /** * mnt_copy_fs: - * @fs: source FS + * @dest: destination FS + * @src: source FS + * + * If @dest is NULL, then a new FS is allocated, if any @dest field is already + * set then the field is NOT overwrited. * * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is * not linked with any existing mnt_tab. * - * Returns: copy of @fs + * Returns: @dest or NULL in case of error */ -struct libmnt_fs *mnt_copy_fs(const struct libmnt_fs *fs) +struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, + const struct libmnt_fs *src) { - struct libmnt_fs *n = mnt_new_fs(); + const struct libmnt_fs *org = dest; - if (!n) - return NULL; + if (!dest) { + dest = mnt_new_fs(); + if (!dest) + return NULL; + } - n->id = fs->id; - n->parent = fs->parent; - n->devno = fs->devno; + /*DBG(FS, mnt_debug_h(dest, "copy from %p", src));*/ - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, source))) + dest->id = src->id; + dest->parent = src->parent; + dest->devno = src->devno; + + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, source))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, tagname))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, tagname))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, tagval))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, tagval))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, root))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, root))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, target))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, target))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, fstype))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fstype))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, vfs_optstr))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, vfs_optstr))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, fs_optstr))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fs_optstr))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, user_optstr))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, user_optstr))) goto err; - if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, attrs))) + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, attrs))) goto err; - n->freq = fs->freq; - n->passno = fs->passno; - n->flags = fs->flags; + dest->freq = src->freq; + dest->passno = src->passno; + dest->flags = src->flags; - return n; + return dest; err: - mnt_free_fs(n); + if (!org) + mnt_free_fs(dest); return NULL; } @@ -400,6 +429,31 @@ int mnt_fs_set_target(struct libmnt_fs *fs, const char *target) return 0; } +int __mnt_fs_get_flags(struct libmnt_fs *fs) +{ + return fs ? fs->flags : 0; +} + +int __mnt_fs_set_flags(struct libmnt_fs *fs, int flags) +{ + if (fs) { + fs->flags = flags; + return 0; + } + return -EINVAL; +} + +/** + * mnt_fs_is_kernel: + * @fs: filesystem + * + * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts. + */ +int mnt_fs_is_kernel(struct libmnt_fs *fs) +{ + return __mnt_fs_get_flags(fs) & MNT_FS_KERNEL; +} + /** * mnt_fs_get_fstype: * @fs: fstab/mtab/mountinfo entry pointer @@ -1400,11 +1454,11 @@ int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt) return -ENOMEM; } - if ((rc = cpy_str(&m->mnt_fsname, mnt_fs_get_source(fs)))) + if ((rc = update_str(&m->mnt_fsname, mnt_fs_get_source(fs)))) goto err; - if ((rc = cpy_str(&m->mnt_dir, mnt_fs_get_target(fs)))) + if ((rc = update_str(&m->mnt_dir, mnt_fs_get_target(fs)))) goto err; - if ((rc = cpy_str(&m->mnt_type, mnt_fs_get_fstype(fs)))) + if ((rc = update_str(&m->mnt_type, mnt_fs_get_fstype(fs)))) goto err; errno = 0; diff --git a/shlibs/mount/src/libmount.h.in b/shlibs/mount/src/libmount.h.in index aa00b938d..1831ed18a 100644 --- a/shlibs/mount/src/libmount.h.in +++ b/shlibs/mount/src/libmount.h.in @@ -199,7 +199,9 @@ extern int mnt_lock_file(struct libmnt_lock *ml); /* fs.c */ extern struct libmnt_fs *mnt_new_fs(void); extern void mnt_free_fs(struct libmnt_fs *fs); -extern struct libmnt_fs *mnt_copy_fs(const struct libmnt_fs *fs); +extern void mnt_reset_fs(struct libmnt_fs *fs); +extern struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, + const struct libmnt_fs *src); extern void *mnt_fs_get_userdata(struct libmnt_fs *fs); extern int mnt_fs_set_userdata(struct libmnt_fs *fs, void *data); extern const char *mnt_fs_get_source(struct libmnt_fs *fs); @@ -263,6 +265,8 @@ extern int mnt_fs_match_fstype(struct libmnt_fs *fs, const char *types); extern int mnt_fs_match_options(struct libmnt_fs *fs, const char *options); extern int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file); +extern int mnt_fs_is_kernel(struct libmnt_fs *fs); + extern void mnt_free_mntent(struct mntent *mnt); extern int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt); diff --git a/shlibs/mount/src/libmount.sym b/shlibs/mount/src/libmount.sym index 2481b4931..d0ebfd728 100644 --- a/shlibs/mount/src/libmount.sym +++ b/shlibs/mount/src/libmount.sym @@ -36,6 +36,7 @@ global: mnt_context_get_status; mnt_context_get_target; mnt_context_get_user_mflags; + mnt_context_helper_setopt; mnt_context_init_helper; mnt_context_is_fake; mnt_context_is_force; @@ -46,7 +47,6 @@ global: mnt_context_is_sloppy; mnt_context_is_verbose; mnt_context_mount; - mnt_context_helper_setopt; mnt_context_prepare_mount; mnt_context_prepare_umount; mnt_context_set_cache; @@ -98,6 +98,7 @@ global: mnt_fs_get_userdata; mnt_fs_get_user_options; mnt_fs_get_vfs_options; + mnt_fs_is_kernel; mnt_fs_match_fstype; mnt_fs_match_options; mnt_fs_match_source; @@ -157,6 +158,7 @@ global: mnt_optstr_set_option; mnt_parse_version_string; mnt_reset_context; + mnt_reset_fs; mnt_reset_iter; mnt_resolve_path; mnt_resolve_spec; diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index a38aa10e4..aeceb7f96 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -193,6 +193,12 @@ struct libmnt_fs { #define MNT_FS_PSEUDO (1 << 1) /* pseudo filesystem */ #define MNT_FS_NET (1 << 2) /* network filesystem */ #define MNT_FS_SWAP (1 << 3) /* swap device */ +#define MNT_FS_KERNEL (1 << 4) /* data from /proc/{mounts,self/mountinfo} */ +#define MNT_FS_MERGED (1 << 5) /* already merged data from /dev/.mount/utab */ + +extern int __mnt_fs_get_flags(struct libmnt_fs *fs); +extern int __mnt_fs_set_flags(struct libmnt_fs *fs, int flags); + /* * mtab/fstab/mountinfo file diff --git a/shlibs/mount/src/tab.c b/shlibs/mount/src/tab.c index ab4117683..2d2e72fd1 100644 --- a/shlibs/mount/src/tab.c +++ b/shlibs/mount/src/tab.c @@ -424,7 +424,7 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat if (!tb || !path) return NULL; - DBG(TAB, mnt_debug_h(tb, "lookup target: %s", path)); + DBG(TAB, mnt_debug_h(tb, "lookup TARGET: %s", path)); /* native @target */ mnt_reset_iter(&itr, direction); @@ -733,7 +733,7 @@ int test_copy_fs(struct libmnt_test *ts, int argc, char *argv[]) printf("ORIGINAL:\n"); mnt_fs_print_debug(fs, stdout); - fs = mnt_copy_fs(fs); + fs = mnt_copy_fs(NULL, fs); if (!fs) goto done; diff --git a/shlibs/mount/src/tab_parse.c b/shlibs/mount/src/tab_parse.c index 42b108ff8..4eb32eb63 100644 --- a/shlibs/mount/src/tab_parse.c +++ b/shlibs/mount/src/tab_parse.c @@ -140,6 +140,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, char *s) &fs->fs_optstr); if (rc == 10) { + fs->flags |= MNT_FS_KERNEL; fs->devno = makedev(maj, min); unmangle_string(fs->root); @@ -335,6 +336,7 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam { int nlines = 0; int rc = -1; + int flags = 0; assert(tb); assert(f); @@ -342,6 +344,12 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam DBG(TAB, mnt_debug_h(tb, "%s: start parsing", filename)); + /* necessary for /proc/mounts only, the /proc/self/mountinfo + * parser sets propertly the flag + */ + if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0) + flags = MNT_FS_KERNEL; + while (!feof(f)) { struct libmnt_fs *fs = mnt_new_fs(); @@ -349,8 +357,10 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam goto err; rc = mnt_table_parse_next(tb, f, fs, filename, &nlines); - if (!rc) + if (!rc) { rc = mnt_table_add_fs(tb, fs); + fs->flags |= flags; + } if (rc) { mnt_free_fs(fs); if (rc == 1) @@ -631,6 +641,9 @@ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct *t = mnt_fs_get_target(fs), *r = mnt_fs_get_root(fs); + if (fs->flags & MNT_FS_MERGED) + continue; + if (s && t && r && !strcmp(t, target) && !strcmp(s, src) && !strcmp(r, root)) break; @@ -641,6 +654,7 @@ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct mnt_fs_append_user_options(fs, optstr); mnt_fs_append_attributes(fs, attrs); mnt_fs_set_bindsrc(fs, mnt_fs_get_bindsrc(uf)); + fs->flags |= MNT_FS_MERGED; DBG(TAB, mnt_debug_h(tb, "found fs:")); DBG(TAB, mnt_fs_print_debug(fs, stderr)); diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c index 60a628a4a..d66b64f94 100644 --- a/shlibs/mount/src/tab_update.c +++ b/shlibs/mount/src/tab_update.c @@ -324,7 +324,7 @@ static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct } /* allocate the entry */ - *ent = mnt_copy_fs(fs); + *ent = mnt_copy_fs(NULL, fs); if (!*ent) { rc = -ENOMEM; goto err; |