diff options
author | Karel Zak | 2011-06-23 15:07:55 +0200 |
---|---|---|
committer | Karel Zak | 2011-06-23 15:07:55 +0200 |
commit | 9f7472b0b84f3238abe19fcbf5a2fb864fd2e71d (patch) | |
tree | 14321ff72c2f77a112936a2d95ac6956f0184c50 /libmount/src | |
parent | libmount: fix fstype caching (diff) | |
download | kernel-qcow2-util-linux-9f7472b0b84f3238abe19fcbf5a2fb864fd2e71d.tar.gz kernel-qcow2-util-linux-9f7472b0b84f3238abe19fcbf5a2fb864fd2e71d.tar.xz kernel-qcow2-util-linux-9f7472b0b84f3238abe19fcbf5a2fb864fd2e71d.zip |
libmount: add support for mount -a
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src')
-rw-r--r-- | libmount/src/context.c | 96 | ||||
-rw-r--r-- | libmount/src/context_mount.c | 117 | ||||
-rw-r--r-- | libmount/src/libmount.h.in | 8 | ||||
-rw-r--r-- | libmount/src/libmount.sym | 14 | ||||
-rw-r--r-- | libmount/src/optstr.c | 6 |
5 files changed, 221 insertions, 20 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c index 681b0575b..ff199ea2e 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -66,7 +66,7 @@ struct libmnt_context *mnt_new_context(void) /* if we're really root and aren't running setuid */ cxt->restricted = (uid_t) 0 == ruid && ruid == euid ? 0 : 1; - DBG(CXT, mnt_debug_h(cxt, "allocate %s", + DBG(CXT, mnt_debug_h(cxt, "----> allocate %s", cxt->restricted ? "[RESTRICTED]" : "")); mnt_has_regular_mtab(&cxt->mtab_path, &cxt->mtab_writable); @@ -103,7 +103,7 @@ void mnt_free_context(struct libmnt_context *cxt) mnt_free_lock(cxt->lock); mnt_free_update(cxt->update); - DBG(CXT, mnt_debug_h(cxt, "free")); + DBG(CXT, mnt_debug_h(cxt, "<---- free")); free(cxt); } @@ -134,10 +134,8 @@ int mnt_reset_context(struct libmnt_context *cxt) if (!cxt) return -EINVAL; - DBG(CXT, mnt_debug_h(cxt, - "reset [status=%d %s]", - mnt_context_get_status(cxt), - mnt_context_get_status(cxt) == 0 ? "FAILED" : "SUCCESS")); + DBG(CXT, mnt_debug_h(cxt, "<---- reset [status=%d] ---->", + mnt_context_get_status(cxt))); fl = cxt->flags; @@ -165,7 +163,16 @@ int mnt_reset_context(struct libmnt_context *cxt) /* restore non-resetable flags */ cxt->flags |= (fl & MNT_FL_EXTERN_FSTAB); cxt->flags |= (fl & MNT_FL_EXTERN_CACHE); - + cxt->flags |= (fl & MNT_FL_NOMTAB); + cxt->flags |= (fl & MNT_FL_FAKE); + cxt->flags |= (fl & MNT_FL_SLOPPY); + cxt->flags |= (fl & MNT_FL_VERBOSE); + cxt->flags |= (fl & MNT_FL_NOHELPERS); + cxt->flags |= (fl & MNT_FL_LOOPDEL); + cxt->flags |= (fl & MNT_FL_LAZY); + cxt->flags |= (fl & MNT_FL_FORCE); + cxt->flags |= (fl & MNT_FL_NOCANONICALIZE); + cxt->flags |= (fl & MNT_FL_RDONLY_UMOUNT); return 0; } @@ -1556,7 +1563,7 @@ int mnt_context_get_status(struct libmnt_context *cxt) /** * mnt_context_set_syscall_status: * @cxt: mount context - * @status: mount(2) return code + * @status: mount(2) status * * The @status should be 0 on succcess, or negative number on error (-1 or * -errno). @@ -1645,6 +1652,30 @@ int mnt_context_helper_setopt(struct libmnt_context *cxt, int c, char *arg) return -EINVAL; } +/** + * @cxt: context + * @fs; filesystem + * @mounted: returns 1 for mounted and 0 for non-mounted filesystems + * + * Returns: 0 on success and negative number in case of error. + */ +int mnt_context_is_fs_mounted(struct libmnt_context *cxt, + struct libmnt_fs *fs, int *mounted) +{ + struct libmnt_table *mtab; + int rc; + + if (!cxt || !fs || !mounted) + return -EINVAL; + + rc = mnt_context_get_mtab(cxt, &mtab); + if (rc) + return rc; + + *mounted = mnt_table_is_fs_mounted(mtab, fs); + return 0; +} + #ifdef TEST_PROGRAM struct libmnt_lock *lock; @@ -1796,15 +1827,62 @@ int test_flags(struct libmnt_test *ts, int argc, char *argv[]) return rc; } +int test_mountall(struct libmnt_test *ts, int argc, char *argv[]) +{ + struct libmnt_context *cxt; + struct libmnt_iter *itr; + struct libmnt_fs *fs; + int mntrc, ignored, idx = 1; + + cxt = mnt_new_context(); + itr = mnt_new_iter(MNT_ITER_FORWARD); + + if (!cxt || !itr) + return -ENOMEM; + + if (argc > 2) { + if (!strcmp(argv[idx], "-O")) { + mnt_context_set_options_pattern(cxt, argv[idx + 1]); + idx += 2; + } + if (!strcmp(argv[idx], "-t")) { + mnt_context_set_fstype_pattern(cxt, argv[idx + 1]); + idx += 2; + } + } + + while (mnt_context_next_mount(cxt, itr, &fs, &mntrc, &ignored) == 0) { + + const char *tgt = mnt_fs_get_target(fs); + + if (ignored == 1) + printf("%s: ignored: not match\n", tgt); + else if (ignored == 2) + printf("%s: ignored: already mounted\n", tgt); + + else if (!mnt_context_get_status(cxt)) { + if (mntrc > 0) { + errno = mntrc; + warn("%s: mount failed", tgt); + } else + warnx("%s: mount failed", tgt); + } else + printf("%s: successfully mounted\n", tgt); + } + + mnt_free_context(cxt); + return 0; +} + int main(int argc, char *argv[]) { struct libmnt_test tss[] = { { "--mount", test_mount, "[-o <opts>] [-t <type>] <spec>|<src> <target>" }, { "--umount", test_umount, "[-t <type>] [-f][-l][-r] <src>|<target>" }, + { "--mount-all", test_mountall, "[-O <pattern>] [-t <pattern] mount all filesystems from fstab" }, { "--flags", test_flags, "[-o <opts>] <spec>" }, { NULL }}; - umask(S_IWGRP|S_IWOTH); /* to be compatible with mount(8) */ return mnt_run_test(tss, argc, argv); diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 58c3ec10e..53bb3a735 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -359,6 +359,10 @@ static int exec_helper(struct libmnt_context *cxt) /* * The default is to use fstype from cxt->fs, this could be overwritten by * @try_type argument. + * + * Returns: 0 on success, + * >0 in case of mount(2) error (returns syscall errno), + * <0 in case of other errors. */ static int do_mount(struct libmnt_context *cxt, const char *try_type) { @@ -608,7 +612,7 @@ int mnt_context_finalize_mount(struct libmnt_context *cxt) * mount.type helper wasn't sucessfully called. * * Check mnt_context_get_status() after error! -* + * * Returns: 0 on success; * >0 in case of mount(2) error (returns syscall errno), * <0 in case of other errors. @@ -637,3 +641,114 @@ int mnt_context_mount(struct libmnt_context *cxt) return rc; } +/** + * mnt_context_next_mount: + * @cxt: context + * @itr: iterator + * @fs: returns the current filesystem + * @mntrc: returns the return code from mnt_mount_context() + * @ignored: returns 1 for not matching and 2 for already mounted filesystems + * + * This function tries to mount the next filesystem from fstab (as returned by + * mnt_context_get_fstab()). See also mnt_context_set_fstab(). + * + * You can filter out filesystems by: + * mnt_context_set_options_pattern() to simulate mount -a -O <pattern> + * mnt_context_set_fstype_pattern() to simulate mount -a -t <pattern> + * + * If the filesystem is already mounted or does not match defined criteria, + * then the mnt_context_next_mount() function returns zero, but the @ignored is + * non-zero. Note that the root filesystem and filesystems with "noauto" option + * are always ignored. + * + * If mount(2) syscall or mount.<type> helper failed, then the + * mnt_context_next_mount() function returns zero, but the @mntrc is non-zero. + * Use also mnt_context_get_status() to check if the filesystem was + * successfully mounted. + * + * Returns: 0 on success, + * <0 in case of error (!= mount(2) errors) + * 1 at the end of the list. + */ +int mnt_context_next_mount(struct libmnt_context *cxt, + struct libmnt_iter *itr, + struct libmnt_fs **fs, + int *mntrc, + int *ignored) +{ + struct libmnt_table *fstab, *mtab; + const char *o, *tgt; + int rc, mounted = 0; + + if (ignored) + *ignored = 0; + if (mntrc) + *mntrc = 0; + + if (!cxt || !fs || !itr) + return -EINVAL; + + mtab = cxt->mtab; + cxt->mtab = NULL; /* do not reset mtab */ + mnt_reset_context(cxt); + cxt->mtab = mtab; + + rc = mnt_context_get_fstab(cxt, &fstab); + if (rc) + return rc; + + rc = mnt_table_next_fs(fstab, itr, fs); + if (rc != 0) + return rc; /* more filesystems (or error) */ + + o = mnt_fs_get_user_options(*fs); + tgt = mnt_fs_get_target(*fs); + + DBG(CXT, mnt_debug_h(cxt, "next-mount: trying %s", tgt)); + + /* ignore swap */ + if (((*fs)->flags & MNT_FS_SWAP) || + + /* ignore root filesystem */ + (tgt && (strcmp(tgt, "/") == 0 || strcmp(tgt, "root") == 0)) || + + /* ignore noauto filesystems */ + (o && mnt_optstr_get_option(o, "noauto", NULL, NULL) == 0) || + + /* ignore filesystems not match with options patterns */ + (cxt->fstype_pattern && !mnt_fs_match_fstype(*fs, + cxt->fstype_pattern)) || + + /* ignore filesystems not match with type patterns */ + (cxt->optstr_pattern && !mnt_fs_match_options(*fs, + cxt->optstr_pattern))) { + if (ignored) + *ignored = 1; + DBG(CXT, mnt_debug_h(cxt, "next-mount: not-match " + "[fstype: %s, t-pattern: %s, options: %s, O-pattern: %s]", + mnt_fs_get_fstype(*fs), + cxt->fstype_pattern, + mnt_fs_get_options(*fs), + cxt->optstr_pattern)); + return 0; + } + + /* ignore already mounted filesystems */ + rc = mnt_context_is_fs_mounted(cxt, *fs, &mounted); + if (rc) + return rc; + if (mounted) { + if (ignored) + *ignored = 2; + return 0; + } + + rc = mnt_context_set_fs(cxt, *fs); + if (rc) + return rc; + rc = mnt_context_mount(cxt); + if (mntrc) + *mntrc = rc; + return 0; +} + diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index a224fb0f8..111b3a683 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -155,7 +155,7 @@ extern int mnt_optstr_append_option(char **optstr, const char *name, const char *value); extern int mnt_optstr_prepend_option(char **optstr, const char *name, const char *value); -extern int mnt_optstr_get_option(char *optstr, const char *name, +extern int mnt_optstr_get_option(const char *optstr, const char *name, char **value, size_t *valsz); extern int mnt_optstr_set_option(char **optstr, const char *name, const char *value); @@ -395,6 +395,9 @@ extern int mnt_context_is_nomtab(struct libmnt_context *cxt); extern int mnt_context_is_force(struct libmnt_context *cxt); extern int mnt_context_is_verbose(struct libmnt_context *cxt); +extern int mnt_context_is_fs_mounted(struct libmnt_context *cxt, + struct libmnt_fs *fs, int *mounted); + extern int mnt_context_set_fs(struct libmnt_context *cxt, struct libmnt_fs *fs); extern struct libmnt_fs *mnt_context_get_fs(struct libmnt_context *cxt); extern int mnt_context_set_source(struct libmnt_context *cxt, const char *source); @@ -445,6 +448,9 @@ extern int mnt_context_strerror(struct libmnt_context *cxt, char *buf, extern int mnt_context_mount(struct libmnt_context *cxt); extern int mnt_context_umount(struct libmnt_context *cxt); +extern int mnt_context_next_mount(struct libmnt_context *cxt, + struct libmnt_iter *itr, struct libmnt_fs **fs, + int *mntrc, int *ignored); extern int mnt_context_prepare_mount(struct libmnt_context *cxt); extern int mnt_context_do_mount(struct libmnt_context *cxt); diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index d8c01c018..34727a668 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -34,12 +34,14 @@ global: mnt_context_get_optsmode; mnt_context_get_source; mnt_context_get_status; + mnt_context_get_table; 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; + mnt_context_is_fs_mounted; mnt_context_is_lazy; mnt_context_is_nomtab; mnt_context_is_rdonly_umount; @@ -47,6 +49,7 @@ global: mnt_context_is_sloppy; mnt_context_is_verbose; mnt_context_mount; + mnt_context_next_mount; mnt_context_prepare_mount; mnt_context_prepare_umount; mnt_context_set_cache; @@ -61,19 +64,20 @@ global: mnt_context_set_optsmode; mnt_context_set_source; mnt_context_set_syscall_status; - mnt_context_get_table; mnt_context_set_tables_errcb; mnt_context_set_target; mnt_context_set_user_mflags; mnt_context_strerror; mnt_context_umount; mnt_copy_fs; + mnt_diff_tables; mnt_free_cache; mnt_free_context; mnt_free_fs; mnt_free_iter; mnt_free_lock; mnt_free_mntent; + mnt_free_tabdiff; mnt_free_table; mnt_free_update; mnt_fs_append_attributes; @@ -138,6 +142,7 @@ global: mnt_new_fs; mnt_new_iter; mnt_new_lock; + mnt_new_tabdiff; mnt_new_table; mnt_new_table_from_dir; mnt_new_table_from_file; @@ -160,6 +165,7 @@ global: mnt_resolve_spec; mnt_resolve_tag; mnt_split_optstr; + mnt_tabdiff_next_change; mnt_table_add_fs; mnt_table_find_next_fs; mnt_table_find_pair; @@ -171,6 +177,7 @@ global: mnt_table_get_name; mnt_table_get_nents; mnt_table_get_root_fs; + mnt_table_is_fs_mounted; mnt_table_next_child_fs; mnt_table_next_fs; mnt_table_parse_file; @@ -190,11 +197,6 @@ global: mnt_update_is_ready; mnt_update_set_fs; mnt_update_table; - mnt_new_tabdiff; - mnt_free_tabdiff; - mnt_diff_tables; - mnt_tabdiff_next_change; - mnt_table_is_fs_mounted; local: *; }; diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c index 406afc4b7..78b7571d2 100644 --- a/libmount/src/optstr.c +++ b/libmount/src/optstr.c @@ -273,15 +273,15 @@ int mnt_optstr_prepend_option(char **optstr, const char *name, const char *value * Returns: 0 on success, 1 when not found the @name or negative number in case * of error. */ -int mnt_optstr_get_option(char *optstr, const char *name, - char **value, size_t *valsz) +int mnt_optstr_get_option(const char *optstr, const char *name, + char **value, size_t *valsz) { struct libmnt_optloc ol; int rc; mnt_init_optloc(&ol); - rc = mnt_optstr_locate_option(optstr, name, &ol); + rc = mnt_optstr_locate_option((char *) optstr, name, &ol); if (!rc) { if (value) *value = ol.value; |