/* * This function uses @uf to found corresponding record in @tb, then the record * from @tb is updated (user specific mount options are added). * * Note that @uf must contain only user specific mount options instead of * VFS options (note that FS options are ignored). * * Returns modified filesystem (from @tb) or NULL. */ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct libmnt_fs *uf) { struct libmnt_fs *fs; struct libmnt_iter itr; const char *optstr, *src, *target, *root, *attrs; assert(tb); assert(uf); if (!tb || !uf) return NULL; DBG(TAB, mnt_debug_h(tb, "merging user fs")); src = mnt_fs_get_srcpath(uf); target = mnt_fs_get_target(uf); optstr = mnt_fs_get_user_options(uf); attrs = mnt_fs_get_attributes(uf); root = mnt_fs_get_root(uf); if (!src || !target || !root || (!attrs && !optstr)) return NULL; mnt_reset_iter(&itr, MNT_ITER_BACKWARD); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { const char *s = mnt_fs_get_srcpath(fs), *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; } if (fs) { DBG(TAB, mnt_debug_h(tb, "found fs -- appending user optstr")); mnt_fs_append_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)); } return fs; }
/* * 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) { struct libmnt_fs *src_fs; char *fsroot = NULL; const char *src; int rc = 0; DBG(UPDATE, mnt_debug("setting FS root")); assert(upd); assert(upd->fs); assert(fs); if (mountflags & MS_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(upd->fs, src); if (rc) goto err; } } 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(upd->fs, src); if (rc) goto err; mnt_fs_set_fstype(upd->fs, mnt_fs_get_fstype(src_fs)); } upd->fs->root = fsroot; return 0; err: free(fsroot); return rc; }