!422 从systemd原生社区中同步补丁

From: @hongjinghao 
Reviewed-by: @licunlong 
Signed-off-by: @licunlong
This commit is contained in:
openeuler-ci-bot 2023-06-19 03:31:27 +00:00 committed by Gitee
commit 75b64af0ec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
36 changed files with 1892 additions and 28 deletions

View File

@ -0,0 +1,66 @@
From c3fa408dcc03bb6dbd11f180540fb9e684893c39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 16 Oct 2022 21:52:43 +0200
Subject: [PATCH] TEST-15: add one more test for drop-in precedence
---
test/units/testsuite-15.sh | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh
index ed6d5f838d..079c8b290e 100755
--- a/test/units/testsuite-15.sh
+++ b/test/units/testsuite-15.sh
@@ -282,6 +282,41 @@ MemoryMax=1000000001
clear_services a-b-c.slice
}
+test_transient_service_dropins () {
+ echo "Testing dropins for a transient service..."
+ echo "*** test transient service drop-ins"
+
+ mkdir -p /etc/systemd/system/service.d
+ mkdir -p /etc/systemd/system/a-.service.d
+ mkdir -p /etc/systemd/system/a-b-.service.d
+ mkdir -p /etc/systemd/system/a-b-c.service.d
+
+ echo -e '[Service]\nStandardInputText=aaa' >/etc/systemd/system/service.d/drop1.conf
+ echo -e '[Service]\nStandardInputText=bbb' >/etc/systemd/system/a-.service.d/drop2.conf
+ echo -e '[Service]\nStandardInputText=ccc' >/etc/systemd/system/a-b-.service.d/drop3.conf
+ echo -e '[Service]\nStandardInputText=ddd' >/etc/systemd/system/a-b-c.service.d/drop4.conf
+
+ # There's no fragment yet, so this fails
+ systemctl cat a-b-c.service && exit 1
+
+ # xxx → eHh4Cg==
+ systemd-run -u a-b-c.service -p StandardInputData=eHh4Cg== sleep infinity
+
+ data=$(systemctl show -P StandardInputData a-b-c.service)
+ # xxx\naaa\n\bbb\nccc\nddd\n → eHh4…
+ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo="
+
+ # Do a reload and check again
+ systemctl daemon-reload
+ data=$(systemctl show -P StandardInputData a-b-c.service)
+ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo="
+
+ clear_services a-b-c.service
+ rm /etc/systemd/system/service.d/drop1.conf \
+ /etc/systemd/system/a-.service.d/drop2.conf \
+ /etc/systemd/system/a-b-.service.d/drop3.conf
+}
+
test_template_dropins () {
echo "Testing template dropins..."
@@ -621,6 +656,7 @@ test_linked_units
test_template_alias
test_hierarchical_service_dropins
test_hierarchical_slice_dropins
+test_transient_service_dropins
test_template_dropins
test_alias_dropins
test_masked_dropins
--
2.33.0

View File

@ -0,0 +1,108 @@
From 6854434cfb5dda10c07d95835c38b75e5e71c2b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 16 Oct 2022 14:02:45 +0200
Subject: [PATCH] TEST-15: add test for transient units with drop-ins
We want to test four things:
- that the transient units are successfully started when drop-ins exist
- that the transient setings override the defaults
- the drop-ins override the transient settings (the same as for a normal unit)
- that things are the same before and after a reload
To make things more fun, we start and stop units in two different ways: via
systemctl and via a direct busctl invocation. This gives us a bit more coverage
of different code paths.
---
test/units/testsuite-15.sh | 62 ++++++++++++++++++++++++++++++++++----
1 file changed, 56 insertions(+), 6 deletions(-)
diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh
index 8b44d76982..ed6d5f838d 100755
--- a/test/units/testsuite-15.sh
+++ b/test/units/testsuite-15.sh
@@ -181,19 +181,40 @@ test_hierarchical_service_dropins () {
echo "Testing hierarchical service dropins..."
echo "*** test service.d/ top level drop-in"
create_services a-b-c
- check_ko a-b-c ExecCondition "/bin/echo service.d"
- check_ko a-b-c ExecCondition "/bin/echo a-.service.d"
- check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d"
- check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d"
+ check_ko a-b-c ExecCondition "echo service.d"
+ check_ko a-b-c ExecCondition "echo a-.service.d"
+ check_ko a-b-c ExecCondition "echo a-b-.service.d"
+ check_ko a-b-c ExecCondition "echo a-b-c.service.d"
for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do
mkdir -p /usr/lib/systemd/system/$dropin
echo "
[Service]
-ExecCondition=/bin/echo $dropin
+ExecCondition=echo $dropin
" >/usr/lib/systemd/system/$dropin/override.conf
systemctl daemon-reload
- check_ok a-b-c ExecCondition "/bin/echo $dropin"
+ check_ok a-b-c ExecCondition "echo $dropin"
+
+ # Check that we can start a transient service in presence of the drop-ins
+ systemd-run -u a-b-c2.service -p Description='sleepy' sleep infinity
+
+ # The transient setting replaces the default
+ check_ok a-b-c2.service Description "sleepy"
+
+ # The override takes precedence for ExecCondition
+ # (except the last iteration when it only applies to the other service)
+ if [ "$dropin" != "a-b-c.service.d" ]; then
+ check_ok a-b-c2.service ExecCondition "echo $dropin"
+ fi
+
+ # Check that things are the same after a reload
+ systemctl daemon-reload
+ check_ok a-b-c2.service Description "sleepy"
+ if [ "$dropin" != "a-b-c.service.d" ]; then
+ check_ok a-b-c2.service ExecCondition "echo $dropin"
+ fi
+
+ systemctl stop a-b-c2.service
done
for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do
rm -rf /usr/lib/systemd/system/$dropin
@@ -218,6 +239,35 @@ MemoryMax=1000000000
" >/usr/lib/systemd/system/$dropin/override.conf
systemctl daemon-reload
check_ok a-b-c.slice MemoryMax "1000000000"
+
+ busctl call \
+ org.freedesktop.systemd1 \
+ /org/freedesktop/systemd1 \
+ org.freedesktop.systemd1.Manager \
+ StartTransientUnit 'ssa(sv)a(sa(sv))' \
+ 'a-b-c.slice' 'replace' \
+ 2 \
+ 'Description' s 'slice too' \
+ 'MemoryMax' t 1000000002 \
+ 0
+
+ # The override takes precedence for MemoryMax
+ check_ok a-b-c.slice MemoryMax "1000000000"
+ # The transient setting replaces the default
+ check_ok a-b-c.slice Description "slice too"
+
+ # Check that things are the same after a reload
+ systemctl daemon-reload
+ check_ok a-b-c.slice MemoryMax "1000000000"
+ check_ok a-b-c.slice Description "slice too"
+
+ busctl call \
+ org.freedesktop.systemd1 \
+ /org/freedesktop/systemd1 \
+ org.freedesktop.systemd1.Manager \
+ StopUnit 'ss' \
+ 'a-b-c.slice' 'replace'
+
rm /usr/lib/systemd/system/$dropin/override.conf
done
--
2.33.0

View File

@ -0,0 +1,78 @@
From f80c874af376052b6b81f47cbbc43d7fecd98cd6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 16 Oct 2022 12:54:34 +0200
Subject: [PATCH] TEST-15: also test hierarchical drop-ins for slices
Slices are worth testing too, because they don't need a fragment path so they
behave slightly differently than service units. I'm making this a separate
patch from the actual tests that I wanted to add later because it's complex
enough on its own.
---
test/units/testsuite-15.sh | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh
index c3784e2..8bae64d 100755
--- a/test/units/testsuite-15.sh
+++ b/test/units/testsuite-15.sh
@@ -174,8 +174,8 @@ test_template_alias() {
clear_services test15-a@ test15-b@
}
-test_hierarchical_dropins () {
- echo "Testing hierarchical dropins..."
+test_hierarchical_service_dropins () {
+ echo "Testing hierarchical service dropins..."
echo "*** test service.d/ top level drop-in"
create_services a-b-c
check_ko a-b-c ExecCondition "/bin/echo service.d"
@@ -199,6 +199,36 @@ ExecCondition=/bin/echo $dropin
clear_services a-b-c
}
+test_hierarchical_slice_dropins () {
+ echo "Testing hierarchical slice dropins..."
+ echo "*** test slice.d/ top level drop-in"
+ # Slice units don't even need a fragment, so we test the defaults here
+ check_ok a-b-c.slice Description "Slice /a/b/c"
+ check_ok a-b-c.slice MemoryMax "infinity"
+
+ # Test drop-ins
+ for dropin in slice.d a-.slice.d a-b-.slice.d a-b-c.slice.d; do
+ mkdir -p /usr/lib/systemd/system/$dropin
+ echo "
+[Slice]
+MemoryMax=1000000000
+ " >/usr/lib/systemd/system/$dropin/override.conf
+ systemctl daemon-reload
+ check_ok a-b-c.slice MemoryMax "1000000000"
+ rm /usr/lib/systemd/system/$dropin/override.conf
+ done
+
+ # Test unit with a fragment
+ echo "
+[Slice]
+MemoryMax=1000000001
+ " >/usr/lib/systemd/system/a-b-c.slice
+ systemctl daemon-reload
+ check_ok a-b-c.slice MemoryMax "1000000001"
+
+ clear_services a-b-c.slice
+}
+
test_template_dropins () {
echo "Testing template dropins..."
@@ -517,7 +547,8 @@ test_invalid_dropins () {
test_basic_dropins
test_linked_units
test_template_alias
-test_hierarchical_dropins
+test_hierarchical_service_dropins
+test_hierarchical_slice_dropins
test_template_dropins
test_alias_dropins
test_masked_dropins
--
2.33.0

View File

@ -0,0 +1,65 @@
From 1ea74fca3a3c737f3901bc10d879b7830b3528bf Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 25 Oct 2022 21:41:17 +0900
Subject: [PATCH] core/device: also serialize/deserialize device syspath
The field will be used in later commits.
---
src/core/device.c | 13 ++++++++++++-
src/core/device.h | 2 +-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/core/device.c b/src/core/device.c
index 9d694aa..26a6d1f 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -114,6 +114,7 @@ static void device_done(Unit *u) {
assert(d);
device_unset_sysfs(d);
+ d->deserialized_sysfs = mfree(d->deserialized_sysfs);
d->wants_property = strv_free(d->wants_property);
}
@@ -295,6 +296,9 @@ static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
assert(f);
assert(fds);
+ if (d->sysfs)
+ (void) serialize_item(f, "sysfs", d->sysfs);
+
(void) serialize_item(f, "state", device_state_to_string(d->state));
if (device_found_to_string_many(d->found, &s) >= 0)
@@ -312,7 +316,14 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value,
assert(value);
assert(fds);
- if (streq(key, "state")) {
+ if (streq(key, "sysfs")) {
+ if (!d->deserialized_sysfs) {
+ d->deserialized_sysfs = strdup(value);
+ if (!d->deserialized_sysfs)
+ log_oom_debug();
+ }
+
+ } else if (streq(key, "state")) {
DeviceState state;
state = device_state_from_string(value);
diff --git a/src/core/device.h b/src/core/device.h
index dfe8a13..99bf134 100644
--- a/src/core/device.h
+++ b/src/core/device.h
@@ -20,7 +20,7 @@ typedef enum DeviceFound {
struct Device {
Unit meta;
- char *sysfs;
+ char *sysfs, *deserialized_sysfs;
/* In order to be able to distinguish dependencies on different device nodes we might end up creating multiple
* devices for the same sysfs path. We chain them up here. */
--
2.33.0

View File

@ -0,0 +1,43 @@
From cf1ac0cfe44997747b0f857a1d0b67cea1298272 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 25 May 2022 12:01:00 +0200
Subject: [PATCH] core/device: device_coldplug(): don't set DEVICE_DEAD
dm-crypt device units generated by systemd-cryptsetup-generator
habe BindsTo= dependencies on their backend devices. The dm-crypt
devices have the db_persist flag set, and thus survive the udev db
cleanup while switching root. But backend devices usually don't survive.
These devices are neither mounted nor used for swap, thus they will
seen as DEVICE_NOT_FOUND after switching root.
The BindsTo dependency will cause systemd to schedule a stop
job for the dm-crypt device, breaking boot:
[ 68.929457] krypton systemd[1]: systemd-cryptsetup@cr_root.service: Unit is stopped because bound to inactive unit dev-disk-by\x2duuid-3bf91f73\x2d1ee8\x2d4cfc\x2d9048\x2d93ba349b786d.device.
[ 68.945660] krypton systemd[1]: systemd-cryptsetup@cr_root.service: Trying to enqueue job systemd-cryptsetup@cr_root.service/stop/replace
[ 69.473459] krypton systemd[1]: systemd-cryptsetup@cr_root.service: Installed new job systemd-cryptsetup@cr_root.service/stop as 343
Avoid this by not setting the state of the backend devices to
DEVICE_DEAD.
Fixes the LUKS setup issue reported in #23429.
---
src/core/device.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/core/device.c b/src/core/device.c
index 4c261ec554..8728630523 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -205,8 +205,6 @@ static int device_coldplug(Unit *u) {
found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */
if (state == DEVICE_PLUGGED)
state = DEVICE_TENTATIVE; /* downgrade state */
- if (found == DEVICE_NOT_FOUND)
- state = DEVICE_DEAD; /* If nobody sees the device, downgrade more */
}
if (d->found == found && d->state == state)
--
2.33.0

View File

@ -0,0 +1,36 @@
From 4fc69e8a0949c2537019466f839d9b7aee5628c9 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 20 May 2022 10:25:12 +0200
Subject: [PATCH] core/device: do not downgrade device state if it is already
enumerated
On switching root, a device may have a persistent databse. In that case,
Device.enumerated_found may have DEVICE_FOUND_UDEV flag, and it is not
necessary to downgrade the Device.deserialized_found and
Device.deserialized_state. Otherwise, the state of the device unit may
be changed plugged -> dead -> plugged, if the device has not been mounted.
Fixes #23429.
[mwilck: cherry-picked from #23437]
---
src/core/device.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/core/device.c b/src/core/device.c
index 8728630523..fcde8a420e 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -201,7 +201,8 @@ static int device_coldplug(Unit *u) {
* Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by
* device_catchup() or uevents. */
- if (!m->honor_device_enumeration && !MANAGER_IS_USER(m)) {
+ if (!m->honor_device_enumeration && !MANAGER_IS_USER(m) &&
+ !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) {
found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */
if (state == DEVICE_PLUGGED)
state = DEVICE_TENTATIVE; /* downgrade state */
--
2.33.0

View File

@ -0,0 +1,28 @@
From f33bc87989a87475ed41bc9cd715c4cbb18ee389 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 1 May 2022 21:42:43 +0900
Subject: [PATCH] core/device: drop unnecessary condition
---
src/core/device.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/core/device.c b/src/core/device.c
index 44425cda3c..934676287e 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -179,10 +179,7 @@ static void device_catchup(Unit *u) {
assert(d);
- /* Second, let's update the state with the enumerated state if it's different */
- if (d->enumerated_found == d->found)
- return;
-
+ /* Second, let's update the state with the enumerated state */
device_update_found_one(d, d->enumerated_found, DEVICE_FOUND_MASK);
}
--
2.33.0

View File

@ -0,0 +1,117 @@
From 75d7b5989f99125e52d5c0e5656fa1cd0fae2405 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 29 Apr 2022 20:29:11 +0900
Subject: [PATCH] core/device: ignore DEVICE_FOUND_UDEV bit on switching root
The issue #12953 is caused by the following:
On switching root,
- deserialized_found == DEVICE_FOUND_UDEV | DEVICE_FOUND_MOUNT,
- deserialized_state == DEVICE_PLUGGED,
- enumerated_found == DEVICE_FOUND_MOUNT,
On switching root, most devices are not found by the enumeration process.
Hence, the device state is set to plugged by device_coldplug(), and then
changed to the dead state in device_catchup(). So the corresponding
mount point is unmounted. Later when the device is processed by udevd, it
will be changed to plugged state again.
The issue #23208 is caused by the fact that generated udev database in
initramfs and the main system are often different.
So, the two issues have the same root; we should not honor
DEVICE_FOUND_UDEV bit in the deserialized_found on switching root.
This partially reverts c6e892bc0eebe1d42c282bd2d8bae149fbeba85f.
Fixes #12953 and #23208.
Replaces #23215.
Co-authored-by: Martin Wilck <mwilck@suse.com>
---
src/core/device.c | 59 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 49 insertions(+), 10 deletions(-)
diff --git a/src/core/device.c b/src/core/device.c
index 934676287e..1a4563a3d9 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -163,14 +163,57 @@ static int device_coldplug(Unit *u) {
assert(d->state == DEVICE_DEAD);
/* First, let's put the deserialized state and found mask into effect, if we have it. */
+ if (d->deserialized_state < 0)
+ return 0;
+
+ Manager *m = u->manager;
+ DeviceFound found = d->deserialized_found;
+ DeviceState state = d->deserialized_state;
+
+ /* On initial boot, switch-root, reload, reexecute, the following happen:
+ * 1. MANAGER_IS_RUNNING() == false
+ * 2. enumerate devices: manager_enumerate() -> device_enumerate()
+ * Device.enumerated_found is set.
+ * 3. deserialize devices: manager_deserialize() -> device_deserialize()
+ * Device.deserialize_state and Device.deserialized_found are set.
+ * 4. coldplug devices: manager_coldplug() -> device_coldplug()
+ * deserialized properties are copied to the main properties.
+ * 5. MANAGER_IS_RUNNING() == true: manager_ready()
+ * 6. catchup devices: manager_catchup() -> device_catchup()
+ * Device.enumerated_found is applied to Device.found, and state is updated based on that.
+ *
+ * Notes:
+ * - On initial boot, no udev database exists. Hence, no devices are enumerated in the step 2.
+ * Also, there is no deserialized device. Device units are (a) generated based on dependencies of
+ * other units, or (b) generated when uevents are received.
+ *
+ * - On switch-root, the udev databse may be cleared, except for devices with sticky bit, i.e.
+ * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general,
+ * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be
+ * ignored, as udev rules in initramfs and the main system are often different. If the deserialized
+ * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE (or DEVICE_DEAD if nobody
+ * sees the device). Unlike the other starting mode, Manager.honor_device_enumeration == false
+ * (maybe, it is better to rename the flag) when device_coldplug() and device_catchup() are called.
+ * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd
+ * will (re-)process all devices, and the Device.found and Device.state will be adjusted.
+ *
+ * - On reload or reexecute, we can trust enumerated_found, deserialized_found, and deserialized_state.
+ * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by
+ * device_catchup() or uevents. */
+
+ if (!m->honor_device_enumeration && !MANAGER_IS_USER(m)) {
+ found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */
+ if (state == DEVICE_PLUGGED)
+ state = DEVICE_TENTATIVE; /* downgrade state */
+ if (found == DEVICE_NOT_FOUND)
+ state = DEVICE_DEAD; /* If nobody sees the device, downgrade more */
+ }
- if (d->deserialized_state < 0 ||
- (d->deserialized_state == d->state &&
- d->deserialized_found == d->found))
+ if (d->found == found && d->state == state)
return 0;
- d->found = d->deserialized_found;
- device_set_state(d, d->deserialized_state);
+ d->found = found;
+ device_set_state(d, state);
return 0;
}
@@ -644,13 +687,9 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no
}
static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
- Manager *m;
-
assert(d);
- m = UNIT(d)->manager;
-
- if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) {
+ if (MANAGER_IS_RUNNING(UNIT(d)->manager)) {
DeviceFound n, previous;
/* When we are already running, then apply the new mask right-away, and trigger state changes
--
2.33.0

View File

@ -0,0 +1,64 @@
From 54a4d71509c0f3401aa576346754a0781795214a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 25 Oct 2022 21:40:21 +0900
Subject: [PATCH] core/device: update comment
---
src/core/device.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/src/core/device.c b/src/core/device.c
index 0bca0ff..9d694aa 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -172,7 +172,7 @@ static int device_coldplug(Unit *u) {
* 1. MANAGER_IS_RUNNING() == false
* 2. enumerate devices: manager_enumerate() -> device_enumerate()
* Device.enumerated_found is set.
- * 3. deserialize devices: manager_deserialize() -> device_deserialize()
+ * 3. deserialize devices: manager_deserialize() -> device_deserialize_item()
* Device.deserialize_state and Device.deserialized_found are set.
* 4. coldplug devices: manager_coldplug() -> device_coldplug()
* deserialized properties are copied to the main properties.
@@ -187,22 +187,27 @@ static int device_coldplug(Unit *u) {
*
* - On switch-root, the udev databse may be cleared, except for devices with sticky bit, i.e.
* OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general,
- * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be
- * ignored, as udev rules in initramfs and the main system are often different. If the deserialized
- * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE. Unlike the other starting
- * mode, MANAGER_IS_SWITCHING_ROOT() is true when device_coldplug() and device_catchup() are called.
- * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd
- * will (re-)process all devices, and the Device.found and Device.state will be adjusted.
+ * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the
+ * Device.deserialized_found must be ignored, as udev rules in initrd and the main system are often
+ * different. If the deserialized state is DEVICE_PLUGGED, we need to downgrade it to
+ * DEVICE_TENTATIVE. Unlike the other starting mode, MANAGER_IS_SWITCHING_ROOT() is true when
+ * device_coldplug() and device_catchup() are called. Hence, let's conditionalize the operations by
+ * using the flag. After switch-root, systemd-udevd will (re-)process all devices, and the
+ * Device.found and Device.state will be adjusted.
*
- * - On reload or reexecute, we can trust enumerated_found, deserialized_found, and deserialized_state.
- * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by
- * device_catchup() or uevents. */
+ * - On reload or reexecute, we can trust Device.enumerated_found, Device.deserialized_found, and
+ * Device.deserialized_state. Of course, deserialized parameters may be outdated, but the unit
+ * state can be adjusted later by device_catchup() or uevents. */
if (MANAGER_IS_SWITCHING_ROOT(m) &&
!FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) {
- found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */
+ /* The device has not been enumerated. On switching-root, such situation is natural. See the
+ * above comment. To prevent problematic state transition active → dead → active, let's
+ * drop the DEVICE_FOUND_UDEV flag and downgrade state to DEVICE_TENTATIVE(activating). See
+ * issue #12953 and #23208. */
+ found &= ~DEVICE_FOUND_UDEV;
if (state == DEVICE_PLUGGED)
- state = DEVICE_TENTATIVE; /* downgrade state */
+ state = DEVICE_TENTATIVE;
}
if (d->found == found && d->state == state)
--
2.33.0

View File

@ -0,0 +1,42 @@
From b6c86ae28149c4abb2f0bd6acab13153382da9e7 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Oct 2022 01:18:05 +0900
Subject: [PATCH] core/device: verify device syspath on switching root
Otherwise, if a device is removed while switching root, then the
corresponding .device unit will never go to inactive state.
This replaces the code dropped by cf1ac0cfe44997747b0f857a1d0b67cea1298272.
Fixes #25106.
---
src/core/device.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/core/device.c b/src/core/device.c
index 7e354b2b4a..6e07f2745b 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -305,6 +305,19 @@ static int device_coldplug(Unit *u) {
found &= ~DEVICE_FOUND_UDEV;
if (state == DEVICE_PLUGGED)
state = DEVICE_TENTATIVE;
+
+ /* Also check the validity of the device syspath. Without this check, if the device was
+ * removed while switching root, it would never go to inactive state, as both Device.found
+ * and Device.enumerated_found do not have the DEVICE_FOUND_UDEV flag, so device_catchup() in
+ * device_update_found_one() does nothing in most cases. See issue #25106. Note that the
+ * syspath field is only serialized when systemd is sufficiently new and the device has been
+ * already processed by udevd. */
+ if (d->deserialized_sysfs) {
+ _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+
+ if (sd_device_new_from_syspath(&dev, d->deserialized_sysfs) < 0)
+ state = DEVICE_DEAD;
+ }
}
if (d->found == found && d->state == state)
--
2.33.0

View File

@ -0,0 +1,91 @@
From d35fe8c0afaa55441608cb7bbfa4af908e1ea8e3 Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Thu, 5 May 2022 08:49:56 +0200
Subject: [PATCH] core: introduce MANAGER_IS_SWITCHING_ROOT() helper function
Will be used by the following commit.
---
src/core/main.c | 3 +++
src/core/manager.c | 6 ++++++
src/core/manager.h | 6 ++++++
3 files changed, 15 insertions(+)
diff --git a/src/core/main.c b/src/core/main.c
index 1213ad6..df4fb9d 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1981,6 +1981,8 @@ static int invoke_main_loop(
return 0;
case MANAGER_SWITCH_ROOT:
+ manager_set_switching_root(m, true);
+
if (!m->switch_root_init) {
r = prepare_reexecute(m, &arg_serialization, ret_fds, true);
if (r < 0) {
@@ -2899,6 +2901,7 @@ int main(int argc, char *argv[]) {
set_manager_defaults(m);
set_manager_settings(m);
manager_set_first_boot(m, first_boot);
+ manager_set_switching_root(m, arg_switched_root);
/* Remember whether we should queue the default job */
queue_default_job = !arg_serialization || arg_switched_root;
diff --git a/src/core/manager.c b/src/core/manager.c
index abc63a7..d3b7fc5 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -756,6 +756,10 @@ static int manager_setup_sigchld_event_source(Manager *m) {
return 0;
}
+void manager_set_switching_root(Manager *m, bool switching_root) {
+ m->switching_root = MANAGER_IS_SYSTEM(m) && switching_root;
+}
+
int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **_m) {
_cleanup_(manager_freep) Manager *m = NULL;
const char *e;
@@ -1799,6 +1803,8 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
manager_ready(m);
+ manager_set_switching_root(m, false);
+
return 0;
}
diff --git a/src/core/manager.h b/src/core/manager.h
index 14a80b3..453706c 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -400,6 +400,9 @@ struct Manager {
char *switch_root;
char *switch_root_init;
+ /* This is true before and after switching root. */
+ bool switching_root;
+
/* This maps all possible path prefixes to the units needing
* them. It's a hashmap with a path string as key and a Set as
* value where Unit objects are contained. */
@@ -461,6 +464,8 @@ static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
/* The objective is set to OK as soon as we enter the main loop, and set otherwise as soon as we are done with it */
#define MANAGER_IS_RUNNING(m) ((m)->objective == MANAGER_OK)
+#define MANAGER_IS_SWITCHING_ROOT(m) ((m)->switching_root)
+
#define MANAGER_IS_TEST_RUN(m) ((m)->test_run_flags != 0)
int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **m);
@@ -525,6 +530,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason);
void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason);
void manager_set_first_boot(Manager *m, bool b);
+void manager_set_switching_root(Manager *m, bool switching_root);
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
--
2.33.0

View File

@ -0,0 +1,91 @@
From fe432460c2ecbd3dd7f0fa16278b9d4ca57a0de3 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Wed, 10 May 2023 13:54:15 +0800
Subject: [PATCH] core: only refuse Type=dbus service enqueuing if dbus has
stop job
Follow-up for #27579
In #27579 we refused all StartUnit requests for Type=dbus units
if dbus is not running, which means if dbus is manually stopped,
user can't use systemctl to start Type=dbus units again, which
is incorrect.
The only culprit that leads to the cancellation of the whole
transaction mentioned in #26799 is job type conflict on dbus.
So let's relax the restriction and only refuse job enqueuing
if dbus has a stop job.
To summarize, the case we want to avoid is:
1. dbus has a stop job installed
2. StartUnit/ActivationRequest is received
3. Type=dbus service gets started, which has Requires=dbus.socket
4. dbus is pulled in again, resulting in job type conflict
What we can support is:
1. dbus is already stopped
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
3. Type=dbus service gets started, which will wait for dbus to start
4. dbus is started again, thus the job for Type=dbus service
Replaces #27590
Fixes #27588
---
src/core/dbus-unit.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 295e271..24e4d25 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -1849,6 +1849,7 @@ int bus_unit_queue_job(
sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ const char *dbus_unit;
int r;
assert(message);
@@ -1879,13 +1880,30 @@ int bus_unit_queue_job(
(type == JOB_STOP && u->refuse_manual_stop) ||
(IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
(type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
-
- /* dbus-broker issues StartUnit for activation requests, so let's apply the same check
- * used in signal_activation_request(). */
- if (type == JOB_START && u->type == UNIT_SERVICE &&
- SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager))
- return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running.");
+ return sd_bus_error_setf(error,
+ BUS_ERROR_ONLY_BY_DEPENDENCY,
+ "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
+ u->id);
+
+ /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
+ * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
+ * job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting
+ * job enqueuing early.
+ *
+ * Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending()
+ * here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl
+ * to start Type=dbus services even when dbus is inactive. */
+ if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS)
+ FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
+ Unit *dbus;
+
+ dbus = manager_get_unit(u->manager, dbus_unit);
+ if (dbus && unit_stop_pending(dbus))
+ return sd_bus_error_setf(error,
+ BUS_ERROR_SHUTTING_DOWN,
+ "Operation for unit %s refused, D-Bus is shutting down.",
+ u->id);
+ }
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
--
2.33.0

View File

@ -0,0 +1,43 @@
From 53964fd26b4a01191609ffc064aa8ccccd28e377 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Tue, 9 May 2023 00:07:45 +0800
Subject: [PATCH] core: refuse dbus activation if dbus is not running
dbus-broker issues StartUnit directly for activation requests,
so let's add a check on bus state in bus_unit_queue_job to refuse
that if dbus is not running.
Replaces #27570
Closes #26799
---
src/core/dbus-unit.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index c42ae5e..295e271 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -21,6 +21,7 @@
#include "path-util.h"
#include "process-util.h"
#include "selinux-access.h"
+#include "service.h"
#include "signal-util.h"
#include "special.h"
#include "string-table.h"
@@ -1880,6 +1881,12 @@ int bus_unit_queue_job(
(type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
+ /* dbus-broker issues StartUnit for activation requests, so let's apply the same check
+ * used in signal_activation_request(). */
+ if (type == JOB_START && u->type == UNIT_SERVICE &&
+ SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager))
+ return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running.");
+
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
return r;
--
2.33.0

View File

@ -0,0 +1,113 @@
From 7870de03c52982290f9b8ae11eb4d89db66f4be3 Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Thu, 5 May 2022 11:11:57 +0200
Subject: [PATCH] core: replace m->honor_device_enumeration with
MANAGER_IS_SWITCHING_ROOT()
---
src/core/device.c | 7 +++----
src/core/manager.c | 21 +--------------------
src/core/manager.h | 2 --
3 files changed, 4 insertions(+), 26 deletions(-)
diff --git a/src/core/device.c b/src/core/device.c
index d9669e3..0bca0ff 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -189,9 +189,8 @@ static int device_coldplug(Unit *u) {
* OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general,
* we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be
* ignored, as udev rules in initramfs and the main system are often different. If the deserialized
- * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE (or DEVICE_DEAD if nobody
- * sees the device). Unlike the other starting mode, Manager.honor_device_enumeration == false
- * (maybe, it is better to rename the flag) when device_coldplug() and device_catchup() are called.
+ * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE. Unlike the other starting
+ * mode, MANAGER_IS_SWITCHING_ROOT() is true when device_coldplug() and device_catchup() are called.
* Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd
* will (re-)process all devices, and the Device.found and Device.state will be adjusted.
*
@@ -199,7 +198,7 @@ static int device_coldplug(Unit *u) {
* Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by
* device_catchup() or uevents. */
- if (!m->honor_device_enumeration && !MANAGER_IS_USER(m) &&
+ if (MANAGER_IS_SWITCHING_ROOT(m) &&
!FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) {
found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */
if (state == DEVICE_PLUGGED)
diff --git a/src/core/manager.c b/src/core/manager.c
index 5ed7191..91e9b2a 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1689,8 +1689,6 @@ static void manager_ready(Manager *m) {
/* Let's finally catch up with any changes that took place while we were reloading/reexecing */
manager_catchup(m);
-
- m->honor_device_enumeration = true;
}
static Manager* manager_reloading_start(Manager *m) {
@@ -3259,9 +3257,6 @@ int manager_serialize(
(void) serialize_bool(f, "taint-logged", m->taint_logged);
(void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
- /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
- (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
-
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
(void) serialize_item(f, "show-status-overridden",
show_status_to_string(m->show_status_overridden));
@@ -3635,15 +3630,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
else
m->service_watchdogs = b;
- } else if ((val = startswith(l, "honor-device-enumeration="))) {
- int b;
-
- b = parse_boolean(val);
- if (b < 0)
- log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
- else
- m->honor_device_enumeration = b;
-
} else if ((val = startswith(l, "show-status-overridden="))) {
ShowStatus s;
@@ -3767,7 +3753,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
(void) deserialize_dual_timestamp(val, m->timestamps + q);
- else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
+ else if (!STARTSWITH_SET(l, "kdbus-fd=", "honor-device-enumeration=")) /* ignore deprecated values */
log_notice("Unknown serialization item '%s', ignoring.", l);
}
}
@@ -3860,11 +3846,6 @@ int manager_reload(Manager *m) {
assert(m->n_reloading > 0);
m->n_reloading--;
- /* On manager reloading, device tag data should exists, thus, we should honor the results of device
- * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So,
- * let's always set the flag here for safety. */
- m->honor_device_enumeration = true;
-
manager_ready(m);
m->send_reloading_done = true;
diff --git a/src/core/manager.h b/src/core/manager.h
index 453706c..67c204f 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -442,8 +442,6 @@ struct Manager {
unsigned sigchldgen;
unsigned notifygen;
- bool honor_device_enumeration;
-
VarlinkServer *varlink_server;
/* Only systemd-oomd should be using this to subscribe to changes in ManagedOOM settings */
Varlink *managed_oom_varlink_request;
--
2.33.0

View File

@ -0,0 +1,47 @@
From 4617bad0a3b5d8026243cb4e72a5cae25ca106f0 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 6 May 2022 14:01:22 +0900
Subject: [PATCH] core/slice: make slice_freezer_action() return 0 if freezing
state is unchanged
Fixes #23278.
(cherry picked from commit d171e72e7afa11b238ba20758384d223b0c76e39)
---
src/core/slice.c | 6 +-----
src/core/unit.c | 2 ++
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/core/slice.c b/src/core/slice.c
index 2e43c00119..c453aa033e 100644
--- a/src/core/slice.c
+++ b/src/core/slice.c
@@ -389,11 +389,7 @@ static int slice_freezer_action(Unit *s, FreezerAction action) {
return r;
}
- r = unit_cgroup_freezer_action(s, action);
- if (r < 0)
- return r;
-
- return 1;
+ return unit_cgroup_freezer_action(s, action);
}
static int slice_freeze(Unit *s) {
diff --git a/src/core/unit.c b/src/core/unit.c
index b233aca28c..3bceba1317 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -5831,6 +5831,8 @@ static int unit_freezer_action(Unit *u, FreezerAction action) {
if (r <= 0)
return r;
+ assert(IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING));
+
return 1;
}
--
2.33.0

View File

@ -0,0 +1,61 @@
From 82362b16ac842fc38340d21ebf39b259c5edaed3 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 10 May 2022 14:09:24 +0900
Subject: [PATCH] core/timer: fix memleak
Fixes #23326.
(cherry picked from commit d3ab7b8078944db28bc621f43dd942a3c878fffb)
---
src/core/timer.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index a13b864741..0dc49dd46b 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -135,6 +135,7 @@ static int timer_add_trigger_dependencies(Timer *t) {
}
static int timer_setup_persistent(Timer *t) {
+ _cleanup_free_ char *stamp_path = NULL;
int r;
assert(t);
@@ -148,13 +149,13 @@ static int timer_setup_persistent(Timer *t) {
if (r < 0)
return r;
- t->stamp_path = strjoin("/var/lib/systemd/timers/stamp-", UNIT(t)->id);
+ stamp_path = strjoin("/var/lib/systemd/timers/stamp-", UNIT(t)->id);
} else {
const char *e;
e = getenv("XDG_DATA_HOME");
if (e)
- t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id);
+ stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id);
else {
_cleanup_free_ char *h = NULL;
@@ -163,14 +164,14 @@ static int timer_setup_persistent(Timer *t) {
if (r < 0)
return log_unit_error_errno(UNIT(t), r, "Failed to determine home directory: %m");
- t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id);
+ stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id);
}
}
- if (!t->stamp_path)
+ if (!stamp_path)
return log_oom();
- return 0;
+ return free_and_replace(t->stamp_path, stamp_path);
}
static uint64_t timer_get_fixed_delay_hash(Timer *t) {
--
2.33.0

View File

@ -0,0 +1,26 @@
From 38410e13ec9b1b67364f2f0af3b27d9e934bcd96 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 10 May 2022 14:10:17 +0900
Subject: [PATCH] core/timer: fix potential use-after-free
(cherry picked from commit 756491af392a99c4286d876b0041535e50df80ad)
---
src/core/timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index 0dc49dd46b..b439802bc2 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -68,7 +68,7 @@ static void timer_done(Unit *u) {
t->monotonic_event_source = sd_event_source_disable_unref(t->monotonic_event_source);
t->realtime_event_source = sd_event_source_disable_unref(t->realtime_event_source);
- free(t->stamp_path);
+ t->stamp_path = mfree(t->stamp_path);
}
static int timer_verify(Timer *t) {
--
2.33.0

View File

@ -0,0 +1,30 @@
From 3daae8785764304a65892ddcd548b6aae16c9463 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 9 May 2022 00:56:05 +0900
Subject: [PATCH] core/unit: fix use-after-free
Fixes #23312.
(cherry picked from commit 734582830b58e000a26e18807ea277c18778573c)
---
src/core/unit.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index af6cf097fc..b233aca28c 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -671,8 +671,8 @@ Unit* unit_free(Unit *u) {
unit_dequeue_rewatch_pids(u);
- sd_bus_slot_unref(u->match_bus_slot);
- sd_bus_track_unref(u->bus_track);
+ 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);
--
2.33.0

View File

@ -0,0 +1,89 @@
From 1a09fb995e0e84c2a5f40945248644b174863c6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 14 Oct 2022 15:02:20 +0200
Subject: [PATCH] manager: allow transient units to have drop-ins
In https://github.com/containers/podman/issues/16107, starting of a transient
slice unit fails because there's a "global" drop-in
/usr/lib/systemd/user/slice.d/10-oomd-per-slice-defaults.conf (provided by
systemd-oomd-defaults package to install some default oomd policy). This means
that the unit_is_pristine() check fails and starting of the unit is forbidden.
It seems pretty clear to me that dropins at any other level then the unit
should be ignored in this check: we now have multiple layers of drop-ins
(for each level of the cgroup path, and also "global" ones for a specific
unit type). If we install a "global" drop-in, we wouldn't be able to start
any transient units of that type, which seems undesired.
In principle we could reject dropins at the unit level, but I don't think that
is useful. The whole reason for drop-ins is that they are "add ons", and there
isn't any particular reason to disallow them for transient units. It would also
make things harder to implement and describe: one place for drop-ins is good,
but another is bad. (And as a corner case: for instanciated units, a drop-in
in the template would be acceptable, but a instance-specific drop-in bad?)
Thus, $subject.
While at it, adjust the message. All the conditions in unit_is_pristine()
essentially mean that it wasn't loaded (e.g. it might be in an error state),
and that it doesn't have a fragment path (now that drop-ins are acceptable).
If there's a job for it, it necessarilly must have been loaded. If it is
merged into another unit, it also was loaded and found to be an alias.
Based on the discussion in the bugs, it seems that the current message
is far from obvious ;)
Fixes https://github.com/containers/podman/issues/16107,
https://bugzilla.redhat.com/show_bug.cgi?id=2133792.
(cherry picked from commit 1f83244641f13a9cb28fdac7e3c17c5446242dfb)
(cherry picked from commit 98a45608c4bf5aa1ba9b603ac2e5730f13659d88)
---
src/core/dbus-manager.c | 2 +-
src/core/unit.c | 14 ++++++++------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 1a3098ceb1..9a2a5531c6 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -901,7 +901,7 @@ static int transient_unit_from_message(
if (!unit_is_pristine(u))
return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
- "Unit %s already exists.", name);
+ "Unit %s was already loaded or has a fragment file.", name);
/* OK, the unit failed to load and is unreferenced, now let's
* fill in the transient data instead */
diff --git a/src/core/unit.c b/src/core/unit.c
index a7b3208432..60e4e42d2f 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -4806,16 +4806,18 @@ int unit_fail_if_noncanonical(Unit *u, const char* where) {
bool unit_is_pristine(Unit *u) {
assert(u);
- /* Check if the unit already exists or is already around,
- * in a number of different ways. Note that to cater for unit
- * types such as slice, we are generally fine with units that
- * are marked UNIT_LOADED even though nothing was actually
- * loaded, as those unit types don't require a file on disk. */
+ /* Check if the unit already exists or is already around, in a number of different ways. Note that to
+ * cater for unit types such as slice, we are generally fine with units that are marked UNIT_LOADED
+ * even though nothing was actually loaded, as those unit types don't require a file on disk.
+ *
+ * Note that we don't check for drop-ins here, because we allow drop-ins for transient units
+ * identically to non-transient units, both unit-specific and hierarchical. E.g. for a-b-c.service:
+ * service.d/….conf, a-.service.d/….conf, a-b-.service.d/….conf, a-b-c.service.d/….conf.
+ */
return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) &&
!u->fragment_path &&
!u->source_path &&
- strv_isempty(u->dropin_paths) &&
!u->job &&
!u->merged_into;
}
--
2.33.0

View File

@ -0,0 +1,40 @@
From b146a7345b69de16e88347acadb3783ffeeaad9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 14 Oct 2022 14:40:24 +0200
Subject: [PATCH] manager: reformat boolean expression in unit_is_pristine()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Not not IN_SET(…) is just too much for my poor brain. Let's invert
the expression to make it easier to undertand.
---
src/core/unit.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index d6bea2080f..5016114cb4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -4850,12 +4850,12 @@ bool unit_is_pristine(Unit *u) {
* are marked UNIT_LOADED even though nothing was actually
* loaded, as those unit types don't require a file on disk. */
- return !(!IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) ||
- u->fragment_path ||
- u->source_path ||
- !strv_isempty(u->dropin_paths) ||
- u->job ||
- u->merged_into);
+ return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) &&
+ !u->fragment_path &&
+ !u->source_path &&
+ strv_isempty(u->dropin_paths) &&
+ !u->job &&
+ !u->merged_into;
}
pid_t unit_control_pid(Unit *u) {
--
2.33.0

View File

@ -0,0 +1,59 @@
From f1a8b69808777aff37c036fd94a0275873d12407 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 23 Feb 2023 07:31:01 +0900
Subject: [PATCH] sd-event: always initialize sd_event.perturb
If the boot ID cannot be obtained, let's first fallback to the machine
ID, and if still cannot, then let's use 0.
Otherwise, no timer event source cannot be triggered.
Fixes #26549.
(cherry picked from commit 6d2326e036ceed30f9ccdb0266713c10a44dcf6c)
(cherry picked from commit 58c821af607b61738b7b72ad1452e70f648689a6)
(cherry picked from commit 78976199b2e016600c3f7cf8f39747c9ef6c853b)
(cherry picked from commit ac04d804c30f519918866fb4eeb3bc4a9cbadd43)
---
src/libsystemd/sd-event/sd-event.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 89accdce00..37565b17be 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -1126,22 +1126,21 @@ _public_ int sd_event_add_io(
}
static void initialize_perturb(sd_event *e) {
- sd_id128_t bootid = {};
+ sd_id128_t id = {};
- /* When we sleep for longer, we try to realign the wakeup to
- the same time within each minute/second/250ms, so that
- events all across the system can be coalesced into a single
- CPU wakeup. However, let's take some system-specific
- randomness for this value, so that in a network of systems
- with synced clocks timer events are distributed a
- bit. Here, we calculate a perturbation usec offset from the
- boot ID. */
+ /* When we sleep for longer, we try to realign the wakeup to the same time within each
+ * minute/second/250ms, so that events all across the system can be coalesced into a single CPU
+ * wakeup. However, let's take some system-specific randomness for this value, so that in a network
+ * of systems with synced clocks timer events are distributed a bit. Here, we calculate a
+ * perturbation usec offset from the boot ID (or machine ID if failed, e.g. /proc is not mounted). */
if (_likely_(e->perturb != USEC_INFINITY))
return;
- if (sd_id128_get_boot(&bootid) >= 0)
- e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE;
+ if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) > 0)
+ e->perturb = (id.qwords[0] ^ id.qwords[1]) % USEC_PER_MINUTE;
+ else
+ e->perturb = 0; /* This is a super early process without /proc and /etc ?? */
}
static int event_setup_timer_fd(
--
2.33.0

View File

@ -0,0 +1,31 @@
From 056fbe84ef67168adcaf41baa37de1b712f6fb74 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 23 Feb 2023 07:31:01 +0900
Subject: [PATCH] sd-event: fix error handling
Follow-up for 6d2326e036ceed30f9ccdb0266713c10a44dcf6c.
(cherry picked from commit 1912f790fee9e0182acd77b77496f500094a140d)
(cherry picked from commit a719c2ec2f410f8b979cec04dcdac9af470ee52b)
(cherry picked from commit dd6561ff3e12314d41954b7ea8e3627101931a18)
(cherry picked from commit 8be4af42044969bc268b32ffe9570cee733fecf6)
---
src/libsystemd/sd-event/sd-event.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 37565b17be..df4d9037ac 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -1137,7 +1137,7 @@ static void initialize_perturb(sd_event *e) {
if (_likely_(e->perturb != USEC_INFINITY))
return;
- if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) > 0)
+ if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) >= 0)
e->perturb = (id.qwords[0] ^ id.qwords[1]) % USEC_PER_MINUTE;
else
e->perturb = 0; /* This is a super early process without /proc and /etc ?? */
--
2.33.0

View File

@ -0,0 +1,27 @@
From 5e069e405a73ff5a406598436fe21d6dabbb281c Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 May 2022 16:05:04 +0900
Subject: [PATCH] sd-lldp: use memcpy_safe() as the buffer size may be zero
(cherry picked from commit 87bd4b79e692f384c2190c9b3824df4853333018)
---
src/libsystemd-network/lldp-neighbor.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c
index 372bc2ef93..bc98235ce1 100644
--- a/src/libsystemd-network/lldp-neighbor.c
+++ b/src/libsystemd-network/lldp-neighbor.c
@@ -652,7 +652,8 @@ int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t ra
if (!n)
return -ENOMEM;
- memcpy(LLDP_NEIGHBOR_RAW(n), raw, raw_size);
+ memcpy_safe(LLDP_NEIGHBOR_RAW(n), raw, raw_size);
+
r = lldp_neighbor_parse(n);
if (r < 0)
return r;
--
2.33.0

View File

@ -0,0 +1,31 @@
From 412b89a6e8055f2c8c9db4b6b847f081e00461ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 6 May 2022 17:36:47 +0200
Subject: [PATCH] shared/bootspec: avoid crashing on config without a value
(cherry picked from commit b6bd2562ebb01b48cdb55a970d9daa1799b59876)
---
src/shared/bootspec.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c
index 0076092c2a..9e2b2899bd 100644
--- a/src/shared/bootspec.c
+++ b/src/shared/bootspec.c
@@ -124,6 +124,13 @@ static int boot_entry_load(
continue;
}
+ if (isempty(p)) {
+ /* Some fields can reasonably have an empty value. In other cases warn. */
+ if (!STR_IN_SET(field, "options", "devicetree-overlay"))
+ log_warning("%s:%u: Field %s without value", tmp.path, line, field);
+ continue;
+ }
+
if (streq(field, "title"))
r = free_and_strdup(&tmp.title, p);
else if (streq(field, "version"))
--
2.33.0

View File

@ -0,0 +1,34 @@
From c1dbf637d7f5588a19b5d9ea812fee2e68a6dcfa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 May 2022 14:28:36 +0200
Subject: [PATCH] shared/json: fix memory leak on failed normalization
We need to increase the counter immediately after taking the ref,
otherwise we may not unref it properly if we fail before incrementing.
(cherry picked from commit 7e4be6a5845f983a299932d4ccb2c4349cf8dd52)
---
src/shared/json.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/shared/json.c b/src/shared/json.c
index dff95eda26..711aa36c87 100644
--- a/src/shared/json.c
+++ b/src/shared/json.c
@@ -4680,10 +4680,11 @@ int json_variant_normalize(JsonVariant **v) {
if (!a)
return -ENOMEM;
- for (i = 0; i < m; i++) {
+ for (i = 0; i < m; ) {
a[i] = json_variant_ref(json_variant_by_index(*v, i));
+ i++;
- r = json_variant_normalize(a + i);
+ r = json_variant_normalize(&a[i-1]);
if (r < 0)
goto finish;
}
--
2.33.0

View File

@ -0,0 +1,31 @@
From 6100e1dded709f681aca0cf913095e2591a54e33 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 21 May 2022 03:03:21 +0900
Subject: [PATCH] sysext: refuse empty release ID to avoid triggering assertion
Otherwise, the assertion in extension_release_validate() will be
triggered.
(cherry picked from commit 30e29edf4c0bb025aa7dc03c415b727fddf996ac)
---
src/sysext/sysext.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index 60789e0f2c..4245bf1760 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -483,6 +483,10 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
"SYSEXT_LEVEL", &host_os_release_sysext_level);
if (r < 0)
return log_error_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(arg_root));
+ if (isempty(host_os_release_id))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "'ID' field not found or empty in 'os-release' data of OS tree '%s': %m",
+ empty_to_root(arg_root));
/* Let's now mount all images */
HASHMAP_FOREACH(img, images) {
--
2.33.0

View File

@ -0,0 +1,113 @@
From 1fb7f8e15e19fbe61230b70203b0c35fca54f0a0 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 25 May 2022 17:39:14 +0200
Subject: [PATCH] test: cover initrd->sysroot transition in TEST-24
This should cover cases regarding devices with `OPTIONS+="db_persist"`
during initrd->sysroot transition.
See:
* https://github.com/systemd/systemd/issues/23429
* https://github.com/systemd/systemd/pull/23218
* https://github.com/systemd/systemd/pull/23489
* https://bugzilla.redhat.com/show_bug.cgi?id=2087225
---
test/TEST-24-CRYPTSETUP/test.sh | 61 ++++++++++++++++-----------------
1 file changed, 29 insertions(+), 32 deletions(-)
diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh
index 2c13126..a52848b 100755
--- a/test/TEST-24-CRYPTSETUP/test.sh
+++ b/test/TEST-24-CRYPTSETUP/test.sh
@@ -9,6 +9,13 @@ TEST_FORCE_NEWIMAGE=1
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
+PART_UUID="deadbeef-dead-dead-beef-000000000000"
+DM_NAME="test24_varcrypt"
+# Mount the keyfile only in initrd (hence rd.luks.key), since it resides on
+# the rootfs and we would get a (harmless) error when trying to mount it after
+# switching root (since rootfs is already mounted)
+KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME rd.luks.key=$PART_UUID=/etc/varkey:LABEL=systemd_boot"
+
check_result_qemu() {
local ret=1
@@ -16,12 +23,12 @@ check_result_qemu() {
[[ -e "${initdir:?}/testok" ]] && ret=0
[[ -f "$initdir/failed" ]] && cp -a "$initdir/failed" "${TESTDIR:?}"
- cryptsetup luksOpen "${LOOPDEV:?}p2" varcrypt <"$TESTDIR/keyfile"
- mount /dev/mapper/varcrypt "$initdir/var"
+ cryptsetup luksOpen "${LOOPDEV:?}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile"
+ mount "/dev/mapper/$DM_NAME" "$initdir/var"
save_journal "$initdir/var/log/journal"
_umount_dir "$initdir/var"
_umount_dir "$initdir"
- cryptsetup luksClose /dev/mapper/varcrypt
+ cryptsetup luksClose "/dev/mapper/$DM_NAME"
[[ -f "$TESTDIR/failed" ]] && cat "$TESTDIR/failed"
echo "${JOURNAL_LIST:-No journals were saved}"
@@ -34,39 +41,29 @@ test_create_image() {
create_empty_image_rootdir
echo -n test >"${TESTDIR:?}/keyfile"
- cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile"
- cryptsetup luksOpen "${LOOPDEV}p2" varcrypt <"$TESTDIR/keyfile"
- mkfs.ext4 -L var /dev/mapper/varcrypt
+ cryptsetup -q luksFormat --uuid="$PART_UUID" --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile"
+ cryptsetup luksOpen "${LOOPDEV}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile"
+ mkfs.ext4 -L var "/dev/mapper/$DM_NAME"
mkdir -p "${initdir:?}/var"
- mount /dev/mapper/varcrypt "$initdir/var"
-
- # Create what will eventually be our root filesystem onto an overlay
- (
- LOG_LEVEL=5
- # shellcheck source=/dev/null
- source <(udevadm info --export --query=env --name=/dev/mapper/varcrypt)
- # shellcheck source=/dev/null
- source <(udevadm info --export --query=env --name="${LOOPDEV}p2")
-
- setup_basic_environment
- mask_supporting_services
-
- install_dmevent
- generate_module_dependencies
- cat >"$initdir/etc/crypttab" <<EOF
-$DM_NAME UUID=$ID_FS_UUID /etc/varkey
-EOF
- echo -n test >"$initdir/etc/varkey"
- ddebug <"$initdir/etc/crypttab"
+ mount "/dev/mapper/$DM_NAME" "$initdir/var"
+
+ LOG_LEVEL=5
+
+ setup_basic_environment
+ mask_supporting_services
+
+ install_dmevent
+ generate_module_dependencies
+
+ echo -n test >"$initdir/etc/varkey"
- cat >>"$initdir/etc/fstab" <<EOF
-/dev/mapper/varcrypt /var ext4 defaults 0 1
+ cat >>"$initdir/etc/fstab" <<EOF
+/dev/mapper/$DM_NAME /var ext4 defaults 0 1
EOF
- # Forward journal messages to the console, so we have something
- # to investigate even if we fail to mount the encrypted /var
- echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf"
- )
+ # Forward journal messages to the console, so we have something
+ # to investigate even if we fail to mount the encrypted /var
+ echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf"
}
cleanup_root_var() {
--
2.33.0

View File

@ -0,0 +1,66 @@
From b22d90e59438481b421b1eb2449e6efdfb7f2118 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 26 May 2022 13:19:11 +0200
Subject: [PATCH] test: generate a custom initrd for TEST-24 if $INITRD is
unset
Co-Authored-By: Yu Watanabe <watanabe.yu+github@gmail.com>
---
test/TEST-24-CRYPTSETUP/test.sh | 24 ++++++++++++++++++++++++
test/test-functions | 5 +++++
2 files changed, 29 insertions(+)
diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh
index a52848b..c18f4aa 100755
--- a/test/TEST-24-CRYPTSETUP/test.sh
+++ b/test/TEST-24-CRYPTSETUP/test.sh
@@ -64,6 +64,30 @@ EOF
# Forward journal messages to the console, so we have something
# to investigate even if we fail to mount the encrypted /var
echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf"
+
+ # If $INITRD wasn't provided explicitly, generate a custom one with dm-crypt
+ # support
+ if [[ -z "$INITRD" ]]; then
+ INITRD="${TESTDIR:?}/initrd.img"
+ dinfo "Generating a custom initrd with dm-crypt support in '${INITRD:?}'"
+
+ if command -v dracut >/dev/null; then
+ dracut --force --verbose --add crypt "$INITRD"
+ elif command -v mkinitcpio >/dev/null; then
+ mkinitcpio --addhooks sd-encrypt --generate "$INITRD"
+ elif command -v mkinitramfs >/dev/null; then
+ # The cryptroot hook is provided by the cryptsetup-initramfs package
+ if ! dpkg-query -s cryptsetup-initramfs; then
+ derror "Missing 'cryptsetup-initramfs' package for dm-crypt support in initrd"
+ return 1
+ fi
+
+ mkinitramfs -o "$INITRD"
+ else
+ dfatal "Unrecognized initrd generator, can't continue"
+ return 1
+ fi
+ fi
}
cleanup_root_var() {
diff --git a/test/test-functions b/test/test-functions
index bef87ca..0239bbc 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -325,6 +325,11 @@ qemu_min_version() {
# Return 0 if QEMU did run (then you must check the result state/logs for actual
# success), or 1 if QEMU is not available.
run_qemu() {
+ # If the test provided its own initrd, use it (e.g. TEST-24)
+ if [[ -z "$INITRD" && -f "${TESTDIR:?}/initrd.img" ]]; then
+ INITRD="$TESTDIR/initrd.img"
+ fi
+
if [ -f /etc/machine-id ]; then
read -r MACHINE_ID </etc/machine-id
[ -z "$INITRD" ] && [ -e "$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/initrd" ] \
--
2.33.0

View File

@ -0,0 +1,44 @@
From 6b70d3cf81088ee9226cd691bbccc4ebf4764065 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 26 May 2022 14:52:52 +0200
Subject: [PATCH] test: store the key on a separate device
---
test/TEST-24-CRYPTSETUP/test.sh | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh
index bdf630d912..b81b811654 100755
--- a/test/TEST-24-CRYPTSETUP/test.sh
+++ b/test/TEST-24-CRYPTSETUP/test.sh
@@ -12,10 +12,8 @@ TEST_FORCE_NEWIMAGE=1
PART_UUID="deadbeef-dead-dead-beef-000000000000"
DM_NAME="test24_varcrypt"
-# Mount the keyfile only in initrd (hence rd.luks.key), since it resides on
-# the rootfs and we would get a (harmless) error when trying to mount it after
-# switching root (since rootfs is already mounted)
-KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME rd.luks.key=$PART_UUID=/etc/varkey:LABEL=systemd_boot"
+KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME luks.key=$PART_UUID=/keyfile:LABEL=varcrypt_keydev"
+QEMU_OPTIONS+=" -drive format=raw,cache=unsafe,file=${STATEDIR:?}/keydev.img"
check_result_qemu() {
local ret=1
@@ -57,7 +55,13 @@ test_create_image() {
install_dmevent
generate_module_dependencies
- echo -n test >"$initdir/etc/varkey"
+ # Create a keydev
+ dd if=/dev/zero of="${STATEDIR:?}/keydev.img" bs=1M count=16
+ mkfs.ext4 -L varcrypt_keydev "$STATEDIR/keydev.img"
+ mkdir -p "$STATEDIR/keydev"
+ mount "$STATEDIR/keydev.img" "$STATEDIR/keydev"
+ echo -n test >"$STATEDIR/keydev/keyfile"
+ umount "$STATEDIR/keydev"
cat >>"$initdir/etc/fstab" <<EOF
/dev/mapper/$DM_NAME /var ext4 defaults 0 1
--
2.33.0

View File

@ -0,0 +1,46 @@
From 71d2356edffafe8c40797c64f6fb82a8885d1da9 Mon Sep 17 00:00:00 2001
From: Evgeny Vereshchagin <evvers@ya.ru>
Date: Wed, 4 May 2022 11:35:19 +0000
Subject: [PATCH] timedatectl: fix a memory leak
```
timedatectl list-timezones --no-pager
...
==164329==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 8192 byte(s) in 1 object(s) allocated from:
#0 0x7fe8a74b6f8c in reallocarray (/lib64/libasan.so.6+0xaef8c)
#1 0x7fe8a63485dc in strv_push ../src/basic/strv.c:419
#2 0x7fe8a6349419 in strv_consume ../src/basic/strv.c:490
#3 0x7fe8a634958d in strv_extend ../src/basic/strv.c:542
#4 0x7fe8a643d787 in bus_message_read_strv_extend ../src/libsystemd/sd-bus/bus-message.c:5606
#5 0x7fe8a643db9d in sd_bus_message_read_strv ../src/libsystemd/sd-bus/bus-message.c:5628
#6 0x4085fb in list_timezones ../src/timedate/timedatectl.c:314
#7 0x7fe8a61ef3e1 in dispatch_verb ../src/shared/verbs.c:103
#8 0x410f91 in timedatectl_main ../src/timedate/timedatectl.c:1025
#9 0x41111c in run ../src/timedate/timedatectl.c:1043
#10 0x411242 in main ../src/timedate/timedatectl.c:1046
#11 0x7fe8a489df1f in __libc_start_call_main (/lib64/libc.so.6+0x40f1f)
```
(cherry picked from commit a2e37d52312806b1847800df2358e61276cda052)
---
src/timedate/timedatectl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 75ca6195da..31909064cf 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -304,7 +304,7 @@ static int list_timezones(int argc, char **argv, void *userdata) {
sd_bus *bus = userdata;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
int r;
- char** zones;
+ _cleanup_strv_free_ char **zones = NULL;
r = bus_call_method(bus, bus_timedate, "ListTimezones", &error, &reply, NULL);
if (r < 0)
--
2.33.0

View File

@ -0,0 +1,31 @@
From c3fcff52912b0323e11f535fce151dc758f111e6 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 14 Aug 2022 06:00:10 +0900
Subject: [PATCH] udev/cdrom_id: check last track info
Fixes off-by-one issue.
Fixes #24306.
(cherry picked from commit 628998ecfa0d39b38874e1aecdb28022f80f3269)
(cherry picked from commit c67a388aeffcdc27ff280f01b7939005f7a9c8e9)
---
src/udev/cdrom_id/cdrom_id.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index cdb66bb3b7..964eb6988e 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -704,7 +704,7 @@ static int cd_media_toc(Context *c) {
/* Take care to not iterate beyond the last valid track as specified in
* the TOC, but also avoid going beyond the TOC length, just in case
* the last track number is invalidly large */
- for (size_t i = 4; i + 8 < len && num_tracks > 0; i += 8, --num_tracks) {
+ for (size_t i = 4; i + 8 <= len && num_tracks > 0; i += 8, --num_tracks) {
bool is_data_track;
uint32_t block;
--
2.33.0

View File

@ -0,0 +1,36 @@
From 639423416c18c3a41a8f326618e340c25585a40a Mon Sep 17 00:00:00 2001
From: Alban Bedel <alban.bedel@aerq.com>
Date: Wed, 15 Jun 2022 13:12:46 +0200
Subject: [PATCH] units: remove the restart limit on the modprobe@.service
They are various cases where the same module might be repeatedly
loaded in a short time frame, for example if a service depending on a
module keep restarting, or if many instances of such service get
started at the same time. If this happend the modprobe@.service
instance will be marked as failed because it hit the restart limit.
Overall it doesn't seems to make much sense to have a restart limit on
the modprobe service so just disable it.
Fixes: #23742
(cherry picked from commit 9625350e5381a68c1179ae4581e7586c206663e1)
(cherry picked from commit 8539a62207c9d0cc1656458eb53ffc9177b2c7c8)
---
units/modprobe@.service | 1 +
1 file changed, 1 insertion(+)
diff --git a/units/modprobe@.service b/units/modprobe@.service
index cf8baf6084..85a2c08dee 100644
--- a/units/modprobe@.service
+++ b/units/modprobe@.service
@@ -13,6 +13,7 @@ DefaultDependencies=no
Before=sysinit.target
Documentation=man:modprobe(8)
ConditionCapability=CAP_SYS_MODULE
+StartLimitIntervalSec=0
[Service]
Type=oneshot
--
2.33.0

View File

@ -71,9 +71,9 @@ index 25d058f..ddddc8e 100644
typedef struct Manager Manager;
@@ -445,6 +446,7 @@ struct Manager {
unsigned sigchldgen;
unsigned notifygen;
bool honor_device_enumeration;
+ char *default_unit_slice;
bool in_manager_catchup;

View File

@ -15,16 +15,16 @@ This patch just fix that fs will not unmounted during booting when calling
daemon-reload, if boot time is more than 10min, just ensure fs will not
unmounted during 10min after booting.
---
src/core/device.c | 16 ++++++++++++++++-
src/core/device.c | 16 +++++++++++++++-
src/core/manager.c | 5 +++++
src/core/manager.h | 1 +
3 files changed, 21 insertions(+), 1 deletion(-)
src/core/manager.h | 2 ++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/core/device.c b/src/core/device.c
index 8f30c4e..71cb2a1 100644
index 58007cc..7be59bd 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -646,7 +647,10 @@ static int device_process_new(Manager *m, sd_device *dev) {
@@ -728,7 +728,10 @@ static void device_process_new(Manager *m, sd_device *dev) {
}
static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
@ -35,7 +35,7 @@ index 8f30c4e..71cb2a1 100644
/* Didn't exist before, but does now? if so, generate a new invocation ID for it */
if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND)
@@ -659,10 +663,21 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no
@@ -741,10 +744,21 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no
/* If the device has not been seen by udev yet, but is now referenced by the kernel, then we assume the
* kernel knows it now, and udev might soon too. */
device_set_state(d, DEVICE_TENTATIVE);
@ -59,10 +59,10 @@ index 8f30c4e..71cb2a1 100644
static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
diff --git a/src/core/manager.c b/src/core/manager.c
index 41b7cf7..b948ac6 100644
index 5becd30..c5dd041 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -788,6 +788,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
@@ -811,6 +811,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
.test_run_flags = test_run_flags,
.default_oom_policy = OOM_STOP,
@ -70,7 +70,7 @@ index 41b7cf7..b948ac6 100644
};
#if ENABLE_EFI
@@ -1475,6 +1476,8 @@ static void manager_catchup(Manager *m) {
@@ -1579,6 +1580,8 @@ static void manager_catchup(Manager *m) {
log_debug("Invoking unit catchup() handlers…");
@ -79,7 +79,7 @@ index 41b7cf7..b948ac6 100644
/* Let's catch up on any state changes that happened while we were reloading/reexecing */
HASHMAP_FOREACH_KEY(u, k, m->units) {
@@ -1484,6 +1487,8 @@ static void manager_catchup(Manager *m) {
@@ -1588,6 +1591,8 @@ static void manager_catchup(Manager *m) {
unit_catchup(u);
}
@ -89,17 +89,18 @@ index 41b7cf7..b948ac6 100644
static void manager_distribute_fds(Manager *m, FDSet *fds) {
diff --git a/src/core/manager.h b/src/core/manager.h
index d1e540a..73c149f 100644
index 67c204f..d298dce 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -423,6 +423,7 @@ struct Manager {
@@ -442,6 +442,8 @@ struct Manager {
unsigned sigchldgen;
unsigned notifygen;
bool honor_device_enumeration;
+ bool in_manager_catchup;
+
VarlinkServer *varlink_server;
/* Only systemd-oomd should be using this to subscribe to changes in ManagedOOM settings */
Varlink *managed_oom_varlink_request;
--
2.23.0
2.33.0

View File

@ -2,30 +2,30 @@ From e485f8a182f8a141676f7ffe0311a1a4724c3c1a Mon Sep 17 00:00:00 2001
From: licunlong <licunlong1@huawei.com>
Date: Tue, 28 Jun 2022 21:56:26 +0800
Subject: [PATCH] fix mount failed while daemon-reexec
---
src/core/manager.c | 1 +
src/core/manager.h | 1 +
src/core/mount.c | 5 ++++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/core/manager.c b/src/core/manager.c
index 5dff366..45c4ae0 100644
index 55adcd1..74f8304 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1762,6 +1762,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
@@ -1808,6 +1808,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
}
manager_ready(m);
+ m->mountinfo_uptodate = false;
return 0;
}
manager_set_switching_root(m, false);
diff --git a/src/core/manager.h b/src/core/manager.h
index cf6cd64..663fe8d 100644
index 31b4670..df74200 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -238,6 +238,7 @@ struct Manager {
@@ -259,6 +259,7 @@ struct Manager {
/* Data specific to the mount subsystem */
struct libmnt_monitor *mount_monitor;
sd_event_source *mount_event_source;
@ -34,10 +34,10 @@ index cf6cd64..663fe8d 100644
/* Data specific to the swap filesystem */
FILE *proc_swaps;
diff --git a/src/core/mount.c b/src/core/mount.c
index 6e514d5..25b0460 100644
index 8fed04c..00482e9 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1684,6 +1684,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
@@ -1785,6 +1785,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
(void) mount_setup_unit(m, device, path, options, fstype, set_flags);
}
@ -45,7 +45,7 @@ index 6e514d5..25b0460 100644
return 0;
}
@@ -1842,8 +1843,10 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
@@ -1948,8 +1949,10 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
assert(m);
r = drain_libmount(m);
@ -59,3 +59,4 @@ index 6e514d5..25b0460 100644
if (r < 0) {
--
2.33.0

View File

@ -21,7 +21,7 @@
Name: systemd
Url: https://www.freedesktop.org/wiki/Software/systemd
Version: 249
Release: 51
Release: 52
License: MIT and LGPLv2+ and GPLv2+
Summary: System and Service Manager
@ -478,6 +478,38 @@ Patch6430: backport-udev-assume-block-device-is-not-locked-when-a-new-event
Patch6431: backport-udev-fix-inversed-inequality-for-timeout-of-retrying-event.patch
Patch6432: backport-udev-certainly-restart-event-for-previously-locked-device.patch
Patch6433: backport-udev-drop-unnecessary-calls-of-event_queue_start.patch
Patch6434: backport-timedatectl-fix-a-memory-leak.patch
Patch6435: backport-core-slice-make-slice_freezer_action-return-0-if-fre.patch
Patch6436: backport-core-unit-fix-use-after-free.patch
Patch6437: backport-shared-json-fix-memory-leak-on-failed-normalization.patch
Patch6438: backport-core-timer-fix-memleak.patch
Patch6439: backport-core-timer-fix-potential-use-after-free.patch
Patch6440: backport-units-remove-the-restart-limit-on-the-modprobe-.serv.patch
Patch6441: backport-udev-cdrom_id-check-last-track-info.patch
Patch6442: backport-manager-reformat-boolean-expression-in-unit_is_prist.patch
Patch6443: backport-manager-allow-transient-units-to-have-drop-ins.patch
Patch6444: backport-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch
Patch6445: backport-TEST-15-add-test-for-transient-units-with-drop-ins.patch
Patch6446: backport-TEST-15-add-one-more-test-for-drop-in-precedence.patch
Patch6447: backport-sd-event-always-initialize-sd_event.perturb.patch
Patch6448: backport-sd-event-fix-error-handling.patch
Patch6449: backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch
Patch6450: backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch
Patch6451: backport-core-device-drop-unnecessary-condition.patch
Patch6452: backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch
Patch6453: backport-test-cover-initrd-sysroot-transition-in-TEST-24.patch
Patch6454: backport-test-generate-a-custom-initrd-for-TEST-24-if-INITRD-.patch
Patch6455: backport-test-store-the-key-on-a-separate-device.patch
Patch6456: backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch
Patch6457: backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch
Patch6458: backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch
Patch6459: backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch
Patch6460: backport-core-device-update-comment.patch
Patch6461: backport-core-device-also-serialize-deserialize-device-syspat.patch
Patch6462: backport-core-device-verify-device-syspath-on-switching-root.patch
Patch6463: backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch
Patch6464: backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch
Patch6465: backport-sysext-refuse-empty-release-ID-to-avoid-triggering-a.patch
Patch9001: update-rtc-with-system-clock-when-shutdown.patch
Patch9002: udev-add-actions-while-rename-netif-failed.patch
@ -1949,6 +1981,9 @@ fi
%{_libdir}/security/pam_systemd.so
%changelog
* Thu Jun 15 2023 hongjinghao <hongjinghao@huawei.com> - 249-52
- backport: sync patches from systemd community
* Mon Jun 12 2023 chenjiayi <chenjiayi22@huawei.com> - 249-51
- backport upstream patches to fix event loss when the whole disk is locked