summaryrefslogtreecommitdiff
path: root/src/basic/mount-util.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-02-15 09:32:04 +0900
committerSven Eden <yamakuzure@gmx.net>2018-05-30 07:59:01 +0200
commit2f42b0cdac62766e887eaad370cf9fad682c84b0 (patch)
tree59d38486abbd109231911739000abbacea8d4830 /src/basic/mount-util.c
parentdfa4d304232d841d119f9f5a2a6f9ff8399f16ef (diff)
mount-util: add mount_option_mangle()
This is used in the later commits.
Diffstat (limited to 'src/basic/mount-util.c')
-rw-r--r--src/basic/mount-util.c74
1 files changed, 74 insertions, 0 deletions
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 <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;
+}