2020-04-03 07:13:51 +00:00
|
|
|
#!/usr/bin/env bash
|
2021-10-17 16:13:06 +00:00
|
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
2023-05-22 14:02:43 +00:00
|
|
|
# shellcheck disable=SC2317
|
2021-04-09 17:39:41 +00:00
|
|
|
set -eux
|
2020-04-03 07:13:51 +00:00
|
|
|
set -o pipefail
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
# shellcheck source=test/units/test-control.sh
|
|
|
|
. "$(dirname "$0")"/test-control.sh
|
|
|
|
|
2020-04-03 07:13:51 +00:00
|
|
|
systemd-analyze log-level debug
|
|
|
|
|
2024-05-11 17:17:13 +00:00
|
|
|
unit=TEST-38-FREEZER-sleep.service
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
start_test_service() {
|
|
|
|
systemctl daemon-reload
|
|
|
|
systemctl start "${unit}"
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_freeze() {
|
2021-04-09 17:56:12 +00:00
|
|
|
local name object_path suffix
|
2020-04-03 07:13:51 +00:00
|
|
|
|
2021-04-09 17:56:12 +00:00
|
|
|
suffix="${1##*.}"
|
2022-06-17 13:28:17 +00:00
|
|
|
name="${1%".$suffix"}"
|
2021-04-09 17:56:12 +00:00
|
|
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
busctl call \
|
|
|
|
org.freedesktop.systemd1 \
|
|
|
|
"${object_path}" \
|
|
|
|
org.freedesktop.systemd1.Unit \
|
|
|
|
Freeze
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_thaw() {
|
2021-04-09 17:56:12 +00:00
|
|
|
local name object_path suffix
|
2020-04-03 07:13:51 +00:00
|
|
|
|
2021-04-09 17:56:12 +00:00
|
|
|
suffix="${1##*.}"
|
2022-06-17 13:28:17 +00:00
|
|
|
name="${1%".$suffix"}"
|
2021-04-09 17:56:12 +00:00
|
|
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
busctl call \
|
|
|
|
org.freedesktop.systemd1 \
|
|
|
|
"${object_path}" \
|
|
|
|
org.freedesktop.systemd1.Unit \
|
|
|
|
Thaw
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_freeze_unit() {
|
|
|
|
busctl call \
|
|
|
|
org.freedesktop.systemd1 \
|
|
|
|
/org/freedesktop/systemd1 \
|
|
|
|
org.freedesktop.systemd1.Manager \
|
|
|
|
FreezeUnit \
|
|
|
|
s \
|
|
|
|
"$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_thaw_unit() {
|
|
|
|
busctl call \
|
|
|
|
org.freedesktop.systemd1 \
|
|
|
|
/org/freedesktop/systemd1 \
|
|
|
|
org.freedesktop.systemd1.Manager \
|
|
|
|
ThawUnit \
|
|
|
|
s \
|
|
|
|
"$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_can_freeze() {
|
2021-04-09 17:56:12 +00:00
|
|
|
local name object_path suffix
|
2020-04-03 07:13:51 +00:00
|
|
|
|
2021-04-09 17:56:12 +00:00
|
|
|
suffix="${1##*.}"
|
2022-06-17 13:28:17 +00:00
|
|
|
name="${1%".$suffix"}"
|
2021-04-09 17:56:12 +00:00
|
|
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
busctl get-property \
|
|
|
|
org.freedesktop.systemd1 \
|
|
|
|
"${object_path}" \
|
|
|
|
org.freedesktop.systemd1.Unit \
|
|
|
|
CanFreeze
|
|
|
|
}
|
|
|
|
|
|
|
|
check_freezer_state() {
|
2021-04-09 17:56:12 +00:00
|
|
|
local name object_path suffix
|
2020-04-03 07:13:51 +00:00
|
|
|
|
2021-04-09 17:56:12 +00:00
|
|
|
suffix="${1##*.}"
|
2022-06-17 13:28:17 +00:00
|
|
|
name="${1%".$suffix"}"
|
2021-04-09 17:56:12 +00:00
|
|
|
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
|
2020-04-03 07:13:51 +00:00
|
|
|
|
2021-06-22 10:12:34 +00:00
|
|
|
for _ in {0..10}; do
|
|
|
|
state=$(busctl get-property \
|
|
|
|
org.freedesktop.systemd1 \
|
|
|
|
"${object_path}" \
|
|
|
|
org.freedesktop.systemd1.Unit \
|
|
|
|
FreezerState | cut -d " " -f2 | tr -d '"')
|
|
|
|
|
|
|
|
# Ignore the intermediate freezing & thawing states in case we check
|
|
|
|
# the unit state too quickly
|
2024-05-13 11:27:14 +00:00
|
|
|
[[ "$state" =~ ^(freezing|thawing) ]] || break
|
2021-06-22 10:12:34 +00:00
|
|
|
sleep .5
|
|
|
|
done
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
[ "$state" = "$2" ] || {
|
|
|
|
echo "error: unexpected freezer state, expected: $2, actual: $state" >&2
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
check_cgroup_state() {
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
# foo.unit -> /system.slice/foo.unit/
|
|
|
|
# foo.slice/ -> /foo.slice/./
|
|
|
|
# foo.slice/foo.unit -> /foo.slice/foo.unit/
|
|
|
|
local slice unit
|
|
|
|
unit="${1##*/}"
|
|
|
|
slice="${1%"$unit"}"
|
|
|
|
slice="${slice%/}"
|
|
|
|
grep -q "frozen $2" /sys/fs/cgroup/"${slice:-system.slice}"/"${unit:-.}"/cgroup.events
|
2020-04-03 07:13:51 +00:00
|
|
|
}
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
testcase_dbus_api() {
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "Test that DBus API works:"
|
|
|
|
echo -n " - Freeze(): "
|
|
|
|
dbus_freeze "${unit}"
|
|
|
|
check_freezer_state "${unit}" "frozen"
|
|
|
|
check_cgroup_state "$unit" 1
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - Thaw(): "
|
|
|
|
dbus_thaw "${unit}"
|
|
|
|
check_freezer_state "${unit}" "running"
|
|
|
|
check_cgroup_state "$unit" 0
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - FreezeUnit(): "
|
|
|
|
dbus_freeze_unit "${unit}"
|
|
|
|
check_freezer_state "${unit}" "frozen"
|
|
|
|
check_cgroup_state "$unit" 1
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - ThawUnit(): "
|
|
|
|
dbus_thaw_unit "${unit}"
|
|
|
|
check_freezer_state "${unit}" "running"
|
|
|
|
check_cgroup_state "$unit" 0
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - CanFreeze(): "
|
|
|
|
output=$(dbus_can_freeze "${unit}")
|
|
|
|
[ "$output" = "b true" ]
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
testcase_systemctl() {
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "Test that systemctl freeze/thaw verbs:"
|
|
|
|
|
|
|
|
systemctl start "$unit"
|
|
|
|
|
|
|
|
echo -n " - freeze: "
|
|
|
|
systemctl freeze "$unit"
|
|
|
|
check_freezer_state "${unit}" "frozen"
|
|
|
|
check_cgroup_state "$unit" 1
|
|
|
|
# Freezing already frozen unit should be NOP and return quickly
|
|
|
|
timeout 3s systemctl freeze "$unit"
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - thaw: "
|
|
|
|
systemctl thaw "$unit"
|
|
|
|
check_freezer_state "${unit}" "running"
|
|
|
|
check_cgroup_state "$unit" 0
|
|
|
|
# Likewise thawing already running unit shouldn't block
|
|
|
|
timeout 3s systemctl thaw "$unit"
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
systemctl stop "$unit"
|
|
|
|
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
testcase_systemctl_show() {
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "Test systemctl show integration:"
|
|
|
|
|
|
|
|
systemctl start "$unit"
|
|
|
|
|
|
|
|
echo -n " - FreezerState property: "
|
|
|
|
state=$(systemctl show -p FreezerState --value "$unit")
|
|
|
|
[ "$state" = "running" ]
|
|
|
|
systemctl freeze "$unit"
|
|
|
|
state=$(systemctl show -p FreezerState --value "$unit")
|
|
|
|
[ "$state" = "frozen" ]
|
|
|
|
systemctl thaw "$unit"
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - CanFreeze property: "
|
|
|
|
state=$(systemctl show -p CanFreeze --value "$unit")
|
|
|
|
[ "$state" = "yes" ]
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
systemctl stop "$unit"
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
testcase_recursive() {
|
2020-04-03 07:13:51 +00:00
|
|
|
local slice="bar.slice"
|
|
|
|
local unit="baz.service"
|
|
|
|
|
|
|
|
systemd-run --unit "$unit" --slice "$slice" sleep 3600 >/dev/null 2>&1
|
|
|
|
|
|
|
|
echo "Test recursive freezing:"
|
|
|
|
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
echo -n " - freeze/thaw parent: "
|
2020-04-03 07:13:51 +00:00
|
|
|
systemctl freeze "$slice"
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen-by-parent"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl thaw "$slice"
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "running"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 0
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "[ OK ]"
|
|
|
|
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
echo -n " - child freeze/thaw during frozen parent: "
|
|
|
|
systemctl freeze "$slice"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen-by-parent"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl freeze "$unit"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl thaw "$unit"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen-by-parent"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
2020-04-03 07:13:51 +00:00
|
|
|
systemctl thaw "$slice"
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "running"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 0
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - pre-frozen child not thawed by parent: "
|
|
|
|
systemctl freeze "$unit"
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl freeze "$slice"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl thaw "$slice"
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - pre-frozen child demoted and thawed by parent: "
|
|
|
|
systemctl freeze "$slice"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl thaw "$unit"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen-by-parent"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl thaw "$slice"
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "running"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 0
|
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - child promoted and not thawed by parent: "
|
|
|
|
systemctl freeze "$slice"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen-by-parent"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl freeze "$unit"
|
|
|
|
check_freezer_state "$slice" "frozen"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
|
|
|
systemctl thaw "$slice"
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "[ OK ]"
|
|
|
|
|
2024-01-24 00:50:21 +00:00
|
|
|
echo -n " - can't stop a frozen unit: "
|
|
|
|
(! systemctl -q stop "$unit" )
|
|
|
|
echo "[ OK ]"
|
|
|
|
systemctl thaw "$unit"
|
|
|
|
|
2020-04-03 07:13:51 +00:00
|
|
|
systemctl stop "$unit"
|
|
|
|
systemctl stop "$slice"
|
|
|
|
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
testcase_preserve_state() {
|
2020-04-03 07:13:51 +00:00
|
|
|
local slice="bar.slice"
|
|
|
|
local unit="baz.service"
|
|
|
|
|
|
|
|
systemd-run --unit "$unit" --slice "$slice" sleep 3600 >/dev/null 2>&1
|
|
|
|
|
|
|
|
echo "Test that freezer state is preserved when recursive freezing is initiated from outside (e.g. by manager up the tree):"
|
|
|
|
|
|
|
|
echo -n " - freeze from outside: "
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
echo 1 >/sys/fs/cgroup/"$slice"/cgroup.freeze
|
2020-06-05 09:35:01 +00:00
|
|
|
# Give kernel some time to freeze the slice
|
|
|
|
sleep 1
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
# Our state should not be affected
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "running"
|
2020-04-03 07:13:51 +00:00
|
|
|
|
|
|
|
# However actual kernel state should be frozen
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
check_cgroup_state "$slice/" 1
|
|
|
|
check_cgroup_state "$slice/$unit" 1
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - thaw from outside: "
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
echo 0 >/sys/fs/cgroup/"$slice"/cgroup.freeze
|
2020-06-05 09:35:01 +00:00
|
|
|
sleep 1
|
|
|
|
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
check_freezer_state "$unit" "running"
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_cgroup_state "$slice/" 0
|
|
|
|
check_cgroup_state "$slice/$unit" 0
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "[ OK ]"
|
|
|
|
|
|
|
|
echo -n " - thaw from outside while inner service is frozen: "
|
|
|
|
systemctl freeze "$unit"
|
core: Rework recursive freeze/thaw
This commit overhauls the way freeze/thaw works recursively:
First, it introduces new FreezerActions that are like the existing
FREEZE and THAW but indicate that the action was initiated by a parent
unit. We also refactored the code to pass these FreezerActions through
the whole call stack so that we can make use of them. FreezerState was
extended similarly, to be able to differentiate between a unit that's
frozen manually and a unit that's frozen because a parent is frozen.
Next, slices were changed to check recursively that all their child
units can be frozen before it attempts to freeze them. This is different
from the previous behavior, that would just check if the unit's type
supported freezing at all. This cleans up the code, and also ensures
that the behavior of slices corresponds to the unit's actual ability
to be frozen
Next, we make it so that if you FREEZE a slice, it'll PARENT_FREEZE
all of its children. Similarly, if you THAW a slice it will PARENT_THAW
its children.
Finally, we use the new states available to us to refactor the code
that actually does the cgroup freezing. The code now looks at the unit's
existing freezer state and the action being requested, and decides what
next state is most appropriate. Then it puts the unit in that state.
For instance, a RUNNING unit with a request to PARENT_FREEZE will
put the unit into the PARENT_FREEZING state. As another example, a
FROZEN unit who's parent is also FROZEN will transition to
PARENT_FROZEN in response to a request to THAW.
Fixes https://github.com/systemd/systemd/issues/30640
Fixes https://github.com/systemd/systemd/issues/15850
2024-01-21 20:05:20 +00:00
|
|
|
check_freezer_state "$unit" "frozen"
|
|
|
|
echo 1 >/sys/fs/cgroup/"$slice"/cgroup.freeze
|
|
|
|
echo 0 >/sys/fs/cgroup/"$slice"/cgroup.freeze
|
|
|
|
check_freezer_state "$slice" "running"
|
|
|
|
check_freezer_state "$unit" "frozen"
|
2020-04-03 07:13:51 +00:00
|
|
|
echo "[ OK ]"
|
|
|
|
|
2024-01-24 00:50:21 +00:00
|
|
|
systemctl thaw "$unit"
|
2020-04-03 07:13:51 +00:00
|
|
|
systemctl stop "$unit"
|
|
|
|
systemctl stop "$slice"
|
|
|
|
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
2023-05-22 14:02:43 +00:00
|
|
|
if [[ -e /sys/fs/cgroup/system.slice/cgroup.freeze ]]; then
|
2020-04-03 07:13:51 +00:00
|
|
|
start_test_service
|
2023-05-22 14:02:43 +00:00
|
|
|
run_testcases
|
|
|
|
fi
|
2020-04-03 07:13:51 +00:00
|
|
|
|
2023-07-12 13:49:55 +00:00
|
|
|
touch /testok
|