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:
commit
d20ea2c515
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user