summaryrefslogtreecommitdiffstats
path: root/src/vmspawn/vmspawn-mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vmspawn/vmspawn-mount.c')
-rw-r--r--src/vmspawn/vmspawn-mount.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/vmspawn/vmspawn-mount.c b/src/vmspawn/vmspawn-mount.c
new file mode 100644
index 0000000..ee63bda
--- /dev/null
+++ b/src/vmspawn/vmspawn-mount.c
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "extract-word.h"
+#include "macro.h"
+#include "parse-argument.h"
+#include "path-util.h"
+#include "string-util.h"
+#include "vmspawn-mount.h"
+
+static void runtime_mount_done(RuntimeMount *mount) {
+ assert(mount);
+
+ mount->source = mfree(mount->source);
+ mount->target = mfree(mount->target);
+}
+
+void runtime_mount_context_done(RuntimeMountContext *ctx) {
+ assert(ctx);
+
+ FOREACH_ARRAY(mount, ctx->mounts, ctx->n_mounts)
+ runtime_mount_done(mount);
+
+ free(ctx->mounts);
+}
+
+int runtime_mount_parse(RuntimeMountContext *ctx, const char *s, bool read_only) {
+ _cleanup_(runtime_mount_done) RuntimeMount mount = { .read_only = read_only };
+ _cleanup_free_ char *source_rel = NULL;
+ int r;
+
+ assert(ctx);
+
+ r = extract_first_word(&s, &source_rel, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -EINVAL;
+
+ if (isempty(source_rel))
+ return -EINVAL;
+
+ r = path_make_absolute_cwd(source_rel, &mount.source);
+ if (r < 0)
+ return r;
+
+ /* virtiofsd only supports directories */
+ r = is_dir(mount.source, /* follow= */ true);
+ if (r < 0)
+ return r;
+ if (!r)
+ return -ENOTDIR;
+
+ mount.target = s ? strdup(s) : TAKE_PTR(source_rel);
+ if (!mount.target)
+ return -ENOMEM;
+
+ if (!path_is_absolute(mount.target))
+ return -EINVAL;
+
+ if (!GREEDY_REALLOC(ctx->mounts, ctx->n_mounts + 1))
+ return log_oom();
+
+ ctx->mounts[ctx->n_mounts++] = TAKE_STRUCT(mount);
+
+ return 0;
+}