vmspawn: by default, let machined register a cgroup for VMs

This mimics what we do in nspawn: if registration is enabled we'll let
machined allocate a scope unit for us. When --keep-unit is used we'll
register without creating a new scope.

This brings behaviour more inline with what nspawn does, exposing the
same sets of options.
This commit is contained in:
Lennart Poettering 2024-05-27 13:30:31 +02:00
parent e16be05858
commit ecc4287dee
4 changed files with 24 additions and 5 deletions

View file

@ -22,7 +22,8 @@ int register_machine(
const char *directory,
unsigned cid,
const char *address,
const char *key_path) {
const char *key_path,
bool keep_unit) {
_cleanup_(varlink_unrefp) Varlink *vl = NULL;
int r;
@ -71,7 +72,8 @@ int register_machine(
SD_JSON_BUILD_PAIR_CONDITION(!!directory, "rootDirectory", SD_JSON_BUILD_STRING(directory)),
SD_JSON_BUILD_PAIR_CONDITION(!!address, "sshAddress", SD_JSON_BUILD_STRING(address)),
SD_JSON_BUILD_PAIR_CONDITION(!!key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(key_path)),
SD_JSON_BUILD_PAIR_CONDITION(isatty(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)));
SD_JSON_BUILD_PAIR_CONDITION(isatty(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)),
SD_JSON_BUILD_PAIR_CONDITION(!keep_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)));
}
int unregister_machine(sd_bus *bus, const char *machine_name) {

View file

@ -11,5 +11,7 @@ int register_machine(
const char *directory,
unsigned cid,
const char *address,
const char *key_path);
const char *key_path,
bool keep_unit);
int unregister_machine(sd_bus *bus, const char *machine_name);

View file

@ -107,6 +107,7 @@ 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;
static sd_id128_t arg_uuid = {};
static char **arg_kernel_cmdline_extra = NULL;
static char **arg_extra_drives = NULL;
@ -170,6 +171,7 @@ static int help(void) {
" --uuid=UUID Set a specific machine UUID for the VM\n"
"\n%3$sProperties:%4$s\n"
" --register=BOOLEAN Register VM with systemd-machined\n"
" --keep-unit Don't let systemd-machined allocate scope unit for us\n"
"\n%3$sUser Namespacing:%4$s\n"
" --private-users=UIDBASE[:NUIDS]\n"
" Configure the UID/GID range to map into the\n"
@ -235,6 +237,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NETWORK_USER_MODE,
ARG_UUID,
ARG_REGISTER,
ARG_KEEP_UNIT,
ARG_BIND,
ARG_BIND_RO,
ARG_EXTRA_DRIVE,
@ -277,6 +280,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "network-user-mode", no_argument, NULL, ARG_NETWORK_USER_MODE },
{ "uuid", required_argument, NULL, ARG_UUID },
{ "register", required_argument, NULL, ARG_REGISTER },
{ "keep-unit", no_argument, NULL, ARG_KEEP_UNIT },
{ "bind", required_argument, NULL, ARG_BIND },
{ "bind-ro", required_argument, NULL, ARG_BIND_RO },
{ "extra-drive", required_argument, NULL, ARG_EXTRA_DRIVE },
@ -443,6 +447,11 @@ static int parse_argv(int argc, char *argv[]) {
r = parse_boolean_argument("--register=", optarg, &arg_register);
if (r < 0)
return r;
break;
case ARG_KEEP_UNIT:
arg_keep_unit = true;
break;
case ARG_BIND:
@ -2055,7 +2064,8 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
arg_directory,
child_cid,
child_cid != VMADDR_CID_ANY ? vm_address : NULL,
ssh_private_key_path);
ssh_private_key_path,
arg_keep_unit);
if (r < 0)
return r;
}
@ -2229,6 +2239,11 @@ static int verify_arguments(void) {
if (!strv_isempty(arg_initrds) && !arg_linux)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --initrd= cannot be used without --linux=.");
if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0)
/* Save the user from accidentally registering either user-$SESSION.scope or user@.service.
* The latter is not technically a user session, but we don't need to labour the point. */
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--keep-unit --register=yes may not be used when invoked from a user session.");
return 0;
}

View file

@ -84,7 +84,7 @@ if ! systemd-detect-virt -c; then
-p DelegateSubgroup=supervisor \
-p Environment=SYSTEMD_LOG_LEVEL=debug \
--wait -- \
systemd-nspawn --keep-unit -i /var/tmp/unpriv.raw --read-only --pipe echo thisisatest >/tmp/unpriv.out2
systemd-nspawn --keep-unit --register=no -i /var/tmp/unpriv.raw --read-only --pipe echo thisisatest >/tmp/unpriv.out2
echo thisisatest | cmp /tmp/unpriv.out2 -
fi