diff options
author | Sam Leonard <sam.leonard@codethink.co.uk> | 2023-12-20 10:03:01 +0100 |
---|---|---|
committer | Sam Leonard <sam.leonard@codethink.co.uk> | 2024-02-09 12:43:19 +0100 |
commit | 19301e76e62aa3525c327b879f9d06ffd66cc6c5 (patch) | |
tree | 024a435727730bc09c402431c300e15b2d96b88f /src/vmspawn | |
parent | vmspawn: add kernel configuration options (diff) | |
download | systemd-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.build | 1 | ||||
-rw-r--r-- | src/vmspawn/vmspawn.c | 68 |
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"); |