mirror of
https://github.com/systemd/systemd
synced 2025-10-04 19:24:44 +02:00
Compare commits
No commits in common. "09928421ea3718e96dee3c5cd2b1427dea557986" and "009adf6c0e435376c80fbc11675d581e0a94d350" have entirely different histories.
09928421ea
...
009adf6c0e
@ -5123,8 +5123,7 @@ static int unit_cgroup_freezer_kernel_state(Unit *u, FreezerState *ret) {
|
|||||||
|
|
||||||
int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
|
int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL;
|
||||||
FreezerState current, next, objective;
|
FreezerState target, current, next;
|
||||||
bool action_in_progress = false;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -5134,32 +5133,25 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
|
|||||||
if (!cg_freezer_supported())
|
if (!cg_freezer_supported())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unit_next_freezer_state(u, action, &next, &objective);
|
unit_next_freezer_state(u, action, &next, &target);
|
||||||
|
|
||||||
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
|
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
|
||||||
if (!crt || !crt->cgroup_path)
|
if (!crt || !crt->cgroup_realized) {
|
||||||
/* No realized cgroup = nothing to freeze */
|
/* No realized cgroup = nothing to freeze */
|
||||||
goto finish;
|
u->freezer_state = freezer_state_finish(next);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = unit_cgroup_freezer_kernel_state(u, ¤t);
|
r = unit_cgroup_freezer_kernel_state(u, ¤t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (current == objective) {
|
if (current == target)
|
||||||
if (objective == FREEZER_FROZEN)
|
next = freezer_state_finish(next);
|
||||||
goto finish;
|
else if (IN_SET(next, FREEZER_FROZEN, FREEZER_FROZEN_BY_PARENT, FREEZER_RUNNING)) {
|
||||||
|
/* We're transitioning into a finished state, which implies that the cgroup's
|
||||||
/* Skip thaw only if no freeze operation was in flight */
|
* current state already matches the target and thus we'd return 0. But, reality
|
||||||
if (IN_SET(u->freezer_state, FREEZER_RUNNING, FREEZER_THAWING))
|
* shows otherwise. This indicates that our freezer_state tracking has diverged
|
||||||
goto finish;
|
|
||||||
} else
|
|
||||||
action_in_progress = true;
|
|
||||||
|
|
||||||
if (next == freezer_state_finish(next)) {
|
|
||||||
/* We're directly transitioning into a finished state, which in theory means that
|
|
||||||
* the cgroup's current state already matches the objective and thus we'd return 0.
|
|
||||||
* But, reality shows otherwise (such case would have been handled by current == objective
|
|
||||||
* branch above). This indicates that our freezer_state tracking has diverged
|
|
||||||
* from the real state of the cgroup, which can happen if someone meddles with the
|
* from the real state of the cgroup, which can happen if someone meddles with the
|
||||||
* cgroup from underneath us. This really shouldn't happen during normal operation,
|
* cgroup from underneath us. This really shouldn't happen during normal operation,
|
||||||
* though. So, let's warn about it and fix up the state to be valid */
|
* though. So, let's warn about it and fix up the state to be valid */
|
||||||
@ -5173,25 +5165,22 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
|
|||||||
next = FREEZER_FREEZING_BY_PARENT;
|
next = FREEZER_FREEZING_BY_PARENT;
|
||||||
else if (next == FREEZER_RUNNING)
|
else if (next == FREEZER_RUNNING)
|
||||||
next = FREEZER_THAWING;
|
next = FREEZER_THAWING;
|
||||||
else
|
|
||||||
assert_not_reached();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "cgroup.freeze", &path);
|
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "cgroup.freeze", &path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = write_string_file(path, one_zero(objective == FREEZER_FROZEN), WRITE_STRING_FILE_DISABLE_BUFFER);
|
log_unit_debug(u, "Unit freezer state was %s, now %s.",
|
||||||
|
freezer_state_to_string(u->freezer_state),
|
||||||
|
freezer_state_to_string(next));
|
||||||
|
|
||||||
|
r = write_string_file(path, one_zero(target == FREEZER_FROZEN), WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
finish:
|
u->freezer_state = next;
|
||||||
if (action_in_progress)
|
return target != current;
|
||||||
unit_set_freezer_state(u, next);
|
|
||||||
else
|
|
||||||
unit_set_freezer_state(u, freezer_state_finish(next));
|
|
||||||
|
|
||||||
return action_in_progress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {
|
int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {
|
||||||
|
@ -6188,26 +6188,26 @@ bool unit_can_isolate_refuse_manual(Unit *u) {
|
|||||||
return unit_can_isolate(u) && !u->refuse_manual_start;
|
return unit_can_isolate(u) && !u->refuse_manual_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_next_freezer_state(Unit *u, FreezerAction action, FreezerState *ret, FreezerState *ret_objective) {
|
void unit_next_freezer_state(Unit *u, FreezerAction action, FreezerState *ret, FreezerState *ret_target) {
|
||||||
FreezerState curr, parent, next, objective;
|
Unit *slice;
|
||||||
|
FreezerState curr, parent, next, tgt;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(IN_SET(action, FREEZER_FREEZE, FREEZER_PARENT_FREEZE,
|
assert(IN_SET(action, FREEZER_FREEZE, FREEZER_PARENT_FREEZE,
|
||||||
FREEZER_THAW, FREEZER_PARENT_THAW));
|
FREEZER_THAW, FREEZER_PARENT_THAW));
|
||||||
assert(ret);
|
assert(ret);
|
||||||
assert(ret_objective);
|
assert(ret_target);
|
||||||
|
|
||||||
/* This function determines the correct freezer state transitions for a unit
|
/* This function determines the correct freezer state transitions for a unit
|
||||||
* given the action being requested. It returns the next state, and also the "objective",
|
* given the action being requested. It returns the next state, and also the "target",
|
||||||
* which is either FREEZER_FROZEN or FREEZER_RUNNING, depending on what actual state we
|
* which is either FREEZER_FROZEN or FREEZER_RUNNING, depending on what actual state we
|
||||||
* ultimately want to achieve. */
|
* ultimately want to achieve. */
|
||||||
|
|
||||||
curr = u->freezer_state;
|
curr = u->freezer_state;
|
||||||
|
slice = UNIT_GET_SLICE(u);
|
||||||
Unit *slice = UNIT_GET_SLICE(u);
|
if (slice)
|
||||||
if (slice)
|
|
||||||
parent = slice->freezer_state;
|
parent = slice->freezer_state;
|
||||||
else
|
else
|
||||||
parent = FREEZER_RUNNING;
|
parent = FREEZER_RUNNING;
|
||||||
|
|
||||||
if (action == FREEZER_FREEZE) {
|
if (action == FREEZER_FREEZE) {
|
||||||
@ -6251,13 +6251,13 @@ void unit_next_freezer_state(Unit *u, FreezerAction action, FreezerState *ret, F
|
|||||||
next = FREEZER_THAWING;
|
next = FREEZER_THAWING;
|
||||||
}
|
}
|
||||||
|
|
||||||
objective = freezer_state_finish(next);
|
tgt = freezer_state_finish(next);
|
||||||
if (objective == FREEZER_FROZEN_BY_PARENT)
|
if (tgt == FREEZER_FROZEN_BY_PARENT)
|
||||||
objective = FREEZER_FROZEN;
|
tgt = FREEZER_FROZEN;
|
||||||
assert(IN_SET(objective, FREEZER_RUNNING, FREEZER_FROZEN));
|
assert(IN_SET(tgt, FREEZER_RUNNING, FREEZER_FROZEN));
|
||||||
|
|
||||||
*ret = next;
|
*ret = next;
|
||||||
*ret_objective = objective;
|
*ret_target = tgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unit_can_freeze(Unit *u) {
|
bool unit_can_freeze(Unit *u) {
|
||||||
@ -6272,22 +6272,6 @@ bool unit_can_freeze(Unit *u) {
|
|||||||
return UNIT_VTABLE(u)->freezer_action;
|
return UNIT_VTABLE(u)->freezer_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_set_freezer_state(Unit *u, FreezerState state) {
|
|
||||||
assert(u);
|
|
||||||
assert(state >= 0);
|
|
||||||
assert(state < _FREEZER_STATE_MAX);
|
|
||||||
|
|
||||||
if (u->freezer_state == state)
|
|
||||||
return;
|
|
||||||
|
|
||||||
log_unit_debug(u, "Freezer state changed %s -> %s",
|
|
||||||
freezer_state_to_string(u->freezer_state), freezer_state_to_string(state));
|
|
||||||
|
|
||||||
u->freezer_state = state;
|
|
||||||
|
|
||||||
unit_add_to_dbus_queue(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unit_frozen(Unit *u) {
|
void unit_frozen(Unit *u) {
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|
||||||
|
@ -1040,8 +1040,7 @@ bool unit_can_isolate_refuse_manual(Unit *u);
|
|||||||
|
|
||||||
bool unit_can_freeze(Unit *u);
|
bool unit_can_freeze(Unit *u);
|
||||||
int unit_freezer_action(Unit *u, FreezerAction action);
|
int unit_freezer_action(Unit *u, FreezerAction action);
|
||||||
void unit_next_freezer_state(Unit *u, FreezerAction a, FreezerState *ret, FreezerState *ret_objective);
|
void unit_next_freezer_state(Unit *u, FreezerAction a, FreezerState *ret, FreezerState *ret_tgt);
|
||||||
void unit_set_freezer_state(Unit *u, FreezerState state);
|
|
||||||
void unit_frozen(Unit *u);
|
void unit_frozen(Unit *u);
|
||||||
void unit_thawed(Unit *u);
|
void unit_thawed(Unit *u);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user