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);
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);
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);
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;
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)