vmspawn: use fstab.extra credential for runtime mounts instead of kernel cmdline
Switch runtime virtiofs mount configuration from systemd.mount-extra=
kernel command line parameters to the fstab.extra credential. This
avoids consuming kernel command line space (which is limited) and
matches the approach used by mkosi.
Each mount is added as an fstab entry in the format:
{tag} {destination} virtiofs {ro|rw},x-initrd.mount
If the user already specified a fstab.extra credential via
--set-credential= or --load-credential=, the virtiofs mount entries
are appended to it rather than conflicting.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Daan De Meyer
parent
2371c9e798
commit
e98a26ddc0
+3
-3
@@ -447,10 +447,10 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl
|
||||
FLAGS_SET(flags, XESCAPE_FORCE_ELLIPSIS));
|
||||
}
|
||||
|
||||
char* octescape(const char *s, size_t len) {
|
||||
char* octescape_full(const char *s, size_t len, const char *bad) {
|
||||
char *buf, *t;
|
||||
|
||||
/* Escapes \ and " chars, in \nnn style escaping. */
|
||||
/* Escapes all chars in bad, in addition to \ and " chars, in \nnn octal style escaping. */
|
||||
|
||||
assert(s || len == 0);
|
||||
|
||||
@@ -467,7 +467,7 @@ char* octescape(const char *s, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uint8_t u = (uint8_t) s[i];
|
||||
|
||||
if (u < ' ' || u >= 127 || IN_SET(u, '\\', '"')) {
|
||||
if (u < ' ' || u >= 127 || IN_SET(u, '\\', '"') || (bad && strchr(bad, u))) {
|
||||
*(t++) = '\\';
|
||||
*(t++) = '0' + (u >> 6);
|
||||
*(t++) = '0' + ((u >> 3) & 7);
|
||||
|
||||
+4
-1
@@ -59,7 +59,10 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape
|
||||
static inline char* xescape(const char *s, const char *bad) {
|
||||
return xescape_full(s, bad, SIZE_MAX, 0);
|
||||
}
|
||||
char* octescape(const char *s, size_t len);
|
||||
char* octescape_full(const char *s, size_t len, const char *bad);
|
||||
static inline char* octescape(const char *s, size_t len) {
|
||||
return octescape_full(s, len, NULL);
|
||||
}
|
||||
char* decescape(const char *s, size_t len, const char *bad) _nonnull_if_nonzero_(1, 2);
|
||||
char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFlags flags);
|
||||
|
||||
|
||||
+30
-4
@@ -3033,6 +3033,8 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
_cleanup_free_ char *fstab_extra = NULL;
|
||||
|
||||
for (size_t j = 0; j < arg_runtime_mounts.n_mounts; j++) {
|
||||
RuntimeMount *m = arg_runtime_mounts.mounts + j;
|
||||
_cleanup_free_ char *listen_address = NULL;
|
||||
@@ -3079,15 +3081,39 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_free_ char *clean_target = xescape(m->target, "\":");
|
||||
if (!clean_target)
|
||||
/* fstab uses whitespace as field separator, so octal-escape spaces in paths */
|
||||
_cleanup_free_ char *escaped_target = octescape_full(m->target, SIZE_MAX, " \t");
|
||||
if (!escaped_target)
|
||||
return log_oom();
|
||||
|
||||
if (strv_extendf(&arg_kernel_cmdline_extra, "systemd.mount-extra=\"%s:%s:virtiofs:%s\"",
|
||||
id, clean_target, m->read_only ? "ro" : "rw") < 0)
|
||||
if (strextendf(&fstab_extra, "%s %s virtiofs %s,x-initrd.mount\n",
|
||||
id, escaped_target, m->read_only ? "ro" : "rw") < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (fstab_extra) {
|
||||
/* If the user already specified a fstab.extra credential, combine it with ours */
|
||||
MachineCredential *existing = machine_credential_find(&arg_credentials, "fstab.extra");
|
||||
if (existing) {
|
||||
_cleanup_free_ char *combined = NULL;
|
||||
|
||||
if (existing->size > 0 && existing->data[existing->size - 1] != '\n')
|
||||
r = asprintf(&combined, "%.*s\n%s", (int) existing->size, existing->data, fstab_extra);
|
||||
else
|
||||
r = asprintf(&combined, "%.*s%s", (int) existing->size, existing->data, fstab_extra);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
erase_and_free(existing->data);
|
||||
existing->data = TAKE_PTR(combined);
|
||||
existing->size = r;
|
||||
} else {
|
||||
r = machine_credential_add(&arg_credentials, "fstab.extra", fstab_extra, SIZE_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
_cleanup_(rm_rf_physical_and_freep) char *smbios_dir = NULL;
|
||||
r = mkdtemp_malloc("/var/tmp/vmspawn-smbios-XXXXXX", &smbios_dir);
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user