diff --git a/man/systemd-vmspawn.xml b/man/systemd-vmspawn.xml
index ce352bc2d0..a9011d9106 100644
--- a/man/systemd-vmspawn.xml
+++ b/man/systemd-vmspawn.xml
@@ -158,20 +158,20 @@
-
+ PATH
- Start QEMU in graphical mode.
-
-
+
+ Set the initrd to use for direct kernel boot.
+ If the linux kernel supplied is a UKI then this argument is not required.
+ If no initrd was installed into the image then the image will fail to boot.
+
+
- BOOL
+
- Configure whether to search for firmware which supports Secure Boot.
- If the option is not specified the first firmware which is detected will be used.
- If the option is set to yes then the first firmware with Secure Boot support will be selected.
- If no is specified then the first firmware without Secure Boot will be selected.
+ Start QEMU in graphical mode.
@@ -186,9 +186,21 @@
-
-
+
+ BOOL
+
+ Configure whether to search for firmware which supports Secure Boot.
+ If the option is not specified the first firmware which is detected will be used.
+ If the option is set to yes then the first firmware with Secure Boot support will be selected.
+ If no is specified then the first firmware without Secure Boot will be selected.
+
+
+
+
+
+
+ System Identity Options
diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c
index bc9ee01e77..5e5139d574 100644
--- a/src/vmspawn/vmspawn.c
+++ b/src/vmspawn/vmspawn.c
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#include "sd-event.h"
@@ -23,8 +24,10 @@
#include "gpt.h"
#include "hexdecoct.h"
#include "hostname-util.h"
+#include "kernel-image.h"
#include "log.h"
#include "machine-credential.h"
+#include "macro.h"
#include "main-func.h"
#include "mkdir.h"
#include "pager.h"
@@ -37,6 +40,7 @@
#include "rm-rf.h"
#include "signal-util.h"
#include "socket-util.h"
+#include "string-util.h"
#include "strv.h"
#include "tmpfile-util.h"
#include "unit-name.h"
@@ -55,6 +59,7 @@ static int arg_qemu_vsock = -1;
static unsigned arg_vsock_cid = VMADDR_CID_ANY;
static int arg_tpm = -1;
static char *arg_linux = NULL;
+static char *arg_initrd = NULL;
static bool arg_qemu_gui = false;
static int arg_secure_boot = -1;
static MachineCredentialContext arg_credentials = {};
@@ -72,6 +77,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_runtime_directory, freep);
STATIC_DESTRUCTOR_REGISTER(arg_credentials, machine_credential_context_done);
STATIC_DESTRUCTOR_REGISTER(arg_firmware, freep);
STATIC_DESTRUCTOR_REGISTER(arg_linux, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_initrd, freep);
STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline_extra, strv_freep);
static int help(void) {
@@ -101,6 +107,7 @@ static int help(void) {
" --vsock-cid= Specify the CID to use for the qemu guest's vsock\n"
" --tpm=BOOL Configure whether to use a virtual TPM or not\n"
" --linux=PATH Specify the linux kernel for direct kernel boot\n"
+ " --initrd=PATH Specify the initrd for direct kernel boot\n"
" --qemu-gui Start QEMU in graphical mode\n"
" --secure-boot=BOOL Configure whether to search for firmware which\n"
" supports Secure Boot\n"
@@ -136,6 +143,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VSOCK_CID,
ARG_TPM,
ARG_LINUX,
+ ARG_INITRD,
ARG_QEMU_GUI,
ARG_SECURE_BOOT,
ARG_SET_CREDENTIAL,
@@ -157,6 +165,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "vsock-cid", required_argument, NULL, ARG_VSOCK_CID },
{ "tpm", required_argument, NULL, ARG_TPM },
{ "linux", required_argument, NULL, ARG_LINUX },
+ { "initrd", required_argument, NULL, ARG_INITRD },
{ "qemu-gui", no_argument, NULL, ARG_QEMU_GUI },
{ "secure-boot", required_argument, NULL, ARG_SECURE_BOOT },
{ "set-credential", required_argument, NULL, ARG_SET_CREDENTIAL },
@@ -261,6 +270,13 @@ static int parse_argv(int argc, char *argv[]) {
return r;
break;
+ case ARG_INITRD: {
+ r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_initrd);
+ if (r < 0)
+ return r;
+ break;
+ }
+
case ARG_QEMU_GUI:
arg_qemu_gui = true;
break;
@@ -927,6 +943,12 @@ static int run_virtual_machine(void) {
return log_oom();
}
+ if (arg_initrd) {
+ r = strv_extend_many(&cmdline, "-initrd", arg_initrd);
+ if (r < 0)
+ return log_oom();
+ }
+
if (use_vsock) {
vsock_fd = open_vsock();
if (vsock_fd < 0)