summaryrefslogtreecommitdiffstats
path: root/src/vmspawn
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2024-02-16 13:09:52 +0100
committerGitHub <noreply@github.com>2024-02-16 13:09:52 +0100
commit92d1419eb85ef630770ef22dbdf3521418ead134 (patch)
tree8110e0ce994dedd0bf103a40c11a2a3c389fa44b /src/vmspawn
parentvarlink: fix varlink_collect_full not resetting state (diff)
parentvmspawn: add --forward-journal= (diff)
downloadsystemd-92d1419eb85ef630770ef22dbdf3521418ead134.tar.xz
systemd-92d1419eb85ef630770ef22dbdf3521418ead134.zip
Merge pull request #31218 from CodethinkLabs/vmspawn/journal_forwarding
vmspawn: support journal forwarding
Diffstat (limited to 'src/vmspawn')
-rw-r--r--src/vmspawn/vmspawn.c110
1 files changed, 91 insertions, 19 deletions
diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c
index f3e2d1f6de..5e582079c7 100644
--- a/src/vmspawn/vmspawn.c
+++ b/src/vmspawn/vmspawn.c
@@ -82,6 +82,7 @@ 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 char **arg_kernel_cmdline_extra = NULL;
@@ -96,6 +97,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_firmware, freep);
STATIC_DESTRUCTOR_REGISTER(arg_linux, freep);
STATIC_DESTRUCTOR_REGISTER(arg_initrds, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_runtime_mounts, runtime_mount_context_done);
+STATIC_DESTRUCTOR_REGISTER(arg_forward_journal, freep);
STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline_extra, strv_freep);
static int help(void) {
@@ -145,6 +147,10 @@ static int help(void) {
" the VM.\n"
" --bind-ro=SOURCE[:TARGET]\n"
" Similar, but creates a read-only mount\n"
+ "\n%3$sIntegration:%4$s\n"
+ " --forward-journal=FILE|DIR\n"
+ " Forward the virtual machine's journal entries to\n"
+ " the host.\n"
"\n%3$sCredentials:%4$s\n"
" --set-credential=ID:VALUE\n"
" Pass a credential with literal value to the\n"
@@ -181,6 +187,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_BIND_RO,
ARG_SECURE_BOOT,
ARG_PRIVATE_USERS,
+ ARG_FORWARD_JOURNAL,
ARG_SET_CREDENTIAL,
ARG_LOAD_CREDENTIAL,
ARG_FIRMWARE,
@@ -209,6 +216,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "bind-ro", required_argument, NULL, ARG_BIND_RO },
{ "secure-boot", required_argument, NULL, ARG_SECURE_BOOT },
{ "private-users", required_argument, NULL, ARG_PRIVATE_USERS },
+ { "forward-journal", required_argument, NULL, ARG_FORWARD_JOURNAL },
{ "set-credential", required_argument, NULL, ARG_SET_CREDENTIAL },
{ "load-credential", required_argument, NULL, ARG_LOAD_CREDENTIAL },
{ "firmware", required_argument, NULL, ARG_FIRMWARE },
@@ -365,6 +373,12 @@ static int parse_argv(int argc, char *argv[]) {
return r;
break;
+ case ARG_FORWARD_JOURNAL:
+ r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_forward_journal);
+ if (r < 0)
+ return r;
+ break;
+
case ARG_SET_CREDENTIAL: {
r = machine_credential_set(&arg_credentials, optarg);
if (r < 0)
@@ -664,6 +678,45 @@ static int start_tpm(sd_bus *bus, const char *scope, const char *tpm, const char
return 0;
}
+static int start_systemd_journal_remote(sd_bus *bus, const char *scope, unsigned port, const char *sd_journal_remote, char **listen_address) {
+ _cleanup_free_ char *scope_prefix = NULL;
+ _cleanup_(socket_service_pair_done) SocketServicePair ssp = {
+ .socket_type = SOCK_STREAM,
+ };
+ int r;
+
+ assert(bus);
+ assert(scope);
+ assert(sd_journal_remote);
+
+ r = unit_name_to_prefix(scope, &scope_prefix);
+ if (r < 0)
+ return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
+
+ 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)
+ return log_oom();
+
+ ssp.exec_start = strv_new(sd_journal_remote,
+ "--output", arg_forward_journal,
+ "--split-mode", endswith(arg_forward_journal, ".journal") ? "none" : "host");
+ if (!ssp.exec_start)
+ return log_oom();
+
+ r = start_socket_service_pair(bus, scope, &ssp);
+ if (r < 0)
+ return r;
+
+ if (listen_address)
+ *listen_address = TAKE_PTR(ssp.listen_address);
+
+ return 0;
+}
+
static int discover_root(char **ret) {
int r;
_cleanup_(dissected_image_unrefp) DissectedImage *image = NULL;
@@ -1105,9 +1158,9 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
return log_oom();
_cleanup_close_ int child_vsock_fd = -EBADF;
+ unsigned child_cid = arg_vsock_cid;
if (use_vsock) {
int device_fd = vhost_device_fd;
- unsigned child_cid = arg_vsock_cid;
if (device_fd < 0) {
child_vsock_fd = open("/dev/vhost-vsock", O_RDWR|O_CLOEXEC);
@@ -1155,24 +1208,6 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
if (r < 0)
return log_oom();
- if (ARCHITECTURE_SUPPORTS_SMBIOS)
- FOREACH_ARRAY(cred, arg_credentials.credentials, arg_credentials.n_credentials) {
- _cleanup_free_ char *cred_data_b64 = NULL;
- ssize_t n;
-
- n = base64mem(cred->data, cred->size, &cred_data_b64);
- if (n < 0)
- return log_oom();
-
- r = strv_extend(&cmdline, "-smbios");
- if (r < 0)
- return log_oom();
-
- r = strv_extendf(&cmdline, "type=11,value=io.systemd.credential.binary:%s=%s", cred->id, cred_data_b64);
- if (r < 0)
- return log_oom();
- }
-
r = strv_extend(&cmdline, "-drive");
if (r < 0)
return log_oom();
@@ -1411,6 +1446,43 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
return log_oom();
}
+ if (arg_forward_journal) {
+ _cleanup_free_ char *sd_journal_remote = NULL, *listen_address = NULL, *cred = NULL;
+ r = find_executable("systemd-journal-remote", &sd_journal_remote);
+ if (r < 0)
+ return log_error_errno(r, "Failed to find systemd-journal-remote binary: %m");
+
+ r = start_systemd_journal_remote(bus, trans_scope, child_cid, sd_journal_remote, &listen_address);
+ if (r < 0)
+ return r;
+
+ cred = strjoin("journal.forward_to_socket:", listen_address);
+ if (!cred)
+ return log_oom();
+
+ r = machine_credential_set(&arg_credentials, cred);
+ if (r < 0)
+ return r;
+ }
+
+ if (ARCHITECTURE_SUPPORTS_SMBIOS)
+ FOREACH_ARRAY(cred, arg_credentials.credentials, arg_credentials.n_credentials) {
+ _cleanup_free_ char *cred_data_b64 = NULL;
+ ssize_t n;
+
+ n = base64mem(cred->data, cred->size, &cred_data_b64);
+ if (n < 0)
+ return log_oom();
+
+ r = strv_extend(&cmdline, "-smbios");
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&cmdline, "type=11,value=io.systemd.credential.binary:%s=%s", cred->id, cred_data_b64);
+ if (r < 0)
+ return log_oom();
+ }
+
if (use_vsock) {
notify_sock_fd = open_vsock();
if (notify_sock_fd < 0)