1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-09 09:57:26 +03:00

Merge pull request #25662 from msizanoen1/s2h-nosuspend-user-proc

sleep: always thaw user.slice even if freezing failed
This commit is contained in:
Lennart Poettering 2022-12-08 17:24:52 +01:00 committed by GitHub
commit d20ea2c515
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 28 deletions

View File

@ -4167,7 +4167,7 @@ int compare_job_priority(const void *a, const void *b) {
int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
_cleanup_free_ char *path = NULL;
FreezerState target, kernel = _FREEZER_STATE_INVALID;
int r;
int r, ret;
assert(u);
assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW));
@ -4175,9 +4175,23 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
if (!cg_freezer_supported())
return 0;
/* Ignore all requests to thaw init.scope or -.slice and reject all requests to freeze them */
if (unit_has_name(u, SPECIAL_ROOT_SLICE) || unit_has_name(u, SPECIAL_INIT_SCOPE))
return action == FREEZER_FREEZE ? -EPERM : 0;
if (!u->cgroup_realized)
return -EBUSY;
if (action == FREEZER_THAW) {
Unit *slice = UNIT_GET_SLICE(u);
if (slice) {
r = unit_cgroup_freezer_action(slice, FREEZER_THAW);
if (r < 0)
return log_unit_error_errno(u, r, "Failed to thaw slice %s of unit: %m", slice->id);
}
}
target = action == FREEZER_FREEZE ? FREEZER_FROZEN : FREEZER_RUNNING;
r = unit_freezer_state_kernel(u, &kernel);
@ -4186,8 +4200,11 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
if (target == kernel) {
u->freezer_state = target;
return 0;
}
if (action == FREEZER_FREEZE)
return 0;
ret = 0;
} else
ret = 1;
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.freeze", &path);
if (r < 0)
@ -4195,16 +4212,18 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
log_unit_debug(u, "%s unit.", action == FREEZER_FREEZE ? "Freezing" : "Thawing");
if (action == FREEZER_FREEZE)
u->freezer_state = FREEZER_FREEZING;
else
u->freezer_state = FREEZER_THAWING;
if (target != kernel) {
if (action == FREEZER_FREEZE)
u->freezer_state = FREEZER_FREEZING;
else
u->freezer_state = FREEZER_THAWING;
}
r = write_string_file(path, one_zero(action == FREEZER_FREEZE), WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
return r;
return 1;
return ret;
}
int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {

View File

@ -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_invocation) {
bus_unit_send_pending_freezer_message(u, true);
assert(!u->pending_freezer_invocation);
}
r = sd_bus_message_new_method_return(message, &u->pending_freezer_message);
if (r < 0)
return r;
u->pending_freezer_invocation = 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,19 +1662,31 @@ 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);
if (!u->pending_freezer_message)
if (!u->pending_freezer_invocation)
return 0;
r = sd_bus_send(NULL, u->pending_freezer_message, NULL);
if (cancelled)
r = sd_bus_message_new_method_error(
u->pending_freezer_invocation,
&reply,
&SD_BUS_ERROR_MAKE_CONST(
BUS_ERROR_FREEZE_CANCELLED, "Freeze operation aborted"));
else
r = sd_bus_message_new_method_return(u->pending_freezer_invocation, &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");
u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message);
u->pending_freezer_invocation = sd_bus_message_unref(u->pending_freezer_invocation);
return 0;
}

View File

@ -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);

View File

@ -998,8 +998,8 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
u->bus_track = sd_bus_track_unref(u->bus_track);
/* Get rid of pending freezer messages on this bus */
if (u->pending_freezer_message && sd_bus_message_get_bus(u->pending_freezer_message) == *bus)
u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message);
if (u->pending_freezer_invocation && sd_bus_message_get_bus(u->pending_freezer_invocation) == *bus)
u->pending_freezer_invocation = sd_bus_message_unref(u->pending_freezer_invocation);
}
/* Get rid of queued message on this bus */

View File

@ -381,6 +381,9 @@ static int slice_freezer_action(Unit *s, FreezerAction action) {
}
UNIT_FOREACH_DEPENDENCY(member, s, UNIT_ATOM_SLICE_OF) {
if (!member->cgroup_realized)
continue;
if (action == FREEZER_FREEZE)
r = UNIT_VTABLE(member)->freeze(member);
else

View File

@ -687,7 +687,7 @@ Unit* unit_free(Unit *u) {
u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
u->bus_track = sd_bus_track_unref(u->bus_track);
u->deserialized_refs = strv_free(u->deserialized_refs);
u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message);
u->pending_freezer_invocation = sd_bus_message_unref(u->pending_freezer_invocation);
unit_free_requires_mounts_for(u);
@ -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);

View File

@ -239,7 +239,7 @@ typedef struct Unit {
FILE *transient_file;
/* Freezer state */
sd_bus_message *pending_freezer_message;
sd_bus_message *pending_freezer_invocation;
FreezerState freezer_state;
/* Job timeout and action to take */

View File

@ -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"

View File

@ -366,6 +366,9 @@ static int freeze_thaw_user_slice(const char **method) {
if (r < 0)
return log_debug_errno(r, "Failed to open connection to systemd: %m");
/* Wait for 1.5 seconds at maximum for freeze operation */
(void) sd_bus_set_method_call_timeout(bus, 1500 * USEC_PER_MSEC);
r = bus_call_method(bus, bus_systemd_mgr, *method, &error, NULL, "s", SPECIAL_USER_SLICE);
if (r < 0)
return log_debug_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
@ -374,7 +377,7 @@ static int freeze_thaw_user_slice(const char **method) {
}
static int execute_s2h(const SleepConfig *sleep_config) {
_unused_ _cleanup_(freeze_thaw_user_slice) const char *auto_method_thaw = NULL;
_unused_ _cleanup_(freeze_thaw_user_slice) const char *auto_method_thaw = "ThawUnit";
int r, k;
assert(sleep_config);
@ -382,8 +385,6 @@ static int execute_s2h(const SleepConfig *sleep_config) {
r = freeze_thaw_user_slice(&(const char*) { "FreezeUnit" });
if (r < 0)
log_debug_errno(r, "Failed to freeze unit user.slice, ignoring: %m");
else
auto_method_thaw = "ThawUnit"; /* from now on we want automatic thawing */;
r = check_wakeup_type();
if (r < 0)