From 000a996dc46c187f803b67b0b0d51ad4d0bc1658 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Fri, 13 Nov 2015 14:12:19 +0100 Subject: Introduce bus_unit_check_load_state() helper This function is used to check that a previous unit load succeed and returns 0 in this case. In the case the load failed, the function setup a bus error accordingly and returns -errno. --- src/core/dbus-unit.c | 17 +++++++++++++++++ src/core/dbus-unit.h | 2 ++ 2 files changed, 19 insertions(+) (limited to 'src') diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index d9b7382c82..66b465a0b7 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -1251,3 +1251,20 @@ int bus_unit_set_properties( return n; } + +int bus_unit_check_load_state(Unit *u, sd_bus_error *error) { + + if (u->load_state == UNIT_LOADED) + return 0; + + /* Give a better description of the unit error when + * possible. Note that in the case of UNIT_MASKED, load_error + * is not set. */ + if (u->load_state == UNIT_MASKED) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit is masked."); + + if (u->load_state == UNIT_NOT_FOUND) + return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit not found."); + + return sd_bus_error_set_errnof(error, u->load_error, "Unit is not loaded properly: %m."); +} diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index b622e0ae8d..0d7e5f8d83 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -37,3 +37,5 @@ int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus int bus_unit_queue_job(sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible, sd_bus_error *error); int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitSetPropertiesMode mode, bool commit, sd_bus_error *error); int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_bus_error *error); + +int bus_unit_check_load_state(Unit *u, sd_bus_error *error); -- cgit v1.2.3-54-g00ecf From e9fd88f2e9a2effb7bcc1541a66263a5f97ce0a6 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Tue, 3 Nov 2015 18:25:46 +0100 Subject: core: allow 'SetUnitProperties()' to run on inactive units too 'set-property' has been primarly designed to change some properties of *active* units. However it can easily work on inactive units as well. In that case changes are only saved in a drop-in for futur uses and changes will be effective when unit will be started. Actually it already works on inactive units but that was not documented and not fully supported. Indeed the inactive units had to be known by the manager otherwise it was reported as not loaded: $ systemctl status my-test.service * my-test.service - My Testing Unit Loaded: loaded (/etc/systemd/system/my-test.service; static; vendor preset: disabled) Drop-In: /etc/systemd/system/my-test.service.d Active: inactive (dead) $ systemctl set-property my-test.service MemoryLimit=1000000 Failed to set unit properties on my-test.service: Unit my-test.service is not loaded. [ Note: that the unit load state reported by the 'status' command might be confusing since it claimed the unit as loaded but 'set-property' reported the contrary. ] One can possibily workaround this by making the unit a dependency of another active unit so the manager will keep it around: $ systemctl add-wants multi-user.target my-test.service Created symlink from /etc/systemd/system/multi-user.target.wants/my-test.service to /etc/systemd/system/my-test.service. $ systemctl set-property my-test.service MemoryLimit=1000000 $ systemctl status my-test.service * my-test.service - My Testing Unit Loaded: loaded (/etc/systemd/system/my-test.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/my-test.service.d `-50-MemoryLimit.conf Active: inactive (dead) This patch simply forces 'SetUnitProperties()' to load the unit if it's not already the case. It also documents the fact that 'set-property' can be used on inactive units. --- man/systemctl.xml | 5 +++++ src/core/dbus-manager.c | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/man/systemctl.xml b/man/systemctl.xml index 755a74f987..1fb056874c 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -888,6 +888,11 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Example: systemctl set-property foobar.service CPUShares=777 + If the specified unit appears to be inactive, the + changes will be only stored on disk as described + previously hence they will be effective when the unit will + be started. + Note that this command allows changing multiple properties at the same time, which is preferable over setting them individually. Like unit file configuration diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index d3bcc795ae..f58ac55009 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -630,9 +630,13 @@ static int method_set_unit_properties(sd_bus_message *message, void *userdata, s if (r < 0) return r; - u = manager_get_unit(m, name); - if (!u) - return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + r = manager_load_unit(m, name, NULL, error, &u); + if (r < 0) + return r; + + r = bus_unit_check_load_state(u, error); + if (r < 0) + return r; return bus_unit_method_set_properties(message, u, error); } -- cgit v1.2.3-54-g00ecf