summaryrefslogtreecommitdiff
path: root/src/nspawn
diff options
context:
space:
mode:
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-mount.c55
-rw-r--r--src/nspawn/nspawn-mount.h2
-rw-r--r--src/nspawn/nspawn.c66
3 files changed, 63 insertions, 60 deletions
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index f8a79eca2f..6782c74b80 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -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,
diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h
index 74aee7ee7f..83acd01e00 100644
--- a/src/nspawn/nspawn-mount.h
+++ b/src/nspawn/nspawn-mount.h
@@ -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);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 9a308688e1..e739df7f72 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -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;