1
0
mirror of https://github.com/systemd/systemd synced 2026-02-26 17:24:47 +01:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Mike Yuan
bd7ba0a645
parse-argument: make parse_tristate_argument() do something useful (#40652)
Alternative to #37751
2026-02-21 03:10:00 +01:00
Mike Yuan
f04023d35f
vmspawn: clean up OVMF secure boot support check a bit
find_ovmf_config() would do filtering based on arg_secure_boot
already, hence the mismatch can only occur if we're using
user-specified firmware. So be explicit about this in log.
2026-02-20 21:21:01 +01:00
Mike Yuan
39a5b957e1
vmspawn: use parse_tristate_argument_with_auto() 2026-02-20 21:21:01 +01:00
Mike Yuan
577e5e9a5e
parse-argument: make parse_tristate_argument() do something useful
I expressed the issue I have with parse_tristate_argument()
in #37751: it doesn't add any value to direct use of parse_tristate();
on the contrary, it doesn't support means to reset the arg to "auto"/-1 state.
The mere reason it existed is that we need a int type ret param.

Since the previous attempt to address this mess failed, let's
try to make the function more useful by making it accept "auto".
I figure this is useful on its own.

As requested in
https://github.com/systemd/systemd/pull/40652#discussion_r2831833996,
the function name is suffixed with _with_auto() to establish
that "auto" is handled internally.
2026-02-20 21:20:45 +01:00
11 changed files with 60 additions and 56 deletions

View File

@ -407,10 +407,11 @@
</varlistentry>
<varlistentry>
<term><option>--variables=yes|no</option></term>
<term><option>--variables=yes|no|auto</option></term>
<listitem><para>Controls whether to touch the firmware's boot loader list stored in EFI variables,
and other EFI variables. If not specified defaults to no when execution in a container runtime is
detected, yes otherwise.</para>
and other EFI variables. If not specified or set to <option>auto</option>, EFI variables will not
be modified when execution in a container runtime is detected. <option>yes</option> may be used to
explicit override the check.</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>

View File

@ -255,8 +255,9 @@
<term><option>--lightweight=<replaceable>BOOLEAN</replaceable></option></term>
<listitem><para>Controls whether to activate the per-user service manager for the target user. By
default if the target user is <literal>root</literal> or a system user the per-user service manager
is not activated as effect of the <command>run0</command> invocation, otherwise it is.</para>
default (unset or set to <option>auto</option>), if the target user is <literal>root</literal> or
a system user the per-user service manager is not activated as effect of the <command>run0</command>
invocation, otherwise it is.</para>
<para>This ultimately controls the <varname>$XDG_SESSION_CLASS</varname> environment variable
<citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>

View File

@ -555,10 +555,10 @@
<term><option>--copy-ownership=</option></term>
<listitem><para>Controls whether file ownership (user and group) is preserved when copying files
with <option>--copy-from</option> or <option>--copy-to</option>. Takes a boolean. If
<literal>yes</literal>, ownership is always preserved. If <literal>no</literal>, ownership is never
preserved and the current user's UID/GID is used instead. If not specified, ownership is preserved
when copying directory trees, but not when copying individual regular files.
with <option>--copy-from</option> or <option>--copy-to</option>. Takes a boolean, or <option>auto</option>.
If <literal>yes</literal>, ownership is always preserved. If <literal>no</literal>, ownership is never
preserved and the current user's UID/GID is used instead. If not specified or <option>auto</option>,
ownership is preserved when copying directory trees, but not when copying individual regular files.
</para>
<xi:include href="version-info.xml" xpointer="v260"/></listitem>

View File

@ -166,8 +166,8 @@
<varlistentry>
<term><option>--kvm=<replaceable>BOOL</replaceable></option></term>
<listitem><para>If <option>--kvm=</option> is not specified, KVM support will be
detected automatically. If true, KVM is always used, and if false, KVM is never used.</para>
<listitem><para>Controls whether to enable KVM acceleration. If not specified or set to <option>auto</option>,
KVM support will be detected automatically. If true, KVM is insisted on. If false, disable KVM.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
@ -175,8 +175,9 @@
<varlistentry>
<term><option>--vsock=<replaceable>BOOL</replaceable></option></term>
<listitem><para>If <option>--vsock=</option> is not specified, VSOCK networking support will be
detected automatically. If true, VSOCK networking is always used, and if false, VSOCK networking is never used.</para>
<listitem><para>Controls whether to allocate a VSOCK socket for guest. If not specified or set to
<option>auto</option>, VSOCK networking support will be detected automatically. If true, VSOCK
is insisted on. If false, VSOCK networking is disabled.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
@ -198,12 +199,10 @@
<term><option>--tpm=<replaceable>BOOL</replaceable></option></term>
<listitem>
<para>If <option>--tpm=</option> is not specified, vmspawn will detect the presence of <citerefentry project='debian'>
<refentrytitle>swtpm</refentrytitle><manvolnum>8</manvolnum></citerefentry> and use it if
available. If yes is specified <citerefentry
project='debian'><refentrytitle>swtpm</refentrytitle><manvolnum>8</manvolnum></citerefentry> is
always used, and if no is set <citerefentry project='debian'><refentrytitle>swtpm</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> is never used.</para>
<para>Controls whether to serve a TPM device for guest, via <citerefentry project='debian'>
<refentrytitle>swtpm</refentrytitle><manvolnum>8</manvolnum></citerefentry>. If not specified or
set to <option>auto</option>, vmspawn will detect the presence of swtpm binary automatically.
If yes, swtpm support is insisted on. If no, TPM is disabled.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
@ -311,9 +310,9 @@
<listitem><para>Configure whether to search for firmware which supports Secure Boot.</para>
<para>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.</para>
<para>If the option is not specified or set to <option>auto</option>, the first firmware 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.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>

View File

@ -521,7 +521,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_VARIABLES:
r = parse_tristate_argument("--variables=", optarg, &arg_touch_variables);
r = parse_tristate_argument_with_auto("--variables=", optarg, &arg_touch_variables);
if (r < 0)
return r;
break;

View File

@ -637,7 +637,7 @@ static int parse_argv(int argc, char *argv[]) {
}
case ARG_COPY_OWNERSHIP:
r = parse_tristate_argument("--copy-ownership=", optarg, &arg_copy_ownership);
r = parse_tristate_argument_with_auto("--copy-ownership=", optarg, &arg_copy_ownership);
if (r < 0)
return r;
break;

View File

@ -1083,7 +1083,7 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
break;
case ARG_LIGHTWEIGHT:
r = parse_tristate_argument("--lightweight=", optarg, &arg_lightweight);
r = parse_tristate_argument_with_auto("--lightweight=", optarg, &arg_lightweight);
if (r < 0)
return r;
break;

View File

@ -20,10 +20,12 @@ int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
/* Returns the result through *ret and the return value. */
assert(optname);
if (s) {
r = parse_boolean(s);
if (r < 0)
return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
return log_error_errno(r, "Failed to parse boolean argument to '%s': %s", optname, s);
if (ret)
*ret = r;
@ -36,24 +38,20 @@ int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
}
}
int parse_tristate_argument(const char *optname, const char *s, int *ret) {
int parse_tristate_argument_with_auto(const char *optname, const char *s, int *ret) {
int r;
if (s) {
r = parse_boolean(s);
if (r < 0)
return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
assert(optname);
assert(s); /* We refuse NULL optarg here, since that would be ambiguous on cmdline:
for --enable-a[=BOOL], --enable-a is intuitively interpreted as true rather than "auto"
(parse_boolean_argument() does exactly that). IOW, tristate options should require
arguments. */
if (ret)
*ret = r;
r = parse_tristate_full(s, "auto", ret);
if (r < 0)
return log_error_errno(r, "Failed to parse tristate argument to '%s': %s", optname, s);
return r;
} else {
if (ret)
*ret = -1;
return 0;
}
return 0;
}
int parse_json_argument(const char *s, sd_json_format_flags_t *ret) {

View File

@ -4,7 +4,7 @@
#include "shared-forward.h"
int parse_boolean_argument(const char *optname, const char *s, bool *ret);
int parse_tristate_argument(const char *optname, const char *s, int *ret);
int parse_tristate_argument_with_auto(const char *optname, const char *s, int *ret);
int parse_json_argument(const char *s, sd_json_format_flags_t *ret);
int parse_path_argument(const char *path, bool suppress_root, char **arg);
int parse_signal_argument(const char *s, int *ret);

View File

@ -830,9 +830,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_CHECK_INHIBITORS:
r = parse_tristate_full(optarg, "auto", &arg_check_inhibitors);
r = parse_tristate_argument_with_auto("--check-inhibitors=", optarg, &arg_check_inhibitors);
if (r < 0)
return log_error_errno(r, "Failed to parse --check-inhibitors= argument: %s", optarg);
return r;
break;
case ARG_PLAIN:

View File

@ -455,15 +455,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_KVM:
r = parse_tristate(optarg, &arg_kvm);
r = parse_tristate_argument_with_auto("--kvm=", optarg, &arg_kvm);
if (r < 0)
return log_error_errno(r, "Failed to parse --kvm=%s: %m", optarg);
return r;
break;
case ARG_VSOCK:
r = parse_tristate(optarg, &arg_vsock);
r = parse_tristate_argument_with_auto("--vsock=", optarg, &arg_vsock);
if (r < 0)
return log_error_errno(r, "Failed to parse --vsock=%s: %m", optarg);
return r;
break;
case ARG_VSOCK_CID:
@ -483,9 +483,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_TPM:
r = parse_tristate(optarg, &arg_tpm);
r = parse_tristate_argument_with_auto("--tpm=", optarg, &arg_tpm);
if (r < 0)
return log_error_errno(r, "Failed to parse --tpm=%s: %m", optarg);
return r;
break;
case ARG_LINUX:
@ -587,9 +587,9 @@ static int parse_argv(int argc, char *argv[]) {
}
case ARG_SECURE_BOOT:
r = parse_tristate(optarg, &arg_secure_boot);
r = parse_tristate_argument_with_auto("--secure-boot=", optarg, &arg_secure_boot);
if (r < 0)
return log_error_errno(r, "Failed to parse --secure-boot=%s: %m", optarg);
return r;
break;
case ARG_PRIVATE_USERS:
@ -1915,6 +1915,16 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
if (r < 0)
return log_error_errno(r, "Failed to find OVMF config: %m");
if (arg_secure_boot > 0 && !ovmf_config->supports_sb) {
assert(arg_firmware);
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE),
"Secure Boot requested, but supplied OVMF firmware blob doesn't support it.");
}
if (arg_secure_boot < 0)
log_debug("Using OVMF firmware %s Secure Boot support.", ovmf_config->supports_sb ? "with" : "without");
_cleanup_(machine_bind_user_context_freep) MachineBindUserContext *bind_user_context = NULL;
r = machine_bind_user_prepare(
/* directory= */ NULL,
@ -1931,11 +1941,6 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
if (r < 0)
return r;
/* only warn if the user hasn't disabled secureboot */
if (!ovmf_config->supports_sb && arg_secure_boot)
log_warning("Couldn't find OVMF firmware blob with Secure Boot support, "
"falling back to OVMF firmware blobs without Secure Boot support.");
_cleanup_free_ char *machine = NULL;
const char *shm = arg_directory || arg_runtime_mounts.n_mounts != 0 ? ",memory-backend=mem" : "";
const char *hpet = ARCHITECTURE_SUPPORTS_HPET ? ",hpet=off" : "";