chiark / gitweb /
mount-util: add mount_option_mangle()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 15 Feb 2018 00:32:04 +0000 (09:32 +0900)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:59:01 +0000 (07:59 +0200)
This is used in the later commits.

src/basic/meson.build
src/basic/mount-util.c
src/basic/mount-util.h

index 0c593cc71135a420b5a5ce0b9a91162106e51659..360c5db0be668fe7ea3a33e42283934a1e417b63 100644 (file)
@@ -473,6 +473,7 @@ libbasic = static_library(
 #if 0 /// no blkid in elogind
 #                         libblkid,
 #endif // 0
+                        libmount,
                         libselinux],
         c_args : ['-fvisibility=default'],
         install : false)
index 8b480bbeb9b6b854c58dd9f2ce8348909b892e0f..e7106898bbd9339930197471ed600791a4525a97 100644 (file)
 #include <sys/statvfs.h>
 #include <unistd.h>
 
+/* Include later */
+//#include <libmount.h>
+
 #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;
+}
index cfe30a6256dc4a804ac1978bf096a9dcd39f9e6d..5088dad930031f7b62a9eedd2f0bcd0857be0172 100644 (file)
@@ -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);