From: msizanoen1 Date: Wed, 7 Dec 2022 13:46:01 +0000 (+0700) Subject: core/unit: allow overriding an ongoing freeze operation X-Git-Tag: v253-rc1~330^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3d19e122cfe341b28dfcb58f1aac829c122da569;p=thirdparty%2Fsystemd.git core/unit: allow overriding an ongoing freeze operation Sometimes a freeze operation can hang due to the presence of kernel threads inside the unit cgroup (e.g. QEMU-KVM). This ensures that the ThawUnit operation invoked by systemd-sleep at wakeup always thaws the unit. --- diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 19a71b6cb38..0702373ab0f 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -782,14 +782,15 @@ static int bus_unit_method_freezer_generic(sd_bus_message *message, void *userda if (r == 0) reply_no_delay = true; - assert(!u->pending_freezer_message); + if (u->pending_freezer_message) { + bus_unit_send_pending_freezer_message(u, true); + assert(!u->pending_freezer_message); + } - r = sd_bus_message_new_method_return(message, &u->pending_freezer_message); - if (r < 0) - return r; + u->pending_freezer_message = sd_bus_message_ref(message); if (reply_no_delay) { - r = bus_unit_send_pending_freezer_message(u); + r = bus_unit_send_pending_freezer_message(u, false); if (r < 0) return r; } @@ -1661,7 +1662,8 @@ void bus_unit_send_pending_change_signal(Unit *u, bool including_new) { bus_unit_send_change_signal(u); } -int bus_unit_send_pending_freezer_message(Unit *u) { +int bus_unit_send_pending_freezer_message(Unit *u, bool cancelled) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int r; assert(u); @@ -1669,7 +1671,18 @@ int bus_unit_send_pending_freezer_message(Unit *u) { if (!u->pending_freezer_message) return 0; - r = sd_bus_send(NULL, u->pending_freezer_message, NULL); + if (cancelled) + r = sd_bus_message_new_method_error( + u->pending_freezer_message, + &reply, + &SD_BUS_ERROR_MAKE_CONST( + BUS_ERROR_FREEZE_CANCELLED, "Freeze operation aborted")); + else + r = sd_bus_message_new_method_return(u->pending_freezer_message, &reply); + if (r < 0) + return r; + + r = sd_bus_send(NULL, reply, NULL); if (r < 0) log_warning_errno(r, "Failed to send queued message, ignoring: %m"); diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 643edcd87e9..6b7828e4bae 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -10,7 +10,7 @@ extern const sd_bus_vtable bus_unit_cgroup_vtable[]; void bus_unit_send_change_signal(Unit *u); void bus_unit_send_pending_change_signal(Unit *u, bool including_new); -int bus_unit_send_pending_freezer_message(Unit *u); +int bus_unit_send_pending_freezer_message(Unit *u, bool cancelled); void bus_unit_send_removed_signal(Unit *u); int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error); diff --git a/src/core/unit.c b/src/core/unit.c index 29b07a6e7a8..e0d54d8fe18 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -5829,7 +5829,7 @@ void unit_frozen(Unit *u) { u->freezer_state = FREEZER_FROZEN; - bus_unit_send_pending_freezer_message(u); + bus_unit_send_pending_freezer_message(u, false); } void unit_thawed(Unit *u) { @@ -5837,7 +5837,7 @@ void unit_thawed(Unit *u) { u->freezer_state = FREEZER_RUNNING; - bus_unit_send_pending_freezer_message(u); + bus_unit_send_pending_freezer_message(u, false); } static int unit_freezer_action(Unit *u, FreezerAction action) { @@ -5862,7 +5862,8 @@ static int unit_freezer_action(Unit *u, FreezerAction action) { if (s != UNIT_ACTIVE) return -EHOSTDOWN; - if (IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING)) + if ((IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING) && action == FREEZER_FREEZE) || + (u->freezer_state == FREEZER_THAWING && action == FREEZER_THAW)) return -EALREADY; r = method(u); diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index d4a1fb689eb..40d6abc4131 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -31,6 +31,7 @@ #define BUS_ERROR_NOTHING_TO_CLEAN "org.freedesktop.systemd1.NothingToClean" #define BUS_ERROR_UNIT_BUSY "org.freedesktop.systemd1.UnitBusy" #define BUS_ERROR_UNIT_INACTIVE "org.freedesktop.systemd1.UnitInactive" +#define BUS_ERROR_FREEZE_CANCELLED "org.freedesktop.systemd1.FreezeCancelled" #define BUS_ERROR_NO_SUCH_MACHINE "org.freedesktop.machine1.NoSuchMachine" #define BUS_ERROR_NO_SUCH_IMAGE "org.freedesktop.machine1.NoSuchImage"