mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 18:55:40 +03:00
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.
This commit is contained in:
parent
a14137d90e
commit
3d19e122cf
@ -782,14 +782,15 @@ static int bus_unit_method_freezer_generic(sd_bus_message *message, void *userda
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
reply_no_delay = true;
|
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);
|
u->pending_freezer_message = sd_bus_message_ref(message);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (reply_no_delay) {
|
if (reply_no_delay) {
|
||||||
r = bus_unit_send_pending_freezer_message(u);
|
r = bus_unit_send_pending_freezer_message(u, false);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -1661,7 +1662,8 @@ void bus_unit_send_pending_change_signal(Unit *u, bool including_new) {
|
|||||||
bus_unit_send_change_signal(u);
|
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;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -1669,7 +1671,18 @@ int bus_unit_send_pending_freezer_message(Unit *u) {
|
|||||||
if (!u->pending_freezer_message)
|
if (!u->pending_freezer_message)
|
||||||
return 0;
|
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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to send queued message, ignoring: %m");
|
log_warning_errno(r, "Failed to send queued message, ignoring: %m");
|
||||||
|
|
||||||
|
@ -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_change_signal(Unit *u);
|
||||||
void bus_unit_send_pending_change_signal(Unit *u, bool including_new);
|
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);
|
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);
|
int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error);
|
||||||
|
@ -5829,7 +5829,7 @@ void unit_frozen(Unit *u) {
|
|||||||
|
|
||||||
u->freezer_state = FREEZER_FROZEN;
|
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) {
|
void unit_thawed(Unit *u) {
|
||||||
@ -5837,7 +5837,7 @@ void unit_thawed(Unit *u) {
|
|||||||
|
|
||||||
u->freezer_state = FREEZER_RUNNING;
|
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) {
|
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)
|
if (s != UNIT_ACTIVE)
|
||||||
return -EHOSTDOWN;
|
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;
|
return -EALREADY;
|
||||||
|
|
||||||
r = method(u);
|
r = method(u);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#define BUS_ERROR_NOTHING_TO_CLEAN "org.freedesktop.systemd1.NothingToClean"
|
#define BUS_ERROR_NOTHING_TO_CLEAN "org.freedesktop.systemd1.NothingToClean"
|
||||||
#define BUS_ERROR_UNIT_BUSY "org.freedesktop.systemd1.UnitBusy"
|
#define BUS_ERROR_UNIT_BUSY "org.freedesktop.systemd1.UnitBusy"
|
||||||
#define BUS_ERROR_UNIT_INACTIVE "org.freedesktop.systemd1.UnitInactive"
|
#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_MACHINE "org.freedesktop.machine1.NoSuchMachine"
|
||||||
#define BUS_ERROR_NO_SUCH_IMAGE "org.freedesktop.machine1.NoSuchImage"
|
#define BUS_ERROR_NO_SUCH_IMAGE "org.freedesktop.machine1.NoSuchImage"
|
||||||
|
Loading…
Reference in New Issue
Block a user