X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fmachine%2Fmachined-dbus.c;h=d0cc07678fa25e4193c1590dbef32fbace3bf7f2;hb=269e4d2d6b75329ae39a71ebe2c14500e03cda95;hp=42ad47dc5317b8cc56553282f8ad57f35d21d1c6;hpb=b667d50d3443be7fd861d319b5acd525aa15329c;p=thirdparty%2Fsystemd.git diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 42ad47dc531..d0cc07678fa 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -1,12 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2011 Lennart Poettering -***/ #include -#include #include #include "sd-id128.h" @@ -14,8 +8,10 @@ #include "alloc-util.h" #include "btrfs-util.h" #include "bus-common-errors.h" +#include "bus-polkit.h" #include "bus-util.h" #include "cgroup-util.h" +#include "errno-util.h" #include "fd-util.h" #include "fileio.h" #include "format-util.h" @@ -26,27 +22,16 @@ #include "machine-image.h" #include "machine-pool.h" #include "machined.h" +#include "missing_capability.h" #include "path-util.h" #include "process-util.h" #include "stdio-util.h" #include "strv.h" +#include "tmpfile-util.h" #include "unit-name.h" #include "user-util.h" -static int property_get_pool_path( - sd_bus *bus, - const char *path, - const char *interface, - const char *property, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error) { - - assert(bus); - assert(reply); - - return sd_bus_message_append(reply, "s", "/var/lib/machines"); -} +static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_pool_path, "s", "/var/lib/machines"); static int property_get_pool_usage( sd_bus *bus, @@ -59,15 +44,10 @@ static int property_get_pool_usage( _cleanup_close_ int fd = -1; uint64_t usage = (uint64_t) -1; - struct stat st; assert(bus); assert(reply); - /* We try to read the quota info from /var/lib/machines, as - * well as the usage of the loopback file - * /var/lib/machines.raw, and pick the larger value. */ - fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY); if (fd >= 0) { BtrfsQuotaInfo q; @@ -76,11 +56,6 @@ static int property_get_pool_usage( usage = q.referenced; } - if (stat("/var/lib/machines.raw", &st) >= 0) { - if (usage == (uint64_t) -1 || st.st_blocks * 512ULL > usage) - usage = st.st_blocks * 512ULL; - } - return sd_bus_message_append(reply, "t", usage); } @@ -95,15 +70,10 @@ static int property_get_pool_limit( _cleanup_close_ int fd = -1; uint64_t size = (uint64_t) -1; - struct stat st; assert(bus); assert(reply); - /* We try to read the quota limit from /var/lib/machines, as - * well as the size of the loopback file - * /var/lib/machines.raw, and pick the smaller value. */ - fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY); if (fd >= 0) { BtrfsQuotaInfo q; @@ -112,11 +82,6 @@ static int property_get_pool_limit( size = q.referenced_max; } - if (stat("/var/lib/machines.raw", &st) >= 0) { - if (size == (uint64_t) -1 || (uint64_t) st.st_size < size) - size = st.st_size; - } - return sd_bus_message_append(reply, "t", size); } @@ -158,8 +123,8 @@ static int method_get_image(sd_bus_message *message, void *userdata, sd_bus_erro if (r < 0) return r; - r = image_find(name, NULL); - if (r == 0) + r = image_find(IMAGE_MACHINE, name, NULL); + if (r == -ENOENT) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); if (r < 0) return r; @@ -463,14 +428,14 @@ static int method_register_machine(sd_bus_message *message, void *userdata, sd_b return method_register_machine_internal(message, false, userdata, error); } -static int method_terminate_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; +static int redirect_method_to_machine(sd_bus_message *message, Manager *m, sd_bus_error *error, sd_bus_message_handler_t method) { Machine *machine; const char *name; int r; assert(message); assert(m); + assert(method); r = sd_bus_message_read(message, "s", &name); if (r < 0) @@ -480,72 +445,32 @@ static int method_terminate_machine(sd_bus_message *message, void *userdata, sd_ if (!machine) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - return bus_machine_method_terminate(message, machine, error); + return method(message, machine, error); } -static int method_kill_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return sd_bus_error_set_errno(error, r); +static int method_unregister_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { + return redirect_method_to_machine(message, userdata, error, bus_machine_method_unregister); +} - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); +static int method_terminate_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { + return redirect_method_to_machine(message, userdata, error, bus_machine_method_terminate); +} - return bus_machine_method_kill(message, machine, error); +static int method_kill_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { + return redirect_method_to_machine(message, userdata, error, bus_machine_method_kill); } static int method_get_machine_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return sd_bus_error_set_errno(error, r); - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_get_addresses(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_get_addresses); } static int method_get_machine_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return sd_bus_error_set_errno(error, r); - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_get_os_release(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_get_os_release); } static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - _cleanup_(image_hashmap_freep) Hashmap *images = NULL; + _cleanup_hashmap_free_ Hashmap *images = NULL; Manager *m = userdata; Image *image; Iterator i; @@ -554,11 +479,11 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er assert(message); assert(m); - images = hashmap_new(&string_hash_ops); + images = hashmap_new(&image_hash_ops); if (!images) return -ENOMEM; - r = image_discover(images); + r = image_discover(IMAGE_MACHINE, images); if (r < 0) return r; @@ -597,152 +522,41 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er } static int method_open_machine_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return sd_bus_error_set_errno(error, r); - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_open_pty(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_open_pty); } static int method_open_machine_login(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_open_login(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_open_login); } static int method_open_machine_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_open_shell(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_open_shell); } static int method_bind_mount_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_bind_mount(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_bind_mount); } static int method_copy_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_copy(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_copy); } static int method_open_machine_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_open_root_directory(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_open_root_directory); } static int method_get_machine_uid_shift(sd_bus_message *message, void *userdata, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - const char *name; - int r; - - assert(message); - assert(m); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - machine = hashmap_get(m->machines, name); - if (!machine) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name); - - return bus_machine_method_get_uid_shift(message, machine, error); + return redirect_method_to_machine(message, userdata, error, bus_machine_method_get_uid_shift); } -static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) { +static int redirect_method_to_image(sd_bus_message *message, Manager *m, sd_bus_error *error, sd_bus_message_handler_t method) { _cleanup_(image_unrefp) Image* i = NULL; const char *name; int r; assert(message); + assert(m); + assert(method); r = sd_bus_message_read(message, "s", &name); if (r < 0) @@ -751,182 +565,46 @@ static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_e if (!image_name_is_valid(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) + r = image_find(IMAGE_MACHINE, name, &i); + if (r == -ENOENT) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_remove(message, i, error); -} - -static int method_rename_image(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image* i = NULL; - const char *old_name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &old_name); if (r < 0) return r; - if (!image_name_is_valid(old_name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name); + i->userdata = m; + return method(message, i, error); +} - r = image_find(old_name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name); +static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) { + return redirect_method_to_image(message, userdata, error, bus_image_method_remove); +} - i->userdata = userdata; - return bus_image_method_rename(message, i, error); +static int method_rename_image(sd_bus_message *message, void *userdata, sd_bus_error *error) { + return redirect_method_to_image(message, userdata, error, bus_image_method_rename); } static int method_clone_image(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *old_name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &old_name); - if (r < 0) - return r; - - if (!image_name_is_valid(old_name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name); - - r = image_find(old_name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name); - - i->userdata = userdata; - return bus_image_method_clone(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_clone); } static int method_mark_image_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - if (!image_name_is_valid(name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_mark_read_only(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_mark_read_only); } static int method_get_image_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - if (!image_name_is_valid(name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_get_hostname(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_get_hostname); } static int method_get_image_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - if (!image_name_is_valid(name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_get_machine_id(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_get_machine_id); } static int method_get_image_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - if (!image_name_is_valid(name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_get_machine_info(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_get_machine_info); } static int method_get_image_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - if (!image_name_is_valid(name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_get_os_release(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_get_os_release); } static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) { @@ -942,7 +620,7 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) { if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1) return -errno; - f = fdopen(operation->extra_fd, "re"); + f = fdopen(operation->extra_fd, "r"); if (!f) return -errno; @@ -952,7 +630,7 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) { errno = 0; n = fread(&success, 1, sizeof(success), f); if (n != sizeof(success)) - return ret < 0 ? ret : (errno != 0 ? -errno : -EIO); + return ret < 0 ? ret : errno_or_else(EIO); if (ret < 0) { _cleanup_free_ char *name = NULL; @@ -964,8 +642,8 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) { if (success) /* The resulting temporary file could not be updated, ignore it. */ return ret; - r = read_nul_string(f, &name); - if (r < 0 || isempty(name)) /* Same here... */ + r = read_nul_string(f, LONG_LINE_MAX, &name); + if (r <= 0) /* Same here... */ return ret; return sd_bus_error_set_errnof(error, ret, "Failed to remove image %s: %m", name); @@ -987,16 +665,16 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) { _cleanup_free_ char *name = NULL; uint64_t size; - r = read_nul_string(f, &name); + r = read_nul_string(f, LONG_LINE_MAX, &name); if (r < 0) return r; - if (isempty(name)) /* reached the end */ + if (r == 0) /* reached the end */ break; errno = 0; n = fread(&size, 1, sizeof(size), f); if (n != sizeof(size)) - return errno != 0 ? -errno : -EIO; + return errno_or_else(EIO); r = sd_bus_message_append(reply, "(st)", name, size); if (r < 0) @@ -1069,7 +747,7 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); if (r == 0) { - _cleanup_(image_hashmap_freep) Hashmap *images = NULL; + _cleanup_hashmap_free_ Hashmap *images = NULL; bool success = true; Image *image; Iterator i; @@ -1077,13 +755,13 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); - images = hashmap_new(&string_hash_ops); + images = hashmap_new(&image_hash_ops); if (!images) { r = -ENOMEM; goto child_fail; } - r = image_discover(images); + r = image_discover(IMAGE_MACHINE, images); if (r < 0) goto child_fail; @@ -1186,19 +864,10 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus return 1; /* Will call us back */ /* Set up the machine directory if necessary */ - r = setup_machine_directory(limit, error); + r = setup_machine_directory(error); if (r < 0) return r; - /* Resize the backing loopback device, if there is one, except if we asked to drop any limit */ - if (limit != (uint64_t) -1) { - r = btrfs_resize_loopback("/var/lib/machines", limit, false); - if (r == -ENOTTY) - return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs."); - if (r < 0 && r != -ENODEV) /* ignore ENODEV, as that's what is returned if the file system is not on loopback */ - return sd_bus_error_set_errnof(error, r, "Failed to adjust loopback limit: %m"); - } - (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit); r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit); @@ -1211,27 +880,7 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus } static int method_set_image_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *i = NULL; - const char *name; - int r; - - assert(message); - - r = sd_bus_message_read(message, "s", &name); - if (r < 0) - return r; - - if (!image_name_is_valid(name)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name); - - r = image_find(name, &i); - if (r < 0) - return r; - if (r == 0) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); - - i->userdata = userdata; - return bus_image_method_set_limit(message, i, error); + return redirect_method_to_image(message, userdata, error, bus_image_method_set_limit); } static int method_map_from_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -1270,8 +919,8 @@ static int method_map_from_machine_user(sd_bus_message *message, void *userdata, if (k < 0 && feof(f)) break; if (k != 3) { - if (ferror(f) && errno > 0) - return -errno; + if (ferror(f)) + return errno_or_else(EIO); return -EIO; } @@ -1328,12 +977,16 @@ static int method_map_to_machine_user(sd_bus_message *message, void *userdata, s if (k < 0 && feof(f)) break; if (k != 3) { - if (ferror(f) && errno > 0) - return -errno; + if (ferror(f)) + return errno_or_else(EIO); return -EIO; } + /* The private user namespace is disabled, ignoring. */ + if (uid_shift == 0) + continue; + if (uid < uid_shift || uid >= uid_shift + uid_range) continue; @@ -1388,8 +1041,8 @@ static int method_map_from_machine_group(sd_bus_message *message, void *groupdat if (k < 0 && feof(f)) break; if (k != 3) { - if (ferror(f) && errno > 0) - return -errno; + if (ferror(f)) + return errno_or_else(EIO); return -EIO; } @@ -1446,12 +1099,16 @@ static int method_map_to_machine_group(sd_bus_message *message, void *groupdata, if (k < 0 && feof(f)) break; if (k != 3) { - if (ferror(f) && errno > 0) - return -errno; + if (ferror(f)) + return errno_or_else(EIO); return -EIO; } + /* The private user namespace is disabled, ignoring. */ + if (gid_shift == 0) + continue; + if (gid < gid_shift || gid >= gid_shift + gid_range) continue; @@ -1484,6 +1141,7 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0), SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0), SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0), + SD_BUS_METHOD("UnregisterMachine", "s", NULL, method_unregister_machine, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED), @@ -1637,99 +1295,24 @@ int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error return 0; } -int manager_start_scope( - Manager *manager, - const char *scope, - pid_t pid, - const char *slice, - const char *description, - sd_bus_message *more_properties, - sd_bus_error *error, - char **job) { - - _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; - int r; +int manager_unref_unit( + Manager *m, + const char *unit, + sd_bus_error *error) { - assert(manager); - assert(scope); - assert(pid > 1); + assert(m); + assert(unit); - r = sd_bus_message_new_method_call( - manager->bus, - &m, + return sd_bus_call_method( + m->bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "StartTransientUnit"); - if (r < 0) - return r; - - r = sd_bus_message_append(m, "ss", strempty(scope), "fail"); - if (r < 0) - return r; - - r = sd_bus_message_open_container(m, 'a', "(sv)"); - if (r < 0) - return r; - - if (!isempty(slice)) { - r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); - if (r < 0) - return r; - } - - if (!isempty(description)) { - r = sd_bus_message_append(m, "(sv)", "Description", "s", description); - if (r < 0) - return r; - } - - r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid); - if (r < 0) - return r; - - r = sd_bus_message_append(m, "(sv)", "Delegate", "b", 1); - if (r < 0) - return r; - - r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", UINT64_C(16384)); - if (r < 0) - return bus_log_create_error(r); - - if (more_properties) { - r = sd_bus_message_copy(m, more_properties, true); - if (r < 0) - return r; - } - - r = sd_bus_message_close_container(m); - if (r < 0) - return r; - - r = sd_bus_message_append(m, "a(sa(sv))", 0); - if (r < 0) - return r; - - r = sd_bus_call(manager->bus, m, 0, error, &reply); - if (r < 0) - return r; - - if (job) { - const char *j; - char *copy; - - r = sd_bus_message_read(reply, "o", &j); - if (r < 0) - return r; - - copy = strdup(j); - if (!copy) - return -ENOMEM; - - *job = copy; - } - - return 1; + "UnrefUnit", + error, + NULL, + "s", + unit); } int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) { @@ -1912,30 +1495,3 @@ int manager_add_machine(Manager *m, const char *name, Machine **_machine) { return 0; } - -int bus_reply_pair_array(sd_bus_message *m, char **l) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - char **k, **v; - int r; - - r = sd_bus_message_new_method_return(m, &reply); - if (r < 0) - return r; - - r = sd_bus_message_open_container(reply, 'a', "{ss}"); - if (r < 0) - return r; - - STRV_FOREACH_PAIR(k, v, l) { - r = sd_bus_message_append(reply, "{ss}", *k, *v); - if (r < 0) - return r; - } - - r = sd_bus_message_close_container(reply); - if (r < 0) - return r; - - return sd_bus_send(NULL, reply, NULL); - -}