nspawn: split out overlayfs argument parsing into a function of its own
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Nov 2016 22:47:58 +0000 (23:47 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 30 Nov 2016 23:25:51 +0000 (00:25 +0100)
Add overlay_mount_parse() similar in style to tmpfs_mount_parse() and
bind_mount_parse().

src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn.c

index f8a79ec..6782c74 100644 (file)
@@ -180,6 +180,61 @@ int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s) {
         return 0;
 }
 
+int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only) {
+        _cleanup_free_ char *upper = NULL, *destination = NULL;
+        _cleanup_strv_free_ char **lower = NULL;
+        CustomMount *m;
+        unsigned k = 0;
+        char **i;
+        int r;
+
+        r = strv_split_extract(&lower, s, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, lower) {
+                if (!path_is_absolute(*i))
+                        return -EINVAL;
+
+                k++;
+        }
+
+        if (k < 2)
+                return -EADDRNOTAVAIL;
+        if (k == 2) {
+                /* If two parameters are specified,
+                 * the first one is the lower, the
+                 * second one the upper directory. And
+                 * we'll also define the destination
+                 * mount point the same as the upper. */
+                upper = lower[1];
+                lower[1] = NULL;
+
+                destination = strdup(upper);
+                if (!destination)
+                        return -ENOMEM;
+
+        } else {
+                upper = lower[k - 2];
+                destination = lower[k - 1];
+                lower[k - 2] = NULL;
+        }
+
+        m = custom_mount_add(l, n, CUSTOM_MOUNT_OVERLAY);
+        if (!m)
+                return -ENOMEM;
+
+        m->destination = destination;
+        m->source = upper;
+        m->lower = lower;
+        m->read_only = read_only;
+
+        upper = destination = NULL;
+        lower = NULL;
+
+        return 0;
+}
+
 static int tmpfs_patch_options(
                 const char *options,
                 bool userns,
index 74aee7e..83acd01 100644 (file)
@@ -61,8 +61,10 @@ typedef struct CustomMount {
 CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t);
 
 void custom_mount_free_all(CustomMount *l, unsigned n);
+
 int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only);
 int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s);
+int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only);
 
 int custom_mount_compare(const void *a, const void *b);
 
index 9a30868..e739df7 100644 (file)
@@ -789,69 +789,15 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_OVERLAY:
-                case ARG_OVERLAY_RO: {
-                        _cleanup_free_ char *upper = NULL, *destination = NULL;
-                        _cleanup_strv_free_ char **lower = NULL;
-                        CustomMount *m;
-                        unsigned n = 0;
-                        char **i;
-
-                        r = strv_split_extract(&lower, optarg, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
-                        if (r == -ENOMEM)
-                                return log_oom();
-                        else if (r < 0) {
-                                log_error("Invalid overlay specification: %s", optarg);
-                                return r;
-                        }
-
-                        STRV_FOREACH(i, lower) {
-                                if (!path_is_absolute(*i)) {
-                                        log_error("Overlay path %s is not absolute.", *i);
-                                        return -EINVAL;
-                                }
-
-                                n++;
-                        }
-
-                        if (n < 2) {
-                                log_error("--overlay= needs at least two colon-separated directories specified.");
-                                return -EINVAL;
-                        }
-
-                        if (n == 2) {
-                                /* If two parameters are specified,
-                                 * the first one is the lower, the
-                                 * second one the upper directory. And
-                                 * we'll also define the destination
-                                 * mount point the same as the upper. */
-                                upper = lower[1];
-                                lower[1] = NULL;
-
-                                destination = strdup(upper);
-                                if (!destination)
-                                        return log_oom();
-
-                        } else {
-                                upper = lower[n - 2];
-                                destination = lower[n - 1];
-                                lower[n - 2] = NULL;
-                        }
-
-                        m = custom_mount_add(&arg_custom_mounts, &arg_n_custom_mounts, CUSTOM_MOUNT_OVERLAY);
-                        if (!m)
-                                return log_oom();
-
-                        m->destination = destination;
-                        m->source = upper;
-                        m->lower = lower;
-                        m->read_only = c == ARG_OVERLAY_RO;
-
-                        upper = destination = NULL;
-                        lower = NULL;
+                case ARG_OVERLAY_RO:
+                        r = overlay_mount_parse(&arg_custom_mounts, &arg_n_custom_mounts, optarg, c == ARG_OVERLAY_RO);
+                        if (r == -EADDRNOTAVAIL)
+                                return log_error_errno(r, "--overlay(-ro)= needs at least two colon-separated directories specified.");
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --overlay(-ro)= argument %s: %m", optarg);
 
                         arg_settings_mask |= SETTING_CUSTOM_MOUNTS;
                         break;
-                }
 
                 case 'E': {
                         char **n;