systemd-252-70
Resolves: RHEL-127425, RHEL-3631, RHEL-25518, RHEL-166187, RHEL-164539
This commit is contained in:
parent
d5a4a5f515
commit
d8982300d8
@ -0,0 +1,42 @@
|
||||
From 4843d4f679bb4dd70f15ce49f0786e80bb821e28 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Sekletar <msekleta@redhat.com>
|
||||
Date: Wed, 25 Feb 2026 19:45:55 +0100
|
||||
Subject: [PATCH] core: cleanup unit's dropin directories from global cache
|
||||
|
||||
When user creates dropin files via API (e.g. systemctl set-property ...)
|
||||
we put the dropin directory path into unit_path_cache. Drop those
|
||||
directories from the cache in unit_free() and prevent memory leak.
|
||||
|
||||
Follow-up for fce94c5c563b8f6ede2b8f7f283d2d2faff4e062.
|
||||
|
||||
(cherry picked from commit 0c98e432d1def1e8428dbead50dc629ed0645366)
|
||||
|
||||
Resolves: RHEL-127425
|
||||
---
|
||||
src/core/unit.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||
index 7f321c911d..790f4023a2 100644
|
||||
--- a/src/core/unit.c
|
||||
+++ b/src/core/unit.c
|
||||
@@ -603,6 +603,8 @@ static void unit_remove_transient(Unit *u) {
|
||||
if (!u->transient)
|
||||
return;
|
||||
|
||||
+ const char *dropin_directory = strjoina(u->id, ".d");
|
||||
+
|
||||
STRV_FOREACH(i, u->dropin_paths) {
|
||||
_cleanup_free_ char *p = NULL, *pp = NULL;
|
||||
|
||||
@@ -616,6 +618,10 @@ static void unit_remove_transient(Unit *u) {
|
||||
if (!path_equal(u->manager->lookup_paths.transient, pp))
|
||||
continue;
|
||||
|
||||
+ /* Drop the transient drop-in directory also from unit path cache. */
|
||||
+ if (path_equal(last_path_component(p), dropin_directory))
|
||||
+ free(set_remove(u->manager->unit_path_cache, p));
|
||||
+
|
||||
(void) unlink(*i);
|
||||
(void) rmdir(p);
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
From b7156edf92d815ad3bf84fbcaaa7a4a94a648999 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Thu, 5 Sep 2024 12:31:20 +0200
|
||||
Subject: [PATCH] udev: allow persistent storage rules for rbd devices
|
||||
|
||||
The RADOS Block Device (rbd) can be used as any other block device with
|
||||
further layers on top of it, hence allow the common persistent storage
|
||||
rules to apply, including watching for changes.
|
||||
|
||||
(cherry picked from commit cbe65d38cf0a2e55cdba75871de108bc505a7095)
|
||||
|
||||
Resolves: RHEL-3631
|
||||
---
|
||||
rules.d/60-block.rules | 2 +-
|
||||
rules.d/60-persistent-storage.rules | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/rules.d/60-block.rules b/rules.d/60-block.rules
|
||||
index 3134ab995e..13f88e92c8 100644
|
||||
--- a/rules.d/60-block.rules
|
||||
+++ b/rules.d/60-block.rules
|
||||
@@ -9,5 +9,5 @@ ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block",
|
||||
|
||||
# watch metadata changes, caused by tools closing the device node which was opened for writing
|
||||
ACTION!="remove", SUBSYSTEM=="block", \
|
||||
- KERNEL=="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*", \
|
||||
+ KERNEL=="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*|rbd*", \
|
||||
OPTIONS+="watch"
|
||||
diff --git a/rules.d/60-persistent-storage.rules b/rules.d/60-persistent-storage.rules
|
||||
index 10b347e191..3aa365bec4 100644
|
||||
--- a/rules.d/60-persistent-storage.rules
|
||||
+++ b/rules.d/60-persistent-storage.rules
|
||||
@@ -7,7 +7,7 @@ ACTION=="remove", GOTO="persistent_storage_end"
|
||||
ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_end"
|
||||
|
||||
SUBSYSTEM!="block|ubi", GOTO="persistent_storage_end"
|
||||
-KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*", GOTO="persistent_storage_end"
|
||||
+KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*|rbd*", GOTO="persistent_storage_end"
|
||||
|
||||
# ignore partitions that span the entire disk
|
||||
TEST=="whole_disk", GOTO="persistent_storage_end"
|
||||
55
1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch
Normal file
55
1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 1aaebe972b912e1f2ef3b874edb22e47f7def5b9 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Macku <jamacku@redhat.com>
|
||||
Date: Mon, 4 May 2026 09:30:17 +0200
|
||||
Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-9.9
|
||||
|
||||
rhel-only: policy
|
||||
|
||||
Resolves: RHEL-25518
|
||||
---
|
||||
man/systemd.net-naming-scheme.xml | 6 ++++++
|
||||
src/shared/netif-naming-scheme.c | 1 +
|
||||
src/shared/netif-naming-scheme.h | 1 +
|
||||
3 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||
index c6ee7b4b6e..be7197d62d 100644
|
||||
--- a/man/systemd.net-naming-scheme.xml
|
||||
+++ b/man/systemd.net-naming-scheme.xml
|
||||
@@ -533,6 +533,12 @@
|
||||
<para>PCI slot number is now read from <constant>firmware_node/sun</constant> sysfs file.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term><constant>rhel-9.9</constant></term>
|
||||
+
|
||||
+ <listitem><para>Same as naming scheme <constant>rhel-9.8</constant>.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
</variablelist>
|
||||
|
||||
<para>By default <constant>rhel-9.0</constant> is used.</para>
|
||||
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
|
||||
index 4ed866491e..5edc50069d 100644
|
||||
--- a/src/shared/netif-naming-scheme.c
|
||||
+++ b/src/shared/netif-naming-scheme.c
|
||||
@@ -48,6 +48,7 @@ static const NamingScheme naming_schemes[] = {
|
||||
{ "rhel-9.6", NAMING_RHEL_9_6 },
|
||||
{ "rhel-9.7", NAMING_RHEL_9_7 },
|
||||
{ "rhel-9.8", NAMING_RHEL_9_8 },
|
||||
+ { "rhel-9.9", NAMING_RHEL_9_9 },
|
||||
/* … add more schemes here, as the logic to name devices is updated … */
|
||||
|
||||
EXTRA_NET_NAMING_MAP
|
||||
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||
index c16476522a..6bb8db920e 100644
|
||||
--- a/src/shared/netif-naming-scheme.h
|
||||
+++ b/src/shared/netif-naming-scheme.h
|
||||
@@ -78,6 +78,7 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_RHEL_9_6 = NAMING_RHEL_9_5,
|
||||
NAMING_RHEL_9_7 = NAMING_RHEL_9_5,
|
||||
NAMING_RHEL_9_8 = NAMING_RHEL_9_5 | NAMING_FIRMWARE_NODE_SUN,
|
||||
+ NAMING_RHEL_9_9 = NAMING_RHEL_9_8,
|
||||
|
||||
EXTRA_NET_NAMING_SCHEMES
|
||||
|
||||
322
1339-fstab-generator-support-swap-on-network-block-device.patch
Normal file
322
1339-fstab-generator-support-swap-on-network-block-device.patch
Normal file
@ -0,0 +1,322 @@
|
||||
From e5e4bfa6dcdc2502e57c813ea0d0a72ee37fb337 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 7 Apr 2026 11:16:42 +0200
|
||||
Subject: [PATCH] fstab-generator: support swap on network block devices
|
||||
|
||||
Teach swap units to support the _netdev option as well, which should
|
||||
make swaps on iSCSI possible. This mirrors the logic we already have for
|
||||
regular mounts in both the fstab-generator and the core
|
||||
(mount.c/swap.c).
|
||||
|
||||
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||||
(cherry picked from commit 3d5bd67a2259e7a4edc27476d4cae049653c4414)
|
||||
|
||||
Resolves: RHEL-166187
|
||||
---
|
||||
man/systemd.swap.xml | 28 +++++++++--
|
||||
src/core/swap.c | 46 ++++++++++++++++---
|
||||
src/fstab-generator/fstab-generator.c | 16 +++++--
|
||||
src/shared/generator.c | 2 +-
|
||||
.../systemd-remount-fs.service | 0
|
||||
.../sysroot.mount | 0
|
||||
.../50-netdev-dependencies.conf | 5 ++
|
||||
.../dev-sdx1.swap | 10 ++++
|
||||
.../systemd-remount-fs.service | 0
|
||||
.../remote-fs.target.requires/dev-sdx1.swap | 1 +
|
||||
.../50-netdev-dependencies.conf | 5 ++
|
||||
.../dev-sdx1.swap | 10 ++++
|
||||
.../sysroot.mount | 0
|
||||
.../remote-fs.target.requires/dev-sdx1.swap | 1 +
|
||||
.../test-21-swap-netdev.fstab.input | 1 +
|
||||
15 files changed, 111 insertions(+), 14 deletions(-)
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container.sysroot/local-fs.target.wants/systemd-remount-fs.service
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container/initrd-usr-fs.target.requires/sysroot.mount
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service
|
||||
create mode 120000 test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
|
||||
create mode 120000 test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap
|
||||
create mode 100644 test/test-fstab-generator/test-21-swap-netdev.fstab.input
|
||||
|
||||
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
|
||||
index 8287382eb6..6af8a31021 100644
|
||||
--- a/man/systemd.swap.xml
|
||||
+++ b/man/systemd.swap.xml
|
||||
@@ -90,9 +90,15 @@
|
||||
<para>The following dependencies are added unless <varname>DefaultDependencies=no</varname> is set:</para>
|
||||
|
||||
<itemizedlist>
|
||||
- <listitem><para>Swap units automatically acquire a <varname>Conflicts=</varname> and a
|
||||
+ <listitem><para>Local swap units automatically acquire a <varname>Conflicts=</varname> and a
|
||||
<varname>Before=</varname> dependency on <filename>umount.target</filename> so that they are deactivated at
|
||||
shutdown as well as a <varname>Before=swap.target</varname> dependency.</para></listitem>
|
||||
+
|
||||
+ <listitem><para>Network swap units (those with <option>_netdev</option> in their options) automatically acquire
|
||||
+ <varname>After=</varname> dependencies on <filename>remote-fs-pre.target</filename> and
|
||||
+ <filename>network.target</filename>, plus <varname>After=</varname> and <varname>Wants=</varname> dependencies
|
||||
+ on <filename>network-online.target</filename>, and a <varname>Before=</varname> dependency on
|
||||
+ <filename>remote-fs.target</filename> instead of <filename>swap.target</filename>.</para></listitem>
|
||||
</itemizedlist>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
@@ -124,7 +130,8 @@
|
||||
|
||||
<listitem><para>With <option>noauto</option>, the swap unit
|
||||
will not be added as a dependency for
|
||||
- <filename>swap.target</filename>. This means that it will not
|
||||
+ <filename>swap.target</filename> (or <filename>remote-fs.target</filename> for network swap devices,
|
||||
+ see <option>_netdev</option> below). This means that it will not
|
||||
be activated automatically during boot, unless it is pulled in
|
||||
by some other unit. The <option>auto</option> option has the
|
||||
opposite meaning and is the default.</para>
|
||||
@@ -136,8 +143,8 @@
|
||||
|
||||
<listitem><para>With <option>nofail</option>, the swap unit
|
||||
will be only wanted, not required by
|
||||
- <filename>swap.target</filename>. This means that the boot
|
||||
- will continue even if this swap device is not activated
|
||||
+ <filename>swap.target</filename> (or <filename>remote-fs.target</filename> for network swap
|
||||
+ devices). This means that the boot will continue even if this swap device is not activated
|
||||
successfully.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -161,6 +168,19 @@
|
||||
in <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term><option>_netdev</option></term>
|
||||
+
|
||||
+ <listitem><para>Marks this swap device as requiring network access. This is useful for swap on
|
||||
+ network block devices (e.g. iSCSI).</para>
|
||||
+
|
||||
+ <para>Network swap units are ordered between <filename>remote-fs-pre.target</filename> and
|
||||
+ <filename>remote-fs.target</filename>, instead of being ordered before
|
||||
+ <filename>swap.target</filename>. They also pull in <filename>network-online.target</filename> and
|
||||
+ are ordered after it and <filename>network.target</filename>.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
diff --git a/src/core/swap.c b/src/core/swap.c
|
||||
index 5c83c4780f..10743d4b9d 100644
|
||||
--- a/src/core/swap.c
|
||||
+++ b/src/core/swap.c
|
||||
@@ -253,6 +253,7 @@ static int swap_add_device_dependencies(Swap *s) {
|
||||
}
|
||||
|
||||
static int swap_add_default_dependencies(Swap *s) {
|
||||
+ SwapParameters *p;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
@@ -266,13 +267,46 @@ static int swap_add_default_dependencies(Swap *s) {
|
||||
if (detect_container() > 0)
|
||||
return 0;
|
||||
|
||||
- /* swap units generated for the swap dev links are missing the
|
||||
- * ordering dep against the swap target. */
|
||||
- r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
+ p = swap_get_parameters(s);
|
||||
+
|
||||
+ if (p && fstab_test_option(p->options, "_netdev\0")) {
|
||||
+ /* Network swap devices (those with _netdev in options) are routed through
|
||||
+ * remote-fs.target instead of swap.target, mirroring how network mounts use
|
||||
+ * remote-fs.target instead of local-fs.target. This avoids an ordering cycle:
|
||||
+ * swap.target is pulled in at sysinit.target time, but network-online.target
|
||||
+ * only comes after basic.target which is after sysinit.target. */
|
||||
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOTE_FS_PRE_TARGET,
|
||||
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET,
|
||||
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ /* Pull in and order after network-online.target, analogous to
|
||||
+ * mount_add_default_network_dependencies() for network mounts. */
|
||||
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_NETWORK_TARGET,
|
||||
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET,
|
||||
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ } else {
|
||||
+ /* swap units generated for the swap dev links are missing the
|
||||
+ * ordering dep against the swap target. */
|
||||
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET,
|
||||
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
|
||||
- return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
+ return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET,
|
||||
+ /* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
|
||||
}
|
||||
|
||||
static int swap_verify(Swap *s) {
|
||||
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
|
||||
index 28677a2f39..7b417dd2d1 100644
|
||||
--- a/src/fstab-generator/fstab-generator.c
|
||||
+++ b/src/fstab-generator/fstab-generator.c
|
||||
@@ -208,6 +208,7 @@ static int add_swap(
|
||||
|
||||
_cleanup_free_ char *name = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
+ bool is_network;
|
||||
int r;
|
||||
|
||||
assert(what);
|
||||
@@ -227,10 +228,12 @@ static int add_swap(
|
||||
return true;
|
||||
}
|
||||
|
||||
- log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s",
|
||||
+ is_network = fstab_test_option(options, "_netdev\0");
|
||||
+
|
||||
+ log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s netdev=%s",
|
||||
what,
|
||||
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS), yes_no(flags & MOUNT_PCRFS),
|
||||
- yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
|
||||
+ yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL), yes_no(is_network));
|
||||
|
||||
r = unit_name_from_path(what, ".swap", &name);
|
||||
if (r < 0)
|
||||
@@ -271,6 +274,12 @@ static int add_swap(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
+ if (is_network) {
|
||||
+ r = generator_write_device_deps(arg_dest, what, /* where= */ NULL, options);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
if (flags & MOUNT_MAKEFS) {
|
||||
r = generator_hook_up_mkswap(arg_dest, what);
|
||||
if (r < 0)
|
||||
@@ -284,7 +293,8 @@ static int add_swap(
|
||||
log_warning("%s: measuring swap devices is currently unsupported.", what);
|
||||
|
||||
if (!(flags & MOUNT_NOAUTO)) {
|
||||
- r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
|
||||
+ const char *target = is_network ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_SWAP_TARGET;
|
||||
+ r = generator_add_symlink(arg_dest, target,
|
||||
(flags & MOUNT_NOFAIL) ? "wants" : "requires", name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
diff --git a/src/shared/generator.c b/src/shared/generator.c
|
||||
index a688ba446c..5dc103400b 100644
|
||||
--- a/src/shared/generator.c
|
||||
+++ b/src/shared/generator.c
|
||||
@@ -428,7 +428,7 @@ int generator_write_device_deps(
|
||||
_cleanup_free_ char *node = NULL, *unit = NULL;
|
||||
int r;
|
||||
|
||||
- if (fstab_is_extrinsic(where, opts))
|
||||
+ if (where && fstab_is_extrinsic(where, opts))
|
||||
return 0;
|
||||
|
||||
if (!fstab_test_option(opts, "_netdev\0"))
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container.sysroot/local-fs.target.wants/systemd-remount-fs.service b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container.sysroot/local-fs.target.wants/systemd-remount-fs.service
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.container/initrd-usr-fs.target.requires/sysroot.mount
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf
|
||||
new file mode 100644
|
||||
index 0000000000..33d814c275
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.device.d/50-netdev-dependencies.conf
|
||||
@@ -0,0 +1,5 @@
|
||||
+# Automatically generated by systemd-fstab-generator
|
||||
+
|
||||
+[Unit]
|
||||
+After=network-online.target network.target
|
||||
+Wants=network-online.target
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap
|
||||
new file mode 100644
|
||||
index 0000000000..32f276c9e1
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/dev-sdx1.swap
|
||||
@@ -0,0 +1,10 @@
|
||||
+# Automatically generated by systemd-fstab-generator
|
||||
+
|
||||
+[Unit]
|
||||
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
+SourcePath=/etc/fstab
|
||||
+After=blockdev@dev-sdx1.target
|
||||
+
|
||||
+[Swap]
|
||||
+What=/dev/sdx1
|
||||
+Options=_netdev
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap
|
||||
new file mode 120000
|
||||
index 0000000000..00f0c5ce66
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected.sysroot/remote-fs.target.requires/dev-sdx1.swap
|
||||
@@ -0,0 +1 @@
|
||||
+../dev-sdx1.swap
|
||||
\ No newline at end of file
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf
|
||||
new file mode 100644
|
||||
index 0000000000..33d814c275
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.device.d/50-netdev-dependencies.conf
|
||||
@@ -0,0 +1,5 @@
|
||||
+# Automatically generated by systemd-fstab-generator
|
||||
+
|
||||
+[Unit]
|
||||
+After=network-online.target network.target
|
||||
+Wants=network-online.target
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap
|
||||
new file mode 100644
|
||||
index 0000000000..32f276c9e1
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/dev-sdx1.swap
|
||||
@@ -0,0 +1,10 @@
|
||||
+# Automatically generated by systemd-fstab-generator
|
||||
+
|
||||
+[Unit]
|
||||
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
+SourcePath=/etc/fstab
|
||||
+After=blockdev@dev-sdx1.target
|
||||
+
|
||||
+[Swap]
|
||||
+What=/dev/sdx1
|
||||
+Options=_netdev
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap
|
||||
new file mode 120000
|
||||
index 0000000000..00f0c5ce66
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.expected/remote-fs.target.requires/dev-sdx1.swap
|
||||
@@ -0,0 +1 @@
|
||||
+../dev-sdx1.swap
|
||||
\ No newline at end of file
|
||||
diff --git a/test/test-fstab-generator/test-21-swap-netdev.fstab.input b/test/test-fstab-generator/test-21-swap-netdev.fstab.input
|
||||
new file mode 100644
|
||||
index 0000000000..5f719a4202
|
||||
--- /dev/null
|
||||
+++ b/test/test-fstab-generator/test-21-swap-netdev.fstab.input
|
||||
@@ -0,0 +1 @@
|
||||
+/dev/sdx1 none swap _netdev 0 0
|
||||
460
1340-core-increment-start-limit-counter-only-when-we-can-.patch
Normal file
460
1340-core-increment-start-limit-counter-only-when-we-can-.patch
Normal file
@ -0,0 +1,460 @@
|
||||
From 4060cdad388b0ae658f2024633b842a46c37962e Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Mon, 20 Oct 2025 19:40:28 +0900
|
||||
Subject: [PATCH] core: increment start limit counter only when we can start
|
||||
the unit
|
||||
|
||||
Otherwise, e.g. requesting to start a unit that is under stopping may
|
||||
enter the failed state.
|
||||
|
||||
This makes
|
||||
- rename .can_start() -> .test_startable(), and make it allow to return
|
||||
boolean and refuse to start units when it returns false,
|
||||
- refuse earlier to start units that are in the deactivating state, so
|
||||
several redundant conditions in .start() can be dropped,
|
||||
- move checks for unit states mapped to UNIT_ACTIVATING from .start() to
|
||||
.test_startable().
|
||||
|
||||
Fixes #39247.
|
||||
|
||||
(cherry picked from commit 8eefd0f4debc0bcfeea89dd39c43e3318f3f7ae7)
|
||||
|
||||
Resolves: RHEL-164539
|
||||
---
|
||||
src/core/automount.c | 6 ++--
|
||||
src/core/mount.c | 25 +++++----------
|
||||
src/core/path.c | 6 ++--
|
||||
src/core/service.c | 24 ++++++---------
|
||||
src/core/socket.c | 32 ++++++--------------
|
||||
src/core/swap.c | 23 +++++---------
|
||||
src/core/timer.c | 6 ++--
|
||||
src/core/unit.c | 11 ++++---
|
||||
src/core/unit.h | 4 +--
|
||||
test/units/TEST-07-PID1.start-limit.sh | 42 ++++++++++++++++++++++++++
|
||||
10 files changed, 93 insertions(+), 86 deletions(-)
|
||||
create mode 100755 test/units/TEST-07-PID1.start-limit.sh
|
||||
|
||||
diff --git a/src/core/automount.c b/src/core/automount.c
|
||||
index a44b8e878d..ae8399d1af 100644
|
||||
--- a/src/core/automount.c
|
||||
+++ b/src/core/automount.c
|
||||
@@ -1084,7 +1084,7 @@ static bool automount_supported(void) {
|
||||
return supported;
|
||||
}
|
||||
|
||||
-static int automount_can_start(Unit *u) {
|
||||
+static int automount_test_startable(Unit *u) {
|
||||
Automount *a = AUTOMOUNT(u);
|
||||
int r;
|
||||
|
||||
@@ -1096,7 +1096,7 @@ static int automount_can_start(Unit *u) {
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
|
||||
@@ -1162,5 +1162,5 @@ const UnitVTable automount_vtable = {
|
||||
},
|
||||
},
|
||||
|
||||
- .can_start = automount_can_start,
|
||||
+ .test_startable = automount_test_startable,
|
||||
};
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||
index be6fbf4cc4..5789a253cd 100644
|
||||
--- a/src/core/mount.c
|
||||
+++ b/src/core/mount.c
|
||||
@@ -1212,21 +1212,6 @@ static int mount_start(Unit *u) {
|
||||
Mount *m = MOUNT(u);
|
||||
int r;
|
||||
|
||||
- assert(m);
|
||||
-
|
||||
- /* We cannot fulfill this request right now, try again later
|
||||
- * please! */
|
||||
- if (IN_SET(m->state,
|
||||
- MOUNT_UNMOUNTING,
|
||||
- MOUNT_UNMOUNTING_SIGTERM,
|
||||
- MOUNT_UNMOUNTING_SIGKILL,
|
||||
- MOUNT_CLEANING))
|
||||
- return -EAGAIN;
|
||||
-
|
||||
- /* Already on it! */
|
||||
- if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE))
|
||||
- return 0;
|
||||
-
|
||||
assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
|
||||
|
||||
r = unit_acquire_invocation_id(u);
|
||||
@@ -2214,19 +2199,23 @@ static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
|
||||
return exec_context_get_clean_mask(&m->exec_context, ret);
|
||||
}
|
||||
|
||||
-static int mount_can_start(Unit *u) {
|
||||
+static int mount_test_startable(Unit *u) {
|
||||
Mount *m = MOUNT(u);
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
+ /* It is already being started. */
|
||||
+ if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE))
|
||||
+ return false;
|
||||
+
|
||||
r = unit_test_start_limit(u);
|
||||
if (r < 0) {
|
||||
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
char* mount_get_where_escaped(const Mount *m) {
|
||||
@@ -2337,5 +2326,5 @@ const UnitVTable mount_vtable = {
|
||||
},
|
||||
},
|
||||
|
||||
- .can_start = mount_can_start,
|
||||
+ .test_startable = mount_test_startable,
|
||||
};
|
||||
diff --git a/src/core/path.c b/src/core/path.c
|
||||
index 3a46e44928..6f850244f1 100644
|
||||
--- a/src/core/path.c
|
||||
+++ b/src/core/path.c
|
||||
@@ -846,7 +846,7 @@ static void path_reset_failed(Unit *u) {
|
||||
p->result = PATH_SUCCESS;
|
||||
}
|
||||
|
||||
-static int path_can_start(Unit *u) {
|
||||
+static int path_test_startable(Unit *u) {
|
||||
Path *p = PATH(u);
|
||||
int r;
|
||||
|
||||
@@ -858,7 +858,7 @@ static int path_can_start(Unit *u) {
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static void activation_details_path_done(ActivationDetails *details) {
|
||||
@@ -1000,7 +1000,7 @@ const UnitVTable path_vtable = {
|
||||
|
||||
.bus_set_property = bus_path_set_property,
|
||||
|
||||
- .can_start = path_can_start,
|
||||
+ .test_startable = path_test_startable,
|
||||
};
|
||||
|
||||
const ActivationDetailsVTable activation_details_path_vtable = {
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 53f40b2d78..e152fb6227 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -2557,17 +2557,6 @@ static int service_start(Unit *u) {
|
||||
|
||||
assert(s);
|
||||
|
||||
- /* We cannot fulfill this request right now, try again later
|
||||
- * please! */
|
||||
- if (IN_SET(s->state,
|
||||
- SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||
- SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL, SERVICE_CLEANING))
|
||||
- return -EAGAIN;
|
||||
-
|
||||
- /* Already on it! */
|
||||
- if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST))
|
||||
- return 0;
|
||||
-
|
||||
/* A service that will be restarted must be stopped first to
|
||||
* trigger BindsTo and/or OnFailure dependencies. If a user
|
||||
* does not want to wait for the holdoff time to elapse, the
|
||||
@@ -4707,12 +4696,19 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static int service_can_start(Unit *u) {
|
||||
+static int service_test_startable(Unit *u) {
|
||||
Service *s = SERVICE(u);
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
+ /* First check the state, and do not increment start limit counter if the service cannot start due to
|
||||
+ * that e.g. it is already being started. Note, the service states mapped to UNIT_ACTIVE,
|
||||
+ * UNIT_RELOADING, UNIT_DEACTIVATING, UNIT_MAINTENANCE, and UNIT_REFRESHING are already filtered in
|
||||
+ * unit_start(). Hence, here we only need to check states that mapped to UNIT_ACTIVATING. */
|
||||
+ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST))
|
||||
+ return false;
|
||||
+
|
||||
/* Make sure we don't enter a busy loop of some kind. */
|
||||
r = unit_test_start_limit(u);
|
||||
if (r < 0) {
|
||||
@@ -4720,7 +4716,7 @@ static int service_can_start(Unit *u) {
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
|
||||
@@ -4896,5 +4892,5 @@ const UnitVTable service_vtable = {
|
||||
.finished_job = service_finished_job,
|
||||
},
|
||||
|
||||
- .can_start = service_can_start,
|
||||
+ .test_startable = service_test_startable,
|
||||
};
|
||||
diff --git a/src/core/socket.c b/src/core/socket.c
|
||||
index 7abae70255..103b399ab8 100644
|
||||
--- a/src/core/socket.c
|
||||
+++ b/src/core/socket.c
|
||||
@@ -2460,25 +2460,6 @@ static int socket_start(Unit *u) {
|
||||
|
||||
assert(s);
|
||||
|
||||
- /* We cannot fulfill this request right now, try again later
|
||||
- * please! */
|
||||
- if (IN_SET(s->state,
|
||||
- SOCKET_STOP_PRE,
|
||||
- SOCKET_STOP_PRE_SIGKILL,
|
||||
- SOCKET_STOP_PRE_SIGTERM,
|
||||
- SOCKET_STOP_POST,
|
||||
- SOCKET_FINAL_SIGTERM,
|
||||
- SOCKET_FINAL_SIGKILL,
|
||||
- SOCKET_CLEANING))
|
||||
- return -EAGAIN;
|
||||
-
|
||||
- /* Already on it! */
|
||||
- if (IN_SET(s->state,
|
||||
- SOCKET_START_PRE,
|
||||
- SOCKET_START_CHOWN,
|
||||
- SOCKET_START_POST))
|
||||
- return 0;
|
||||
-
|
||||
/* Cannot run this without the service being around */
|
||||
if (UNIT_ISSET(s->service)) {
|
||||
Service *service;
|
||||
@@ -3392,19 +3373,26 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) {
|
||||
return exec_context_get_clean_mask(&s->exec_context, ret);
|
||||
}
|
||||
|
||||
-static int socket_can_start(Unit *u) {
|
||||
+static int socket_test_startable(Unit *u) {
|
||||
Socket *s = SOCKET(u);
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
+ /* It is already being started. */
|
||||
+ if (IN_SET(s->state,
|
||||
+ SOCKET_START_PRE,
|
||||
+ SOCKET_START_CHOWN,
|
||||
+ SOCKET_START_POST))
|
||||
+ return false;
|
||||
+
|
||||
r = unit_test_start_limit(u);
|
||||
if (r < 0) {
|
||||
socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
|
||||
@@ -3534,5 +3522,5 @@ const UnitVTable socket_vtable = {
|
||||
},
|
||||
},
|
||||
|
||||
- .can_start = socket_can_start,
|
||||
+ .test_startable = socket_test_startable,
|
||||
};
|
||||
diff --git a/src/core/swap.c b/src/core/swap.c
|
||||
index 10743d4b9d..458c935b0c 100644
|
||||
--- a/src/core/swap.c
|
||||
+++ b/src/core/swap.c
|
||||
@@ -933,19 +933,6 @@ static int swap_start(Unit *u) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
-
|
||||
- /* We cannot fulfill this request right now, try again later please! */
|
||||
- if (IN_SET(s->state,
|
||||
- SWAP_DEACTIVATING,
|
||||
- SWAP_DEACTIVATING_SIGTERM,
|
||||
- SWAP_DEACTIVATING_SIGKILL,
|
||||
- SWAP_CLEANING))
|
||||
- return -EAGAIN;
|
||||
-
|
||||
- /* Already on it! */
|
||||
- if (s->state == SWAP_ACTIVATING)
|
||||
- return 0;
|
||||
-
|
||||
assert(IN_SET(s->state, SWAP_DEAD, SWAP_FAILED));
|
||||
|
||||
if (detect_container() > 0)
|
||||
@@ -1612,19 +1599,23 @@ static int swap_can_clean(Unit *u, ExecCleanMask *ret) {
|
||||
return exec_context_get_clean_mask(&s->exec_context, ret);
|
||||
}
|
||||
|
||||
-static int swap_can_start(Unit *u) {
|
||||
+static int swap_test_startable(Unit *u) {
|
||||
Swap *s = SWAP(u);
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
+ /* It is already being started. */
|
||||
+ if (s->state == SWAP_ACTIVATING)
|
||||
+ return false;
|
||||
+
|
||||
r = unit_test_start_limit(u);
|
||||
if (r < 0) {
|
||||
swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
|
||||
@@ -1723,5 +1714,5 @@ const UnitVTable swap_vtable = {
|
||||
},
|
||||
},
|
||||
|
||||
- .can_start = swap_can_start,
|
||||
+ .test_startable = swap_test_startable,
|
||||
};
|
||||
diff --git a/src/core/timer.c b/src/core/timer.c
|
||||
index 8fb79bc0cb..b96e88af90 100644
|
||||
--- a/src/core/timer.c
|
||||
+++ b/src/core/timer.c
|
||||
@@ -897,7 +897,7 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int timer_can_start(Unit *u) {
|
||||
+static int timer_test_startable(Unit *u) {
|
||||
Timer *t = TIMER(u);
|
||||
int r;
|
||||
|
||||
@@ -909,7 +909,7 @@ static int timer_can_start(Unit *u) {
|
||||
return r;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static void activation_details_timer_serialize(ActivationDetails *details, FILE *f) {
|
||||
@@ -1057,7 +1057,7 @@ const UnitVTable timer_vtable = {
|
||||
|
||||
.bus_set_property = bus_timer_set_property,
|
||||
|
||||
- .can_start = timer_can_start,
|
||||
+ .test_startable = timer_test_startable,
|
||||
};
|
||||
|
||||
const ActivationDetailsVTable activation_details_timer_vtable = {
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||
index 790f4023a2..0b58d0498b 100644
|
||||
--- a/src/core/unit.c
|
||||
+++ b/src/core/unit.c
|
||||
@@ -1846,7 +1846,7 @@ int unit_start(Unit *u, ActivationDetails *details) {
|
||||
state = unit_active_state(u);
|
||||
if (UNIT_IS_ACTIVE_OR_RELOADING(state))
|
||||
return -EALREADY;
|
||||
- if (state == UNIT_MAINTENANCE)
|
||||
+ if (IN_SET(state, UNIT_DEACTIVATING, UNIT_MAINTENANCE))
|
||||
return -EAGAIN;
|
||||
|
||||
/* Units that aren't loaded cannot be started */
|
||||
@@ -1889,10 +1889,11 @@ int unit_start(Unit *u, ActivationDetails *details) {
|
||||
return unit_start(following, details);
|
||||
}
|
||||
|
||||
- /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */
|
||||
- if (UNIT_VTABLE(u)->can_start) {
|
||||
- r = UNIT_VTABLE(u)->can_start(u);
|
||||
- if (r < 0)
|
||||
+ /* Check our ability to start early so that ratelimited or already starting/started units don't
|
||||
+ * cause us to enter a busy loop. */
|
||||
+ if (UNIT_VTABLE(u)->test_startable) {
|
||||
+ r = UNIT_VTABLE(u)->test_startable(u);
|
||||
+ if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
diff --git a/src/core/unit.h b/src/core/unit.h
|
||||
index fdea76458d..acbf74477e 100644
|
||||
--- a/src/core/unit.h
|
||||
+++ b/src/core/unit.h
|
||||
@@ -751,8 +751,8 @@ typedef struct UnitVTable {
|
||||
bool (*supported)(void);
|
||||
|
||||
/* If this function is set, it's invoked first as part of starting a unit to allow start rate
|
||||
- * limiting checks to occur before we do anything else. */
|
||||
- int (*can_start)(Unit *u);
|
||||
+ * limiting checks and unit state checks to occur before we do anything else. */
|
||||
+ int (*test_startable)(Unit *u);
|
||||
|
||||
/* The strings to print in status messages */
|
||||
UnitStatusMessageFormats status_message_formats;
|
||||
diff --git a/test/units/TEST-07-PID1.start-limit.sh b/test/units/TEST-07-PID1.start-limit.sh
|
||||
new file mode 100755
|
||||
index 0000000000..f793d32876
|
||||
--- /dev/null
|
||||
+++ b/test/units/TEST-07-PID1.start-limit.sh
|
||||
@@ -0,0 +1,42 @@
|
||||
+#!/usr/bin/env bash
|
||||
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+set -eux
|
||||
+set -o pipefail
|
||||
+
|
||||
+# For issue #39247.
|
||||
+
|
||||
+at_exit() {
|
||||
+ set +e
|
||||
+
|
||||
+ rm -rf /run/systemd/system/systemd-resolved.service.d/
|
||||
+ systemctl daemon-reload
|
||||
+ systemctl restart systemd-resolved.service
|
||||
+}
|
||||
+
|
||||
+trap at_exit EXIT
|
||||
+
|
||||
+mkdir -p /run/systemd/system/systemd-resolved.service.d/
|
||||
+cat >/run/systemd/system/systemd-resolved.service.d/99-start-limit.conf <<EOF
|
||||
+[Unit]
|
||||
+StartLimitBurst=5
|
||||
+StartLimitInterval=30
|
||||
+
|
||||
+[Service]
|
||||
+ExecStopPost=sleep 10
|
||||
+EOF
|
||||
+
|
||||
+systemctl daemon-reload
|
||||
+systemctl restart systemd-resolved.service
|
||||
+systemctl reset-failed systemd-resolved.service
|
||||
+systemctl status --no-pager systemd-resolved.service
|
||||
+systemctl show systemd-resolved.service | grep StartLimit
|
||||
+
|
||||
+for i in {1..5}; do
|
||||
+ echo "Start #$i"
|
||||
+
|
||||
+ systemctl stop --no-block systemd-resolved.service
|
||||
+ if ! resolvectl; then
|
||||
+ journalctl -o short-monotonic --no-hostname --no-pager -u systemd-resolved.service -n 15
|
||||
+ exit 1
|
||||
+ fi
|
||||
+done
|
||||
@ -0,0 +1,38 @@
|
||||
From 769a4fd1ad342ff84e985f0b73f23e03bbb677db Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Tue, 28 Oct 2025 13:20:58 +0900
|
||||
Subject: [PATCH] TEST-07-PID1: wait for systemd-resolved being stopped
|
||||
|
||||
As 'systemctl stop' is called with --no-block, previously systemd-resolved
|
||||
might not be stopped when 'resolvectl' is called, and the DBus connection
|
||||
might be closed during the call:
|
||||
```
|
||||
TEST-07-PID1.sh[5643]: + systemctl stop --no-block systemd-resolved.service
|
||||
TEST-07-PID1.sh[5643]: + resolvectl
|
||||
TEST-07-PID1.sh[5732]: Failed to get global data: Remote peer disconnected
|
||||
```
|
||||
|
||||
Follow-up for 8eefd0f4debc0bcfeea89dd39c43e3318f3f7ae7.
|
||||
Fixes https://github.com/systemd/systemd/pull/39388#issuecomment-3439277442.
|
||||
|
||||
(cherry picked from commit 6454fde83eef8da7391ad18a1b1a3248402f9214)
|
||||
|
||||
Related: RHEL-164539
|
||||
---
|
||||
test/units/TEST-07-PID1.start-limit.sh | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/test/units/TEST-07-PID1.start-limit.sh b/test/units/TEST-07-PID1.start-limit.sh
|
||||
index f793d32876..b512c58ff2 100755
|
||||
--- a/test/units/TEST-07-PID1.start-limit.sh
|
||||
+++ b/test/units/TEST-07-PID1.start-limit.sh
|
||||
@@ -35,6 +35,9 @@ for i in {1..5}; do
|
||||
echo "Start #$i"
|
||||
|
||||
systemctl stop --no-block systemd-resolved.service
|
||||
+ # Wait for systemd-resolved in ExecStart= being stopped.
|
||||
+ # shellcheck disable=SC2016
|
||||
+ timeout 10 bash -c 'until [[ "$(systemctl show --property=MainPID --value systemd-resolved.service)" == 0 ]]; do sleep 0.1; done'
|
||||
if ! resolvectl; then
|
||||
journalctl -o short-monotonic --no-hostname --no-pager -u systemd-resolved.service -n 15
|
||||
exit 1
|
||||
40
1342-test-extend-start-limit-interval.patch
Normal file
40
1342-test-extend-start-limit-interval.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From d092520e2c3221e191b46c6c771d54ec51f678dc Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Sat, 25 Oct 2025 15:34:44 +0900
|
||||
Subject: [PATCH] test: extend start limit interval
|
||||
|
||||
As the modified service requires about ~10 seconds for stopping, the
|
||||
service never hit the start limit even if we tried to restart the
|
||||
service more than 5 times.
|
||||
|
||||
This also checks that the service is actually triggered by dbus method
|
||||
call.
|
||||
|
||||
Follow-up for 8eefd0f4debc0bcfeea89dd39c43e3318f3f7ae7.
|
||||
|
||||
(cherry picked from commit 44b4caad6cc99449bbf705350939fde1ed9b1248)
|
||||
|
||||
Related: RHEL-164539
|
||||
---
|
||||
test/units/TEST-07-PID1.start-limit.sh | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/test/units/TEST-07-PID1.start-limit.sh b/test/units/TEST-07-PID1.start-limit.sh
|
||||
index b512c58ff2..93447452da 100755
|
||||
--- a/test/units/TEST-07-PID1.start-limit.sh
|
||||
+++ b/test/units/TEST-07-PID1.start-limit.sh
|
||||
@@ -19,7 +19,7 @@ mkdir -p /run/systemd/system/systemd-resolved.service.d/
|
||||
cat >/run/systemd/system/systemd-resolved.service.d/99-start-limit.conf <<EOF
|
||||
[Unit]
|
||||
StartLimitBurst=5
|
||||
-StartLimitInterval=30
|
||||
+StartLimitInterval=100
|
||||
|
||||
[Service]
|
||||
ExecStopPost=sleep 10
|
||||
@@ -42,4 +42,5 @@ for i in {1..5}; do
|
||||
journalctl -o short-monotonic --no-hostname --no-pager -u systemd-resolved.service -n 15
|
||||
exit 1
|
||||
fi
|
||||
+ systemctl is-active systemd-resolved.service
|
||||
done
|
||||
18
systemd.spec
18
systemd.spec
@ -21,7 +21,7 @@
|
||||
Name: systemd
|
||||
Url: https://systemd.io
|
||||
Version: 252
|
||||
Release: 69%{?dist}
|
||||
Release: 70%{?dist}
|
||||
# For a breakdown of the licensing, see README
|
||||
License: LGPLv2+ and MIT and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
@ -1418,6 +1418,13 @@ Patch1332: 1332-core-service-do-not-propagate-reload-for-combined-RE.patch
|
||||
Patch1333: 1333-udev-check-for-invalid-chars-in-various-fields-recei.patch
|
||||
Patch1334: 1334-udev-fix-review-mixup.patch
|
||||
Patch1335: 1335-udev-scsi-id-check-for-invalid-chars-in-various-fiel.patch
|
||||
Patch1336: 1336-core-cleanup-unit-s-dropin-directories-from-global-c.patch
|
||||
Patch1337: 1337-udev-allow-persistent-storage-rules-for-rbd-devices.patch
|
||||
Patch1338: 1338-udev-net_id-introduce-naming-scheme-for-RHEL-9.9.patch
|
||||
Patch1339: 1339-fstab-generator-support-swap-on-network-block-device.patch
|
||||
Patch1340: 1340-core-increment-start-limit-counter-only-when-we-can-.patch
|
||||
Patch1341: 1341-TEST-07-PID1-wait-for-systemd-resolved-being-stopped.patch
|
||||
Patch1342: 1342-test-extend-start-limit-interval.patch
|
||||
|
||||
# Downstream-only patches (9000–9999)
|
||||
|
||||
@ -2295,6 +2302,15 @@ systemd-hwdb update &>/dev/null || :
|
||||
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
|
||||
|
||||
%changelog
|
||||
* Tue May 12 2026 systemd maintenance team <systemd-maint@redhat.com> - 252-70
|
||||
- core: cleanup unit's dropin directories from global cache (RHEL-127425)
|
||||
- udev: allow persistent storage rules for rbd devices (RHEL-3631)
|
||||
- udev/net_id: introduce naming scheme for RHEL-9.9 (RHEL-25518)
|
||||
- fstab-generator: support swap on network block devices (RHEL-166187)
|
||||
- core: increment start limit counter only when we can start the unit (RHEL-164539)
|
||||
- TEST-07-PID1: wait for systemd-resolved being stopped (RHEL-164539)
|
||||
- test: extend start limit interval (RHEL-164539)
|
||||
|
||||
* Thu Apr 16 2026 systemd maintenance team <systemd-maint@redhat.com> - 252-69
|
||||
- nspawn: apply BindUser/Ephemeral from settings file only if trusted (RHEL-163871)
|
||||
- nspawn: normalize pivot_root paths (RHEL-163871)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user