From: Yu Watanabe Date: Thu, 15 Feb 2018 00:32:04 +0000 (+0900) Subject: mount-util: add mount_option_mangle() X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=2f42b0cdac62766e887eaad370cf9fad682c84b0;p=elogind.git mount-util: add mount_option_mangle() This is used in the later commits. --- diff --git a/src/basic/meson.build b/src/basic/meson.build index 0c593cc71..360c5db0b 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -473,6 +473,7 @@ libbasic = static_library( #if 0 /// no blkid in elogind # libblkid, #endif // 0 + libmount, libselinux], c_args : ['-fvisibility=default'], install : false) diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 8b480bbeb..e7106898b 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -27,8 +27,12 @@ #include #include +/* Include later */ +//#include + #include "alloc-util.h" #include "escape.h" +//#include "extract-word.h" #include "fd-util.h" #include "fileio.h" #include "fs-util.h" @@ -878,3 +882,73 @@ int mount_propagation_flags_from_string(const char *name, unsigned long *ret) { return -EINVAL; return 0; } + +int mount_option_mangle( + const char *options, + unsigned long mount_flags, + unsigned long *ret_mount_flags, + char **ret_remaining_options) { + + const struct libmnt_optmap *map; + _cleanup_free_ char *ret = NULL; + const char *p; + int r; + + /* This extracts mount flags from the mount options, and store + * non-mount-flag options to '*ret_remaining_options'. + * E.g., + * "rw,nosuid,nodev,relatime,size=1630748k,mode=700,uid=1000,gid=1000" + * is split to MS_NOSUID|MS_NODEV|MS_RELATIME and + * "size=1630748k,mode=700,uid=1000,gid=1000". + * See more examples in test-mount-utils.c. + * + * Note that if 'options' does not contain any non-mount-flag options, + * then '*ret_remaining_options' is set to NULL instread of empty string. + * Note that this does not check validity of options stored in + * '*ret_remaining_options'. + * Note that if 'options' is NULL, then this just copies 'mount_flags' + * to '*ret_mount_flags'. */ + + assert(ret_mount_flags); + assert(ret_remaining_options); + + map = mnt_get_builtin_optmap(MNT_LINUX_MAP); + if (!map) + return -EINVAL; + + p = options; + for (;;) { + _cleanup_free_ char *word = NULL; + const struct libmnt_optmap *ent; + + r = extract_first_word(&p, &word, ",", EXTRACT_QUOTES); + if (r < 0) + return r; + if (r == 0) + break; + + for (ent = map; ent->name; ent++) { + /* All entries in MNT_LINUX_MAP do not take any argument. + * Thus, ent->name does not contain "=" or "[=]". */ + if (!streq(word, ent->name)) + continue; + + if (!(ent->mask & MNT_INVERT)) + mount_flags |= ent->id; + else if (mount_flags & ent->id) + mount_flags ^= ent->id; + + break; + } + + /* If 'word' is not a mount flag, then store it in '*ret_remaining_options'. */ + if (!ent->name && !strextend_with_separator(&ret, ",", word, NULL)) + return -ENOMEM; + } + + *ret_mount_flags = mount_flags; + *ret_remaining_options = ret; + ret = NULL; + + return 0; +} diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h index cfe30a625..5088dad93 100644 --- a/src/basic/mount-util.h +++ b/src/basic/mount-util.h @@ -73,3 +73,9 @@ int umount_verbose(const char *where); const char *mount_propagation_flags_to_string(unsigned long flags); int mount_propagation_flags_from_string(const char *name, unsigned long *ret); + +int mount_option_mangle( + const char *options, + unsigned long mount_flags, + unsigned long *ret_mount_flags, + char **ret_remaining_options);