diff options
author | Lennart Poettering <lennart@poettering.net> | 2025-01-15 16:52:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-15 16:52:24 +0100 |
commit | fc6192f52b272a82a78347651fb44d9ace705e22 (patch) | |
tree | 181fa6bb321691c9a59afb18ab43e382980829f3 /src | |
parent | nspawn: trivial scope reduction (diff) | |
parent | machine: tests for io.systemd.MachineImage.SetPoolLimit (diff) | |
download | systemd-fc6192f52b272a82a78347651fb44d9ace705e22.tar.xz systemd-fc6192f52b272a82a78347651fb44d9ace705e22.zip |
machine: introduce io.systemd.MachineImage.SetPoolLimit (#35953)
This PR introduces io.systemd.MachineImage.SetPoolLimit method which is
alternative to DBus's SetPoolLimit.
This is last function for org.freedesktop.machine1 Dbus interface
Diffstat (limited to 'src')
-rw-r--r-- | src/machine/image-varlink.c | 47 | ||||
-rw-r--r-- | src/machine/image-varlink.h | 2 | ||||
-rw-r--r-- | src/machine/machined-dbus.c | 6 | ||||
-rw-r--r-- | src/machine/machined-varlink.c | 3 | ||||
-rw-r--r-- | src/shared/discover-image.c | 23 | ||||
-rw-r--r-- | src/shared/discover-image.h | 1 | ||||
-rw-r--r-- | src/shared/varlink-io.systemd.MachineImage.c | 15 |
7 files changed, 90 insertions, 7 deletions
diff --git a/src/machine/image-varlink.c b/src/machine/image-varlink.c index 4a4f611bda..0e616da9d1 100644 --- a/src/machine/image-varlink.c +++ b/src/machine/image-varlink.c @@ -4,9 +4,12 @@ #include "sd-varlink.h" #include "bus-polkit.h" +#include "btrfs-util.h" #include "fd-util.h" #include "image-varlink.h" +#include "io-util.h" #include "machine.h" +#include "machine-pool.h" #include "string-util.h" typedef struct ImageUpdateParameters { @@ -230,3 +233,47 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var TAKE_FD(errno_pipe_fd[0]); return 1; } + +int vl_method_set_pool_limit(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + static const sd_json_dispatch_field dispatch_table[] = { + { "limit", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, 0, SD_JSON_MANDATORY }, + VARLINK_DISPATCH_POLKIT_FIELD, + {} + }; + + Manager *manager = ASSERT_PTR(userdata); + uint64_t limit; + int r; + + assert(link); + assert(parameters); + + r = sd_varlink_dispatch(link, parameters, dispatch_table, &limit); + if (r != 0) + return r; + + if (!FILE_SIZE_VALID_OR_INFINITY(limit)) + return sd_varlink_error_invalid_parameter_name(link, "limit"); + + r = varlink_verify_polkit_async( + link, + manager->bus, + "org.freedesktop.machine1.manage-images", + (const char**) STRV_MAKE("verb", "set_pool_limit"), + &manager->polkit_registry); + if (r <= 0) + return r; + + /* Set up the machine directory if necessary */ + r = setup_machine_directory(/* error = */ NULL, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true); + if (r < 0) + return r; + + r = image_set_pool_limit(IMAGE_MACHINE, limit); + if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED, NULL); + if (r < 0) + return r; + + return sd_varlink_reply(link, NULL); +} diff --git a/src/machine/image-varlink.h b/src/machine/image-varlink.h index 7f68fe86fb..5d94edf678 100644 --- a/src/machine/image-varlink.h +++ b/src/machine/image-varlink.h @@ -5,7 +5,9 @@ #define VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE "io.systemd.MachineImage.NoSuchImage" #define VARLINK_ERROR_MACHINE_IMAGE_TOO_MANY_OPERATIONS "io.systemd.MachineImage.TooManyOperations" +#define VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED "io.systemd.MachineImage.NotSupported" int vl_method_update_image(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); +int vl_method_set_pool_limit(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index e50ed7e0df..660839f9c1 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -863,10 +863,8 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus if (r < 0) return r; - (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit); - - r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit); - if (r == -ENOTTY) + r = image_set_pool_limit(IMAGE_MACHINE, limit); + if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs."); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to adjust quota limit: %m"); diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index 72ded672dc..dc293f5895 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -797,7 +797,8 @@ static int manager_varlink_init_machine(Manager *m) { "io.systemd.MachineImage.List", vl_method_list_images, "io.systemd.MachineImage.Update", vl_method_update_image, "io.systemd.MachineImage.Clone", vl_method_clone_image, - "io.systemd.MachineImage.Remove", vl_method_remove_image); + "io.systemd.MachineImage.Remove", vl_method_remove_image, + "io.systemd.MachineImage.SetPoolLimit", vl_method_set_pool_limit); if (r < 0) return log_error_errno(r, "Failed to register varlink methods: %m"); diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 53e9821412..e2f05dca93 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1590,6 +1590,29 @@ int image_set_limit(Image *i, uint64_t referenced_max) { return 0; } +int image_set_pool_limit(ImageClass class, uint64_t referenced_max) { + const char *dir; + int r; + + assert(class >= 0 && class < _IMAGE_CLASS_MAX); + + dir = image_root_to_string(class); + + r = btrfs_qgroup_set_limit(dir, /* qgroupid = */ 0, referenced_max); + if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return r; + if (r < 0) + log_debug_errno(r, "Failed to set limit on btrfs quota group for '%s', ignoring: %m", dir); + + r = btrfs_subvol_set_subtree_quota_limit(dir, /* subvol_id = */ 0, referenced_max); + if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return r; + if (r < 0) + return log_debug_errno(r, "Failed to set subtree quota limit for '%s': %m", dir); + + return 0; +} + int image_read_metadata(Image *i, const ImagePolicy *image_policy) { _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT; int r; diff --git a/src/shared/discover-image.h b/src/shared/discover-image.h index c1fdf15d15..c64d0baefb 100644 --- a/src/shared/discover-image.h +++ b/src/shared/discover-image.h @@ -78,6 +78,7 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile int image_name_lock(const char *name, int operation, LockFile *ret); int image_set_limit(Image *i, uint64_t referenced_max); +int image_set_pool_limit(ImageClass class, uint64_t referenced_max); int image_read_metadata(Image *i, const ImagePolicy *image_policy); diff --git a/src/shared/varlink-io.systemd.MachineImage.c b/src/shared/varlink-io.systemd.MachineImage.c index 813b6c8e68..8e9d90fe70 100644 --- a/src/shared/varlink-io.systemd.MachineImage.c +++ b/src/shared/varlink-io.systemd.MachineImage.c @@ -80,8 +80,15 @@ static SD_VARLINK_DEFINE_METHOD( Remove, VARLINK_DEFINE_IMAGE_LOOKUP_AND_POLKIT_FIELDS); +static SD_VARLINK_DEFINE_METHOD( + SetPoolLimit, + VARLINK_DEFINE_POLKIT_INPUT, + SD_VARLINK_FIELD_COMMENT("New image quota limit"), + SD_VARLINK_DEFINE_INPUT(limit, SD_VARLINK_INT, 0)); + static SD_VARLINK_DEFINE_ERROR(NoSuchImage); static SD_VARLINK_DEFINE_ERROR(TooManyOperations); +static SD_VARLINK_DEFINE_ERROR(NotSupported); SD_VARLINK_DEFINE_INTERFACE( io_systemd_MachineImage, @@ -90,13 +97,17 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_AcquireMetadata, SD_VARLINK_SYMBOL_COMMENT("List images"), &vl_method_List, - SD_VARLINK_SYMBOL_COMMENT("Update image allowing to rename or toggle read-only flag"), + SD_VARLINK_SYMBOL_COMMENT("Update image allowing to rename, toggle read-only flag, or set a limit"), &vl_method_Update, SD_VARLINK_SYMBOL_COMMENT("Clone image"), &vl_method_Clone, SD_VARLINK_SYMBOL_COMMENT("Remove image"), &vl_method_Remove, + SD_VARLINK_SYMBOL_COMMENT("Sets an overall quota limit on the pool of images"), + &vl_method_SetPoolLimit, SD_VARLINK_SYMBOL_COMMENT("No matching image exists"), &vl_error_NoSuchImage, SD_VARLINK_SYMBOL_COMMENT("Too many ongoing background operations"), - &vl_error_TooManyOperations); + &vl_error_TooManyOperations, + SD_VARLINK_SYMBOL_COMMENT("Requested operation is not supported"), + &vl_error_NotSupported); |