diff --git a/man/systemd-vmspawn.xml b/man/systemd-vmspawn.xml
index 2db88d3b7f..5e890d8c29 100644
--- a/man/systemd-vmspawn.xml
+++ b/man/systemd-vmspawn.xml
@@ -164,17 +164,31 @@
If is not specified, vmspawn will detect the presence of
- swtpm8 and use it if available.
- If yes is specified swtpm8
- is always used, and if no is set swtpm
+ swtpm8 and use it if
+ available. If yes is specified swtpm8 is
+ always used, and if no is set swtpm
8 is never used.
- Note: the virtual TPM used may change in future.
-
+
+
+
+ Configures where to place TPM state, in case TPM support is enabled (see
+ above). This takes an absolute file system path to a directory to
+ persistently place the state in. If the directory is missing it is created as needed. If set to the
+ special string auto a peristent path is automatically derived from the VM image
+ path or directory path, with the .tpmstate suffix appended. If set to the
+ special string off the TPM state is only maintained transiently and flushed out
+ when the VM shuts down. This mode is not suitable for VMs which lock disk encryption keys to the
+ TPM, as these keys will be lost on every reboot. Defaults to auto.
+
+
+
+
diff --git a/src/vmspawn/vmspawn-scope.c b/src/vmspawn/vmspawn-scope.c
index 58f6781b77..c8c2b8f296 100644
--- a/src/vmspawn/vmspawn-scope.c
+++ b/src/vmspawn/vmspawn-scope.c
@@ -180,7 +180,6 @@ void socket_service_pair_done(SocketServicePair *p) {
p->exec_start = strv_free(p->exec_start);
p->exec_stop_post = strv_free(p->exec_stop_post);
p->unit_name_prefix = mfree(p->unit_name_prefix);
- p->runtime_directory = mfree(p->runtime_directory);
p->listen_address = mfree(p->listen_address);
p->socket_type = 0;
}
@@ -232,10 +231,11 @@ int start_socket_service_pair(sd_bus *bus, const char *scope, SocketServicePair
/* a(sv) - Properties */
5,
"Description", "s", p->listen_address,
- "AddRef", "b", 1,
+ "AddRef", "b", true,
"BindsTo", "as", 1, scope,
"Listen", "a(ss)", 1, socket_type_str, p->listen_address,
- "CollectMode", "s", "inactive-or-failed");
+ "CollectMode", "s", "inactive-or-failed",
+ "RemoveOnStop", "b", true);
if (r < 0)
return bus_log_create_error(r);
@@ -264,12 +264,6 @@ int start_socket_service_pair(sd_bus *bus, const char *scope, SocketServicePair
if (r < 0)
return bus_log_create_error(r);
- if (p->runtime_directory) {
- r = sd_bus_message_append(m, "(sv)", "RuntimeDirectory", "as", 1, p->runtime_directory);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
if (p->exec_start_pre) {
r = message_add_commands(m, "ExecStartPre", &p->exec_start_pre, 1);
if (r < 0)
diff --git a/src/vmspawn/vmspawn-scope.h b/src/vmspawn/vmspawn-scope.h
index 74c75117f0..100de94fa1 100644
--- a/src/vmspawn/vmspawn-scope.h
+++ b/src/vmspawn/vmspawn-scope.h
@@ -12,7 +12,6 @@ typedef struct SocketServicePair {
char **exec_start;
char **exec_stop_post;
char *unit_name_prefix;
- char *runtime_directory;
char *listen_address;
int socket_type;
} SocketServicePair;
diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c
index 294775d03e..4629cf0e79 100644
--- a/src/vmspawn/vmspawn.c
+++ b/src/vmspawn/vmspawn.c
@@ -81,6 +81,14 @@
#define VM_TAP_HASH_KEY SD_ID128_MAKE(01,d0,c6,4c,2b,df,24,fb,c0,f8,b2,09,7d,59,b2,93)
+typedef enum TpmStateMode {
+ TPM_STATE_OFF, /* keep no state around */
+ TPM_STATE_AUTO, /* keep state around, derive path from image/directory */
+ TPM_STATE_PATH, /* explicitly specified location */
+ _TPM_STATE_MODE_MAX,
+ _TPM_STATE_MODE_INVALID = -EINVAL,
+} TpmStateMode;
+
typedef struct SSHInfo {
unsigned cid;
char *private_key_path;
@@ -108,9 +116,7 @@ static uid_t arg_uid_shift = UID_INVALID, arg_uid_range = 0x10000U;
static RuntimeMountContext arg_runtime_mounts = {};
static SettingsMask arg_settings_mask = 0;
static char *arg_firmware = NULL;
-static char *arg_runtime_directory = NULL;
static char *arg_forward_journal = NULL;
-static bool arg_runtime_directory_created = false;
static bool arg_privileged = false;
static bool arg_register = false;
static bool arg_keep_unit = false;
@@ -124,12 +130,13 @@ static bool arg_discard_disk = true;
struct ether_addr arg_network_provided_mac = {};
static char **arg_smbios11 = NULL;
static uint64_t arg_grow_image = 0;
+static char *arg_tpm_state_path = NULL;
+static TpmStateMode arg_tpm_state_mode = TPM_STATE_AUTO;
STATIC_DESTRUCTOR_REGISTER(arg_directory, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
STATIC_DESTRUCTOR_REGISTER(arg_machine, freep);
STATIC_DESTRUCTOR_REGISTER(arg_cpus, freep);
-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);
@@ -141,6 +148,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_extra_drives, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_background, freep);
STATIC_DESTRUCTOR_REGISTER(arg_ssh_key_type, freep);
STATIC_DESTRUCTOR_REGISTER(arg_smbios11, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(arg_tpm_state_path, freep);
static int help(void) {
_cleanup_free_ char *link = NULL;
@@ -168,6 +176,8 @@ static int help(void) {
" --vsock=BOOL Override autodetection of VSOCK support\n"
" --vsock-cid=CID Specify the CID to use for the guest's VSOCK support\n"
" --tpm=BOOL Enable use of a virtual TPM\n"
+ " --tpm-state=off|auto|PATH\n"
+ " Where to store TPM state\n"
" --linux=PATH Specify the linux kernel for direct kernel boot\n"
" --initrd=PATH Specify the initrd for direct kernel boot\n"
" -n --network-tap Create a TAP device for networking\n"
@@ -263,6 +273,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DISCARD_DISK,
ARG_CONSOLE,
ARG_BACKGROUND,
+ ARG_TPM_STATE,
};
static const struct option options[] = {
@@ -307,6 +318,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "background", required_argument, NULL, ARG_BACKGROUND },
{ "smbios11", required_argument, NULL, 's' },
{ "grow-image", required_argument, NULL, 'G' },
+ { "tpm-state", required_argument, NULL, ARG_TPM_STATE },
{}
};
@@ -602,6 +614,26 @@ static int parse_argv(int argc, char *argv[]) {
break;
+ case ARG_TPM_STATE:
+ if (path_is_absolute(optarg) && path_is_valid(optarg)) {
+ r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm_state_path);
+ if (r < 0)
+ return r;
+
+ arg_tpm_state_mode = TPM_STATE_PATH;
+ break;
+ }
+
+ r = isempty(optarg) ? false :
+ streq(optarg, "auto") ? true :
+ parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --tpm-state= parameter: %s", optarg);
+
+ arg_tpm_state_mode = r ? TPM_STATE_AUTO : TPM_STATE_OFF;
+ arg_tpm_state_path = mfree(arg_tpm_state_path);
+ break;
+
case '?':
return -EINVAL;
@@ -1030,48 +1062,55 @@ static int start_tpm(
sd_bus *bus,
const char *scope,
const char *swtpm,
- char **ret_state_tempdir) {
+ const char *runtime_dir,
+ char **ret_listen_address) {
- _cleanup_(rm_rf_physical_and_freep) char *state_dir = NULL;
- _cleanup_free_ char *scope_prefix = NULL;
- _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
- .socket_type = SOCK_STREAM,
- };
int r;
assert(bus);
assert(scope);
assert(swtpm);
- assert(ret_state_tempdir);
+ assert(runtime_dir);
+ _cleanup_free_ char *scope_prefix = NULL;
r = unit_name_to_prefix(scope, &scope_prefix);
if (r < 0)
return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
+ _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
+ .socket_type = SOCK_STREAM,
+ };
+
ssp.unit_name_prefix = strjoin(scope_prefix, "-tpm");
if (!ssp.unit_name_prefix)
return log_oom();
- state_dir = path_join(arg_runtime_directory, ssp.unit_name_prefix);
- if (!state_dir)
- return log_oom();
-
- if (arg_runtime_directory_created) {
- ssp.runtime_directory = path_join("systemd/vmspawn", ssp.unit_name_prefix);
- if (!ssp.runtime_directory)
- return log_oom();
- }
-
- ssp.listen_address = path_join(state_dir, "sock");
+ ssp.listen_address = path_join(runtime_dir, "tpm.sock");
if (!ssp.listen_address)
return log_oom();
+ _cleanup_free_ char *transient_state_dir = NULL;
+ const char *state_dir;
+ if (arg_tpm_state_path)
+ state_dir = arg_tpm_state_path;
+ else {
+ transient_state_dir = path_join(runtime_dir, ssp.unit_name_prefix);
+ if (!transient_state_dir)
+ return log_oom();
+
+ state_dir = transient_state_dir;
+ }
+
+ r = mkdir_p(state_dir, 0700);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create TPM state directory '%s': %m", state_dir);
+
_cleanup_free_ char *swtpm_setup = NULL;
r = find_executable("swtpm_setup", &swtpm_setup);
if (r < 0)
return log_error_errno(r, "Failed to find swtpm_setup binary: %m");
- ssp.exec_start_pre = strv_new(swtpm_setup, "--tpm-state", state_dir, "--tpm2", "--pcr-banks", "sha256");
+ ssp.exec_start_pre = strv_new(swtpm_setup, "--tpm-state", state_dir, "--tpm2", "--pcr-banks", "sha256", "--not-overwrite");
if (!ssp.exec_start_pre)
return log_oom();
@@ -1091,31 +1130,39 @@ static int start_tpm(
if (r < 0)
return r;
- *ret_state_tempdir = TAKE_PTR(state_dir);
+ if (ret_listen_address)
+ *ret_listen_address = TAKE_PTR(ssp.listen_address);
+
return 0;
}
-static int start_systemd_journal_remote(sd_bus *bus, const char *scope, unsigned port, const char *sd_journal_remote, char **ret_listen_address) {
- _cleanup_free_ char *scope_prefix = NULL;
- _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
- .socket_type = SOCK_STREAM,
- };
+static int start_systemd_journal_remote(
+ sd_bus *bus,
+ const char *scope,
+ unsigned port,
+ const char *sd_journal_remote,
+ char **ret_listen_address) {
+
int r;
assert(bus);
assert(scope);
assert(sd_journal_remote);
+ _cleanup_free_ char *scope_prefix = NULL;
r = unit_name_to_prefix(scope, &scope_prefix);
if (r < 0)
return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
+ _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
+ .socket_type = SOCK_STREAM,
+ };
+
ssp.unit_name_prefix = strjoin(scope_prefix, "-forward-journal");
if (!ssp.unit_name_prefix)
return log_oom();
- r = asprintf(&ssp.listen_address, "vsock:2:%u", port);
- if (r < 0)
+ if (asprintf(&ssp.listen_address, "vsock:2:%u", port) < 0)
return log_oom();
ssp.exec_start = strv_new(
@@ -1197,47 +1244,40 @@ static int find_virtiofsd(char **ret) {
return 0;
}
-static int start_virtiofsd(sd_bus *bus, const char *scope, const char *directory, bool uidmap, char **ret_state_tempdir, char **ret_sock_name) {
- _cleanup_(rm_rf_physical_and_freep) char *state_dir = NULL;
- _cleanup_free_ char *virtiofsd = NULL, *sock_name = NULL, *scope_prefix = NULL;
- _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
- .socket_type = SOCK_STREAM,
- };
+static int start_virtiofsd(
+ sd_bus *bus,
+ const char *scope,
+ const char *directory,
+ bool uidmap,
+ const char *runtime_dir,
+ char **ret_listen_address) {
+
static unsigned virtiofsd_instance = 0;
int r;
assert(bus);
assert(scope);
assert(directory);
- assert(ret_state_tempdir);
- assert(ret_sock_name);
+ assert(runtime_dir);
+ _cleanup_free_ char *virtiofsd = NULL;
r = find_virtiofsd(&virtiofsd);
if (r < 0)
return r;
+ _cleanup_free_ char *scope_prefix = NULL;
r = unit_name_to_prefix(scope, &scope_prefix);
if (r < 0)
return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
+ _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
+ .socket_type = SOCK_STREAM,
+ };
+
if (asprintf(&ssp.unit_name_prefix, "%s-virtiofsd-%u", scope_prefix, virtiofsd_instance++) < 0)
return log_oom();
- state_dir = path_join(arg_runtime_directory, ssp.unit_name_prefix);
- if (!state_dir)
- return log_oom();
-
- if (arg_runtime_directory_created) {
- ssp.runtime_directory = strjoin("systemd/vmspawn/", ssp.unit_name_prefix);
- if (!ssp.runtime_directory)
- return log_oom();
- }
-
- if (asprintf(&sock_name, "sock-%"PRIx64, random_u64()) < 0)
- return log_oom();
-
- ssp.listen_address = path_join(state_dir, sock_name);
- if (!ssp.listen_address)
+ if (asprintf(&ssp.listen_address, "%s/sock-%"PRIx64, runtime_dir, random_u64()) < 0)
return log_oom();
/* QEMU doesn't support submounts so don't announce them */
@@ -1267,8 +1307,8 @@ static int start_virtiofsd(sd_bus *bus, const char *scope, const char *directory
if (r < 0)
return r;
- *ret_state_tempdir = TAKE_PTR(state_dir);
- *ret_sock_name = TAKE_PTR(sock_name);
+ if (ret_listen_address)
+ *ret_listen_address = TAKE_PTR(ssp.listen_address);
return 0;
}
@@ -1634,17 +1674,34 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
return log_oom();
/* if we are going to be starting any units with state then create our runtime dir */
- if (arg_tpm != 0 || arg_directory || arg_runtime_mounts.n_mounts != 0) {
- r = runtime_directory(arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER, "systemd/vmspawn",
- &arg_runtime_directory);
+ _cleanup_free_ char *runtime_dir = NULL;
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir_destroy = NULL;
+ if (arg_tpm != 0 || arg_directory || arg_runtime_mounts.n_mounts != 0 || arg_pass_ssh_key) {
+ _cleanup_free_ char *subdir = NULL;
+
+ if (asprintf(&subdir, "systemd/vmspawn.%" PRIx64, random_u64()) < 0)
+ return log_oom();
+
+ r = runtime_directory(
+ arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
+ subdir,
+ &runtime_dir);
if (r < 0)
return log_error_errno(r, "Failed to lookup runtime directory: %m");
if (r > 0) { /* We need to create our own runtime dir */
- r = mkdir_p(arg_runtime_directory, 0755);
+ r = mkdir_p(runtime_dir, 0755);
if (r < 0)
- return log_error_errno(r, "Failed to create runtime directory: %m");
- arg_runtime_directory_created = true;
+ return log_error_errno(r, "Failed to create runtime directory '%s': %m", runtime_dir);
+
+ /* We created this, hence also destroy it */
+ runtime_dir_destroy = TAKE_PTR(runtime_dir);
+
+ runtime_dir = strdup(runtime_dir_destroy);
+ if (!runtime_dir)
+ return log_oom();
}
+
+ log_debug("Using runtime directory: %s", runtime_dir);
}
_cleanup_close_ int delegate_userns_fd = -EBADF, tap_fd = -EBADF;
@@ -1957,7 +2014,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
escaped_image = escape_qemu_value(arg_image);
if (!escaped_image)
- log_oom();
+ return log_oom();
r = strv_extendf(&cmdline, "if=none,id=vmspawn,file=%s,format=raw,discard=%s", escaped_image, on_off(arg_discard_disk));
if (r < 0)
@@ -1971,34 +2028,28 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
}
if (arg_directory) {
- _cleanup_free_ char *sock_path = NULL, *sock_name = NULL, *escaped_sock_path = NULL;
-
- r = start_virtiofsd(bus, trans_scope, arg_directory, /* uidmap= */ true, &sock_path, &sock_name);
+ _cleanup_free_ char *listen_address = NULL;
+ r = start_virtiofsd(bus, trans_scope, arg_directory, /* uidmap= */ true, runtime_dir, &listen_address);
if (r < 0)
return r;
- escaped_sock_path = escape_qemu_value(sock_path);
- if (!escaped_sock_path)
- log_oom();
-
- r = strv_extend(&cmdline, "-chardev");
- if (r < 0)
+ _cleanup_free_ char *escaped_listen_address = escape_qemu_value(listen_address);
+ if (!escaped_listen_address)
return log_oom();
- r = strv_extendf(&cmdline, "socket,id=%1$s,path=%2$s/%1$s", sock_name, escaped_sock_path);
- if (r < 0)
+ if (strv_extend(&cmdline, "-chardev") < 0)
return log_oom();
- r = strv_extend(&cmdline, "-device");
- if (r < 0)
+ if (strv_extendf(&cmdline, "socket,id=rootdir,path=%s", escaped_listen_address) < 0)
return log_oom();
- r = strv_extendf(&cmdline, "vhost-user-fs-pci,queue-size=1024,chardev=%s,tag=root", sock_name);
- if (r < 0)
+ if (strv_extend_many(
+ &cmdline,
+ "-device",
+ "vhost-user-fs-pci,queue-size=1024,chardev=rootdir,tag=root") < 0)
return log_oom();
- r = strv_extend(&arg_kernel_cmdline_extra, "root=root rootfstype=virtiofs rw");
- if (r < 0)
+ if (strv_extend(&arg_kernel_cmdline_extra, "root=root rootfstype=virtiofs rw") < 0)
return log_oom();
}
@@ -2007,38 +2058,37 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
return log_oom();
FOREACH_ARRAY(mount, arg_runtime_mounts.mounts, arg_runtime_mounts.n_mounts) {
- _cleanup_free_ char *sock_path = NULL, *sock_name = NULL, *clean_target = NULL, *escaped_sock_path = NULL;
- r = start_virtiofsd(bus, trans_scope, mount->source, /* uidmap= */ false, &sock_path, &sock_name);
+ _cleanup_free_ char *listen_address = NULL;
+ r = start_virtiofsd(bus, trans_scope, mount->source, /* uidmap= */ false, runtime_dir, &listen_address);
if (r < 0)
return r;
- escaped_sock_path = escape_qemu_value(sock_path);
- if (!escaped_sock_path)
- log_oom();
-
- r = strv_extend(&cmdline, "-chardev");
- if (r < 0)
+ _cleanup_free_ char *escaped_listen_address = escape_qemu_value(listen_address);
+ if (!escaped_listen_address)
return log_oom();
- r = strv_extendf(&cmdline, "socket,id=%1$s,path=%2$s/%1$s", sock_name, escaped_sock_path);
- if (r < 0)
+ if (strv_extend(&cmdline, "-chardev") < 0)
return log_oom();
- r = strv_extend(&cmdline, "-device");
- if (r < 0)
+ _cleanup_free_ char *id = NULL;
+ if (asprintf(&id, "mnt%zi", mount - arg_runtime_mounts.mounts) < 0)
return log_oom();
- r = strv_extendf(&cmdline, "vhost-user-fs-pci,queue-size=1024,chardev=%1$s,tag=%1$s", sock_name);
- if (r < 0)
+ if (strv_extendf(&cmdline, "socket,id=%s,path=%s", id, escaped_listen_address) < 0)
return log_oom();
- clean_target = xescape(mount->target, "\":");
+ if (strv_extend(&cmdline, "-device") < 0)
+ return log_oom();
+
+ if (strv_extendf(&cmdline, "vhost-user-fs-pci,queue-size=1024,chardev=%1$s,tag=%1$s", id) < 0)
+ return log_oom();
+
+ _cleanup_free_ char *clean_target = xescape(mount->target, "\":");
if (!clean_target)
return log_oom();
- r = strv_extendf(&arg_kernel_cmdline_extra, "systemd.mount-extra=\"%s:%s:virtiofs:%s\"",
- sock_name, clean_target, mount->read_only ? "ro" : "rw");
- if (r < 0)
+ if (strv_extendf(&arg_kernel_cmdline_extra, "systemd.mount-extra=\"%s:%s:virtiofs:%s\"",
+ id, clean_target, mount->read_only ? "ro" : "rw") < 0)
return log_oom();
}
@@ -2052,15 +2102,41 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
/* disable TPM autodetection if the user's hardware doesn't support it */
if (!ARCHITECTURE_SUPPORTS_TPM) {
- if (arg_tpm < 0) {
- arg_tpm = 0;
- log_debug("TPM not support on %s, disabling tpm autodetection and continuing", architecture_to_string(native_architecture()));
- } else if (arg_tpm > 0)
+ if (arg_tpm > 0)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM not supported on %s, refusing", architecture_to_string(native_architecture()));
+ if (arg_tpm < 0) {
+ arg_tpm = false;
+ log_debug("TPM not support on %s, disabling tpm autodetection and continuing", architecture_to_string(native_architecture()));
+ }
}
_cleanup_free_ char *swtpm = NULL;
if (arg_tpm != 0) {
+ if (arg_tpm_state_mode == TPM_STATE_AUTO) {
+ assert(!arg_tpm_state_path);
+
+ const char *p = ASSERT_PTR(arg_image ?: arg_directory);
+
+ _cleanup_free_ char *parent = NULL;
+ r = path_extract_directory(p, &parent);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract parent directory from '%s': %m", p);
+
+ _cleanup_free_ char *filename = NULL;
+ r = path_extract_filename(p, &filename);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract filename from '%s': %m", p);
+
+ if (!strextend(&filename, ".tpmstate"))
+ return log_oom();
+
+ arg_tpm_state_path = path_join(parent, filename);
+ if (!arg_tpm_state_path)
+ return log_oom();
+
+ log_debug("Storing TPM state persistently under '%s'.", arg_tpm_state_path);
+ }
+
r = find_executable("swtpm", &swtpm);
if (r < 0) {
/* log if the user asked for swtpm and we cannot find it */
@@ -2072,34 +2148,30 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
}
}
- _cleanup_free_ char *tpm_state_tempdir = NULL;
+ _cleanup_free_ char *tpm_socket_address = NULL;
if (swtpm) {
- r = start_tpm(bus, trans_scope, swtpm, &tpm_state_tempdir);
+ r = start_tpm(bus, trans_scope, swtpm, runtime_dir, &tpm_socket_address);
if (r < 0) {
/* only bail if the user asked for a tpm */
if (arg_tpm > 0)
return log_error_errno(r, "Failed to start tpm: %m");
+
log_debug_errno(r, "Failed to start tpm, ignoring: %m");
}
}
- if (tpm_state_tempdir) {
- _cleanup_free_ char *escaped_state_dir = NULL;
-
- escaped_state_dir = escape_qemu_value(tpm_state_tempdir);
- if (!escaped_state_dir)
- log_oom();
-
- r = strv_extend(&cmdline, "-chardev");
- if (r < 0)
+ if (tpm_socket_address) {
+ _cleanup_free_ char *escaped_tpm_socket_address = escape_qemu_value(tpm_socket_address);
+ if (!escaped_tpm_socket_address)
return log_oom();
- r = strv_extendf(&cmdline, "socket,id=chrtpm,path=%s/sock", escaped_state_dir);
- if (r < 0)
+ if (strv_extend(&cmdline, "-chardev") < 0)
return log_oom();
- r = strv_extend_many(&cmdline, "-tpmdev", "emulator,id=tpm0,chardev=chrtpm");
- if (r < 0)
+ if (strv_extendf(&cmdline, "socket,id=chrtpm,path=%s", tpm_socket_address) < 0)
+ return log_oom();
+
+ if (strv_extend_many(&cmdline, "-tpmdev", "emulator,id=tpm0,chardev=chrtpm") < 0)
return log_oom();
if (native_architecture() == ARCHITECTURE_X86_64)
@@ -2165,7 +2237,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
if (r < 0)
return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
- privkey_path = strjoin(arg_runtime_directory, "/", scope_prefix, "-", key_type);
+ privkey_path = strjoin(runtime_dir, "/", scope_prefix, "-", key_type);
if (!privkey_path)
return log_oom();