summaryrefslogtreecommitdiffstats
path: root/src/vmspawn
diff options
context:
space:
mode:
authorSam Leonard <sam.leonard@codethink.co.uk>2023-12-20 10:03:01 +0100
committerSam Leonard <sam.leonard@codethink.co.uk>2024-02-09 12:43:19 +0100
commit19301e76e62aa3525c327b879f9d06ffd66cc6c5 (patch)
tree024a435727730bc09c402431c300e15b2d96b88f /src/vmspawn
parentvmspawn: add kernel configuration options (diff)
downloadsystemd-19301e76e62aa3525c327b879f9d06ffd66cc6c5.tar.xz
systemd-19301e76e62aa3525c327b879f9d06ffd66cc6c5.zip
vmspawn: synthesise root= argument for direct kernel boot
Diffstat (limited to 'src/vmspawn')
-rw-r--r--src/vmspawn/meson.build1
-rw-r--r--src/vmspawn/vmspawn.c68
2 files changed, 68 insertions, 1 deletions
diff --git a/src/vmspawn/meson.build b/src/vmspawn/meson.build
index a67c66ebe1..5f54364fac 100644
--- a/src/vmspawn/meson.build
+++ b/src/vmspawn/meson.build
@@ -24,5 +24,6 @@ executables += [
'conditions': ['ENABLE_VMSPAWN'],
'sources' : files('vmspawn.c'),
'link_with' : vmspawn_libs,
+ 'dependencies' : [libblkid]
}
]
diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c
index 985abd9fbe..bc9ee01e77 100644
--- a/src/vmspawn/vmspawn.c
+++ b/src/vmspawn/vmspawn.c
@@ -5,17 +5,22 @@
#include <stdlib.h>
#include <unistd.h>
+#include "sd-event.h"
+#include "sd-id128.h"
+
#include "alloc-util.h"
#include "architecture.h"
#include "build.h"
#include "common-signal.h"
#include "copy.h"
#include "creds-util.h"
+#include "dissect-image.h"
#include "escape.h"
#include "event-util.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
+#include "gpt.h"
#include "hexdecoct.h"
#include "hostname-util.h"
#include "log.h"
@@ -30,7 +35,6 @@
#include "pretty-print.h"
#include "process-util.h"
#include "rm-rf.h"
-#include "sd-event.h"
#include "signal-util.h"
#include "socket-util.h"
#include "strv.h"
@@ -566,6 +570,60 @@ static int start_tpm(sd_bus *bus, const char *scope, const char *tpm, const char
return 0;
}
+static int discover_root(char **ret) {
+ int r;
+ _cleanup_(dissected_image_unrefp) DissectedImage *image = NULL;
+ _cleanup_free_ char *root = NULL;
+
+ assert(ret);
+
+ r = dissect_image_file_and_warn(
+ arg_image,
+ /* verity= */ NULL,
+ /* mount_options= */ NULL,
+ /* image_policy= */ NULL,
+ /* flags= */ 0,
+ &image);
+ if (r < 0)
+ return r;
+
+ if (image->partitions[PARTITION_ROOT].found)
+ root = strjoin("root=PARTUUID=", SD_ID128_TO_UUID_STRING(image->partitions[PARTITION_ROOT].uuid));
+ else if (image->partitions[PARTITION_USR].found)
+ root = strjoin("mount.usr=PARTUUID=", SD_ID128_TO_UUID_STRING(image->partitions[PARTITION_USR].uuid));
+ else
+ return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Cannot perform a direct kernel boot without a root or usr partition, refusing");
+
+ if (!root)
+ return log_oom();
+
+ *ret = TAKE_PTR(root);
+
+ return 0;
+}
+
+static int kernel_cmdline_maybe_append_root(void) {
+ int r;
+ bool cmdline_contains_root = strv_find_startswith(arg_kernel_cmdline_extra, "root=")
+ || strv_find_startswith(arg_kernel_cmdline_extra, "mount.usr=");
+
+ if (!cmdline_contains_root) {
+ _cleanup_free_ char *root = NULL;
+
+ r = discover_root(&root);
+ if (r < 0)
+ return r;
+
+ log_debug("Determined root file system %s from dissected image", root);
+
+ r = strv_consume(&arg_kernel_cmdline_extra, TAKE_PTR(root));
+ if (r < 0)
+ return log_oom();
+ }
+
+ return 0;
+}
+
static int run_virtual_machine(void) {
_cleanup_(ovmf_config_freep) OvmfConfig *ovmf_config = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
@@ -764,6 +822,14 @@ static int run_virtual_machine(void) {
r = strv_extend_many(&cmdline, "-kernel", arg_linux);
if (r < 0)
return log_oom();
+
+ /* We can't rely on gpt-auto-generator when direct kernel booting so synthesize a root=
+ * kernel argument instead. */
+ if (arg_image) {
+ r = kernel_cmdline_maybe_append_root();
+ if (r < 0)
+ return r;
+ }
}
r = strv_extend(&cmdline, "-drive");