Debrand for AlmaLinux

This commit is contained in:
Andrew Lukoshko 2025-02-15 03:33:50 +00:00 committed by AlmaLinux Autopatch
commit 47cfc8e9f9
121 changed files with 10159 additions and 127 deletions

View File

@ -0,0 +1,72 @@
From 39c06ea84187cda78fdce843482765cdf52537b3 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 18 Dec 2024 22:27:29 +0900
Subject: [PATCH] update-utmp: do not give up if the first attempt at
connecting bus failed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Otherwise, the program exits with failure if the first attempt in run() failed:
```
Dec 18 20:27:37 systemd-update-utmp[254]: Bus n/a: changing state UNSET → OPENING
Dec 18 20:27:37 systemd-update-utmp[254]: sd-bus: starting bus by connecting to /run/systemd/private...
Dec 18 20:27:37 systemd-update-utmp[254]: Bus n/a: changing state OPENING → CLOSED
Dec 18 20:27:37 systemd-update-utmp[254]: Failed to get D-Bus connection: Connection refused
```
(cherry picked from commit 85d040dabd2cc67c89b7ed6157429b8f6f2240f4)
---
src/update-utmp/update-utmp.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index e40843cf35..a10e6d478a 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -53,6 +53,12 @@ static int get_startup_monotonic_time(Context *c, usec_t *ret) {
assert(c);
assert(ret);
+ if (!c->bus) {
+ r = bus_connect_system_systemd(&c->bus);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to get D-Bus connection, ignoring: %m");
+ }
+
r = bus_get_property_trivial(
c->bus,
bus_systemd_mgr,
@@ -94,10 +100,13 @@ static int get_current_runlevel(Context *c) {
UINT64_C(100) * USEC_PER_MSEC +
random_u64_range(UINT64_C(1900) * USEC_PER_MSEC * n_attempts / MAX_ATTEMPTS);
(void) usleep_safe(usec);
+ }
+ if (!c->bus) {
r = bus_connect_system_systemd(&c->bus);
if (r == -ECONNREFUSED && n_attempts < 64) {
- log_debug_errno(r, "Failed to reconnect to system bus, retrying after a slight delay: %m");
+ log_debug_errno(r, "Failed to %s to system bus, retrying after a slight delay: %m",
+ n_attempts <= 1 ? "connect" : "reconnect");
continue;
}
if (r < 0)
@@ -251,7 +260,6 @@ static int run(int argc, char *argv[]) {
.audit_fd = -EBADF,
#endif
};
- int r;
log_setup();
@@ -264,9 +272,6 @@ static int run(int argc, char *argv[]) {
log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_WARNING,
errno, "Failed to connect to audit log, ignoring: %m");
#endif
- r = bus_connect_system_systemd(&c.bus);
- if (r < 0)
- return log_error_errno(r, "Failed to get D-Bus connection: %m");
return dispatch_verb(argc, argv, verbs, &c);
}

View File

@ -0,0 +1,78 @@
From d42ebb344d8692e0fd437ce38396d89d06017065 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sun, 9 Feb 2025 09:53:39 +0100
Subject: [PATCH] bootctl: fix potential uninitialized memory access
And while we are at it, let' get rid of have_xyz_partition_uuid
variables, to simplify things.
(cherry picked from commit df28afe9b2de9e480121c25f222fa487fed927ce)
---
src/bootctl/bootctl-status.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/bootctl/bootctl-status.c b/src/bootctl/bootctl-status.c
index 6bcb348935..3b46632b92 100644
--- a/src/bootctl/bootctl-status.c
+++ b/src/bootctl/bootctl-status.c
@@ -476,10 +476,9 @@ int verb_status(int argc, char *argv[], void *userdata) {
for (size_t i = 0; i < ELEMENTSOF(loader_flags); i++)
print_yes_no_line(i == 0, FLAGS_SET(loader_features, loader_flags[i].flag), loader_flags[i].name);
- sd_id128_t loader_partition_uuid;
- bool have_loader_partition_uuid = efi_loader_get_device_part_uuid(&loader_partition_uuid) >= 0;
-
- print_yes_no_line(false, have_loader_partition_uuid, "Boot loader set ESP information");
+ sd_id128_t loader_partition_uuid = SD_ID128_NULL;
+ (void) efi_loader_get_device_part_uuid(&loader_partition_uuid);
+ print_yes_no_line(/* first= */ false, !sd_id128_is_null(loader_partition_uuid), "Boot loader set partition information");
if (current_entry)
printf("Current Entry: %s\n", current_entry);
@@ -488,14 +487,14 @@ int verb_status(int argc, char *argv[], void *userdata) {
if (oneshot_entry && !streq_ptr(oneshot_entry, default_entry))
printf("OneShot Entry: %s\n", oneshot_entry);
- if (have_loader_partition_uuid && !sd_id128_is_null(esp_uuid) && !sd_id128_equal(esp_uuid, loader_partition_uuid))
- printf("WARNING: The boot loader reports a different partition UUID than the detected ESP ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
- SD_ID128_FORMAT_VAL(loader_partition_uuid), SD_ID128_FORMAT_VAL(esp_uuid));
+ if (!sd_id128_is_null(loader_partition_uuid)) {
+ if (!sd_id128_is_null(esp_uuid) && !sd_id128_equal(esp_uuid, loader_partition_uuid))
+ printf("WARNING: The boot loader reports a different partition UUID than the detected ESP ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
+ SD_ID128_FORMAT_VAL(loader_partition_uuid), SD_ID128_FORMAT_VAL(esp_uuid));
- if (!sd_id128_is_null(loader_partition_uuid))
printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(loader_partition_uuid));
- else
+ } else
printf(" Partition: n/a\n");
printf(" Loader: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(loader_path));
printf("\n");
@@ -507,17 +506,18 @@ int verb_status(int argc, char *argv[], void *userdata) {
for (size_t i = 0; i < ELEMENTSOF(stub_flags); i++)
print_yes_no_line(i == 0, FLAGS_SET(stub_features, stub_flags[i].flag), stub_flags[i].name);
- sd_id128_t stub_partition_uuid;
- bool have_stub_partition_uuid = efi_stub_get_device_part_uuid(&stub_partition_uuid) >= 0;
+ sd_id128_t stub_partition_uuid = SD_ID128_NULL;
+ (void) efi_stub_get_device_part_uuid(&stub_partition_uuid);
+
+ if (!sd_id128_is_null(stub_partition_uuid)) {
+ if (!(!sd_id128_is_null(esp_uuid) && sd_id128_equal(esp_uuid, stub_partition_uuid)) &&
+ !(!sd_id128_is_null(xbootldr_uuid) && sd_id128_equal(xbootldr_uuid, stub_partition_uuid)))
+ printf("WARNING: The stub loader reports a different UUID than the detected ESP or XBOOTDLR partition ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR"/"SD_ID128_UUID_FORMAT_STR")!\n",
+ SD_ID128_FORMAT_VAL(stub_partition_uuid), SD_ID128_FORMAT_VAL(esp_uuid), SD_ID128_FORMAT_VAL(xbootldr_uuid));
- if (have_stub_partition_uuid && (!(!sd_id128_is_null(esp_uuid) && sd_id128_equal(esp_uuid, stub_partition_uuid)) &&
- !(!sd_id128_is_null(xbootldr_uuid) && sd_id128_equal(xbootldr_uuid, stub_partition_uuid))))
- printf("WARNING: The stub loader reports a different UUID than the detected ESP or XBOOTDLR partition ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR"/"SD_ID128_UUID_FORMAT_STR")!\n",
- SD_ID128_FORMAT_VAL(stub_partition_uuid), SD_ID128_FORMAT_VAL(esp_uuid), SD_ID128_FORMAT_VAL(xbootldr_uuid));
- if (!sd_id128_is_null(stub_partition_uuid))
printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(stub_partition_uuid));
- else
+ } else
printf(" Partition: n/a\n");
printf(" Stub: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(stub_path));
printf("\n");

View File

@ -0,0 +1,27 @@
From 6e8f67eac6a3c7b159559f21e2146fce608d483e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sun, 9 Feb 2025 23:21:08 +0100
Subject: [PATCH] bootctl: also shown whether stub loader partition data was
passed
Let's make the stub and loader output sections more alike, and say in
both cases whether we recieved that data from the boot phase or not the
same way.
(cherry picked from commit 26bfd97216ab55664214d1e0fac7065e5573a36b)
---
src/bootctl/bootctl-status.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/bootctl/bootctl-status.c b/src/bootctl/bootctl-status.c
index 3b46632b92..9a4c233581 100644
--- a/src/bootctl/bootctl-status.c
+++ b/src/bootctl/bootctl-status.c
@@ -508,6 +508,7 @@ int verb_status(int argc, char *argv[], void *userdata) {
sd_id128_t stub_partition_uuid = SD_ID128_NULL;
(void) efi_stub_get_device_part_uuid(&stub_partition_uuid);
+ print_yes_no_line(/* first= */ false, !sd_id128_is_null(stub_partition_uuid), "Stub loader set partition information");
if (!sd_id128_is_null(stub_partition_uuid)) {
if (!(!sd_id128_is_null(esp_uuid) && sd_id128_equal(esp_uuid, stub_partition_uuid)) &&

View File

@ -0,0 +1,53 @@
From 5f631785cc2dc16bd85566f901cc474417fc0856 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sun, 9 Feb 2025 23:23:38 +0100
Subject: [PATCH] bootctl: suppress output of empty partition info if we also
have no idea about EFI binary path
So far we'd output both the partition and the binary path always, even
if we didn't know either (but in that case show empty information).
Let's address this, and show partition info only if we know it, or if we
know the EFI binary path, but suppress both if we know neither.
Note that we'll show the partition info if we don't know it still if we
know the EFI binary path used for boot, since it is relative to the
partition of course, and hence it's really strange to know one but not
the other, hence it deserves some mentioning in the output.
(cherry picked from commit df418fa234a5b12e302a336df82c97f33871ae35)
---
src/bootctl/bootctl-status.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/bootctl/bootctl-status.c b/src/bootctl/bootctl-status.c
index 9a4c233581..25c9f66a22 100644
--- a/src/bootctl/bootctl-status.c
+++ b/src/bootctl/bootctl-status.c
@@ -494,9 +494,11 @@ int verb_status(int argc, char *argv[], void *userdata) {
printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(loader_partition_uuid));
- } else
+ } else if (loader_path)
printf(" Partition: n/a\n");
- printf(" Loader: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(loader_path));
+
+ if (loader_path)
+ printf(" Loader: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(loader_path));
printf("\n");
}
@@ -518,9 +520,11 @@ int verb_status(int argc, char *argv[], void *userdata) {
printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(stub_partition_uuid));
- } else
+ } else if (stub_path)
printf(" Partition: n/a\n");
- printf(" Stub: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(stub_path));
+
+ if (stub_path)
+ printf(" Stub: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(stub_path));
printf("\n");
}

View File

@ -0,0 +1,52 @@
From 44260aa86bc3017d03046cac0cfe1e4d13a82e45 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sun, 9 Feb 2025 23:34:29 +0100
Subject: [PATCH] bootctl: minor reordering of fields in output
Let's move the currently used/default/oneshot entry output after the
basic info about the boot loader itself, since conceptually these are
objects kinda "one level down" from the boot loader perspective. Hence,
let's *first* show all info about the boot loader itself before we
display the objects it manages.
This is just a trivial change in output, just swaps th elines for these
fields with the ones showing where the boot loader is installed.
(cherry picked from commit af5b961ad8f22be04f47c1c0e729b1e6fd78b423)
---
src/bootctl/bootctl-status.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/bootctl/bootctl-status.c b/src/bootctl/bootctl-status.c
index 25c9f66a22..6f38b0f793 100644
--- a/src/bootctl/bootctl-status.c
+++ b/src/bootctl/bootctl-status.c
@@ -480,13 +480,6 @@ int verb_status(int argc, char *argv[], void *userdata) {
(void) efi_loader_get_device_part_uuid(&loader_partition_uuid);
print_yes_no_line(/* first= */ false, !sd_id128_is_null(loader_partition_uuid), "Boot loader set partition information");
- if (current_entry)
- printf("Current Entry: %s\n", current_entry);
- if (default_entry)
- printf("Default Entry: %s\n", default_entry);
- if (oneshot_entry && !streq_ptr(oneshot_entry, default_entry))
- printf("OneShot Entry: %s\n", oneshot_entry);
-
if (!sd_id128_is_null(loader_partition_uuid)) {
if (!sd_id128_is_null(esp_uuid) && !sd_id128_equal(esp_uuid, loader_partition_uuid))
printf("WARNING: The boot loader reports a different partition UUID than the detected ESP ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
@@ -499,6 +492,14 @@ int verb_status(int argc, char *argv[], void *userdata) {
if (loader_path)
printf(" Loader: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(loader_path));
+
+ if (current_entry)
+ printf("Current Entry: %s\n", current_entry);
+ if (default_entry)
+ printf("Default Entry: %s\n", default_entry);
+ if (oneshot_entry && !streq_ptr(oneshot_entry, default_entry))
+ printf("OneShot Entry: %s\n", oneshot_entry);
+
printf("\n");
}

View File

@ -0,0 +1,46 @@
From 480e39dbbb3df253e02a4908dfcfecf1fb3511e2 Mon Sep 17 00:00:00 2001
From: Michael Olbrich <m.olbrich@pengutronix.de>
Date: Sun, 9 Feb 2025 13:32:36 +0100
Subject: [PATCH] missing_sched: add CLONE_PIDFD
CLONE_PIDFD was introduced in v5.2 and in sched.h in glibc-2.31 so
without this, building with older version fails with:
src/basic/raw-clone.h:41:108: error: 'CLONE_PIDFD' undeclared (first use in this function); did you mean 'CLONE_FILES'?
(cherry picked from commit e91c5cf06ab7ca9e5576c6feac5f743927f2b063)
---
src/basic/missing_sched.h | 7 +++++++
src/basic/raw-clone.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/src/basic/missing_sched.h b/src/basic/missing_sched.h
index bbfc30cc8f..6e5e2b1e20 100644
--- a/src/basic/missing_sched.h
+++ b/src/basic/missing_sched.h
@@ -13,6 +13,13 @@
assert_cc(CLONE_NEWCGROUP == 0x02000000);
#endif
+/* b3e5838252665ee4cfa76b82bdf1198dca81e5be (5.2) */
+#ifndef CLONE_PIDFD
+# define CLONE_PIDFD 0x00001000
+#else
+assert_cc(CLONE_PIDFD == 0x00001000);
+#endif
+
/* 769071ac9f20b6a447410c7eaa55d1a5233ef40c (5.8) */
#ifndef CLONE_NEWTIME
# define CLONE_NEWTIME 0x00000080
diff --git a/src/basic/raw-clone.h b/src/basic/raw-clone.h
index 36202cc0ba..91b0069fb5 100644
--- a/src/basic/raw-clone.h
+++ b/src/basic/raw-clone.h
@@ -11,6 +11,7 @@
#include "log.h"
#include "macro.h"
+#include "missing_sched.h"
#include "process-util.h"
/**

View File

@ -0,0 +1,30 @@
From e8d5d7f355ae826f4f8c0f61f62c31e828bde7d0 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Tue, 4 Feb 2025 14:52:02 +0100
Subject: [PATCH] stub: Mention that VirtualSize should be <= SizeOfRawData
(cherry picked from commit 2443b4d9a17787fd0a63d6591fbdb74650c43994)
---
man/systemd-stub.xml | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/man/systemd-stub.xml b/man/systemd-stub.xml
index 902b4013a0..779867f4d6 100644
--- a/man/systemd-stub.xml
+++ b/man/systemd-stub.xml
@@ -376,6 +376,15 @@
core kernel, the embedded initrd and kernel command line (see above for a full list), including all UKI
profiles.</para>
+ <para>Also note that when <command>systemd-stub</command> measures a PE section, it will measure the
+ amount of bytes that the section takes up in memory (<varname>VirtualSize</varname>) and not the amount
+ of bytes that the section takes up on disk (<varname>SizeOfRawData</varname>). This means that if the
+ size in memory is larger than the size on disk, <command>systemd-stub</command> will end up measuring
+ extra zeroes. To avoid this from happening, it is recommended to make sure that the size in memory of
+ each section that is measured by <command>systemd-stub</command> is always smaller than or equal to the
+ size on disk. <command>ukify</command> automatically makes sure this is the case when building UKIs or
+ addons.</para>
+
<para>Also note that the Linux kernel will measure all initrds it receives into TPM PCR 9. This means
every type of initrd (of the selected UKI profile) will possibly be measured two or three times: the
initrds embedded in the kernel image will be measured to PCR 4, PCR 9 and PCR 11; the initrd synthesized

View File

@ -0,0 +1,42 @@
From 131eff83701ed40468fb68fb0ed33108f215950e Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@suse.com>
Date: Fri, 7 Feb 2025 14:36:06 +0100
Subject: [PATCH] import-pubring.gpg: add openSUSE build key
(cherry picked from commit c8c5ce5772b08da0ad317331b1f4929c1b466ae0)
---
src/import/import-pubring.gpg | Bin 9551 -> 10746 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/src/import/import-pubring.gpg b/src/import/import-pubring.gpg
index be27776896f30f580b03ad79d733483f81c8d117..57f9d04d8bc0c84e55f15c9c64203294c8b2584e 100644
GIT binary patch
delta 1188
zcmV;V1Y7&hO8Qf<PbGhu0u2OWuzn%|5CGowvXMDvvE(8=+@&SU_E8Slf^H<Iy=TEI
zS6%|!Rr;dSXH7cO-5x+Ar83tegx9*`P$7%-urk0)G{a(Y9{+XN4Gf=sAH$xXse#Sy
zG-pF)gJIcKn43scSiTRfb}R1lcC`amc~e~lqWm1$tO8YQH;aF-*RGY~DU<p9__sw}
zitSehuHTbU4f28@q10GPoEOL$FO)J7@N~5RLze;jw}64Rxsfa7Sfp~8yx;)!WC!y}
zx~TK}BiZ!3No8@^t~$NRp)$~)G%|l~PGw+$nw?DbvE(VpTK?GG`PObi|GE^>xH*k~
zF51yT!QQCJT)=-PjIlpDEqG8(yj}Axlu3jU<{`FI<sZ0j6gVQS5zXpLEC%zbPvs(#
zp<yTDENZYSo_fS=J*PXeXSb{;VgFEA`Q`U`c6(3ii-KxT-0=5&?0hi|WBj2`>Z-m2
zdUmFR*Z@H_<ODQ=K31Be&S}J##NIscj&JHjEe`IJsQ7;mNc*x>BX)Z~!9n2hv4q~^
z1#yvNqC@ZKEII+awTe1{d+L}6*0Sz-BIARoI>K*?yl<yX3`Pqk_%9)Q;Cw(fO$BBm
zK1fGo5n|+I5>bsf7AcX~8g6x8YbK`3KSdtQN?e<JW~jS}bJhaJqb=i0TR`O%O1njI
ziDk5(@=bqSZr+(xrwd6L2CoQ{J4FBy0RRE83;+OUaAyGk000000JJo3aAj^&RZ~SE
zP;zf-Wn*+8Q)y>zX>MmAOJ#W=Ja2GiZgX{WWk7FmWo~nIb7d}Xa%VoU3;+OUaAyJl
z000000Eq%V1QP)Q04N0lVz7Q90viJb2?vDE00xr+4IF<pqWEqpw*aK1YY+g5G8SR5
z@<BRACIH*V=4z#rZriL4$Yz5$@}%<-7n{tcv}Ao>ff7I5IBR?s3((G2IlcbdqBDC+
zZjT~Rv#m{*jbd)pDhiCQcJu$HW;Oj<_wS4)Fi>s@@FR7ncwu=Pd%C+AXz1y|eD<qB
zeL94-q-%eCI4wN9f3x4#T(PLpb}9%Yk5+{`>NFTNz^&eq{)VirzI#_BI8^vM-a2#w
zIUqqE5R6GZ#6tSwH}R((|ExP-RG9j59DNfrly2hi>w_|wDL=x^xn+H#Qj^yNxi&mX
z{cJz}!DqHFI87{|hz!=nVAAc;|71?bLkgg`D(rttOT(@n6YM9$*2iI#4Vf>A|6eKW
z8ayMnzVT#Y`fusF&P5Sx2p?Oa#G>FNVM9!D#%9&Nn<(c~HPs?YNgA@KqFmUFcS@BO
z4B7Q=G>u-Xpqc3LSA%6SqV-(ODaJ7E_Z^Wm_WEFv5W%kvZx>2GT6whENT64&SRPJr
zCm(+=FTOB7@SDTE)HOd&N!(ZiKFL0zjt{3PDel*B0rs(pr5czZ0EII~ujNGH1?F6M
zOAvhD!c^hx@el8TC3nG0PYGseMzO{3?~J{iD^fX}+VG=_kIF7t8GGN+OrIZPMc&6A
zJ<}sBrlR+b4t9Hgas-zwg|aYK-FuMrcj*{rvLwKJnq^*0>aC&r7#20K1^@$RaAyFO
C!7JPV
delta 7
OcmewreBNt=zbXI_)dPzF

View File

@ -0,0 +1,630 @@
From d14161d4d08037f28070c9766ae1aebc32876064 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 7 Feb 2025 14:58:29 +0100
Subject: [PATCH] import: update to current fedora keyring
Add a bunch of more released keys. Kinda a follow-up for c8c5ce5772b08da0ad317331b1f4929c1b466ae0
(cherry picked from commit 8135d37f81917f2a7f98a52bdae92eae5878946d)
---
src/import/import-pubring.gpg | Bin 10746 -> 45015 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/src/import/import-pubring.gpg b/src/import/import-pubring.gpg
index 57f9d04d8bc0c84e55f15c9c64203294c8b2584e..8c6d2ebea6014006d327964bed4cdbd78637789f 100644
GIT binary patch
delta 34116
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
delta 8
Pcmcb9pXpcdhF_Wh7eEBr

View File

@ -0,0 +1,39 @@
From 87224a2d4efa30b48407f71aad3ee2df591fe224 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
Date: Thu, 30 Jan 2025 01:19:59 +0000
Subject: [PATCH] ukify: do not fail if pefile complains about hardcoded 256MB
limit
pefile has an hardcoded limit to 256MB per section:
https://github.com/erocarrera/pefile/issues/396
When building an initrd with large firmware files and
lots of kernel modules, this limit can be reached.
Skip over those warnings.
(cherry picked from commit 32caed550f5a81eb87d2e39bc83917df2898d844)
---
src/ukify/ukify.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index 7a9f63e1d4..6ad4298ebe 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -892,8 +892,14 @@ def pe_add_sections(uki: UKI, output: str) -> None:
)
pe = pefile.PE(data=pe.write(), fast_load=True)
+ # pefile has an hardcoded limit of 256MB, which is not enough when building an initrd with large firmware
+ # files and all kernel modules. See: https://github.com/erocarrera/pefile/issues/396
warnings = pe.get_warnings()
- if warnings:
+ for w in warnings:
+ if 'VirtualSize is extremely large' in w:
+ continue
+ if 'VirtualAddress is beyond' in w:
+ continue
raise PEError(f'pefile warnings treated as errors: {warnings}')
security = pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']]

View File

@ -0,0 +1,23 @@
From 6caab0c58c8c43c5d4244e2ef2bb739aa06d81c0 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Sun, 9 Feb 2025 15:38:05 +0100
Subject: [PATCH] tmpfiles: fix copypasta in create_symlink() (FIFO -> symlink)
(cherry picked from commit 6f91e7a3bea2c5046354b31cb650b54e3b2884d5)
---
src/tmpfiles/tmpfiles.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index bff05cda6f..b699a1e5be 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -2422,7 +2422,7 @@ static int create_symlink(Context *c, Item *i) {
return log_error_errno(r, "Failed to extract filename from path '%s': %m", i->path);
if (r == O_DIRECTORY)
return log_error_errno(SYNTHETIC_ERRNO(EISDIR),
- "Cannot open path '%s' for creating FIFO, is a directory.", i->path);
+ "Cannot open path '%s' for creating symlink, is a directory.", i->path);
if (arg_dry_run) {
log_info("Would create symlink %s -> %s", i->path, i->argument);

View File

@ -0,0 +1,23 @@
From a112fca1212c1488c6c43991df2be1fc171b8138 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 12 Feb 2025 09:20:51 +0900
Subject: [PATCH] udev-worker: add debugging log about success of flock() for
whole block device
(cherry picked from commit 951def0e276c041a262b3f147bb42206195fe13e)
---
src/udev/udev-worker.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c
index 59f56f653c..fc1bfd684c 100644
--- a/src/udev/udev-worker.c
+++ b/src/udev/udev-worker.c
@@ -123,6 +123,7 @@ static int worker_lock_whole_disk(sd_device *dev, int *ret_fd) {
if (flock(fd, LOCK_SH|LOCK_NB) < 0)
return log_device_debug_errno(dev, errno, "Failed to flock(%s): %m", val);
+ log_device_debug(dev, "Successfully took flock(LOCK_SH) for %s, it will be released after the event has been processed.", val);
*ret_fd = TAKE_FD(fd);
return 1;

View File

@ -0,0 +1,23 @@
From cc77e140a8b194f710f33c9f552750ce350e6122 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 12 Feb 2025 09:22:49 +0900
Subject: [PATCH] udev-watch: mention that the failure is ignored
(cherry picked from commit a52aad3b4bb735a22ce67110142d135819589a87)
---
src/udev/udev-watch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
index 1b8e2b8dbd..9bd34af858 100644
--- a/src/udev/udev-watch.c
+++ b/src/udev/udev-watch.c
@@ -167,7 +167,7 @@ finalize:
/* 5. remove symlink ID -> wd.
* The file is always owned by the device. Hence, it is safe to remove it unconditionally. */
if (unlinkat(dirfd, id, 0) < 0 && errno != ENOENT)
- log_device_debug_errno(dev, errno, "Failed to remove '/run/udev/watch/%s': %m", id);
+ log_device_debug_errno(dev, errno, "Failed to remove '/run/udev/watch/%s', ignoring: %m", id);
return r;
}

View File

@ -0,0 +1,42 @@
From d32f4bcaf274e208568a5e6151c0a81d00d80438 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 12 Feb 2025 09:23:33 +0900
Subject: [PATCH] udev-watch: do not try to remove invalid watch handle
When a new device is processed, there should be no watch handle for
the device, hence udev_watch_clear() provides -1. Let's not try to call
inotify_rm_watch() in that case.
This should not change any behavior. Just for suppressing spurious
debugging log:
=====
(udev-worker)[3626140]: zram1: Removing watch handle -1.
=====
(cherry picked from commit b3b442062045eac61a9dd3ed73b650dfb5be0b46)
---
src/udev/udev-watch.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
index 9bd34af858..82db39fecd 100644
--- a/src/udev/udev-watch.c
+++ b/src/udev/udev-watch.c
@@ -161,7 +161,7 @@ static int udev_watch_clear(sd_device *dev, int dirfd, int *ret_wd) {
if (ret_wd)
*ret_wd = wd;
- r = 0;
+ r = 1;
finalize:
/* 5. remove symlink ID -> wd.
@@ -249,7 +249,7 @@ int udev_watch_end(int inotify_fd, sd_device *dev) {
/* First, clear symlinks. */
r = udev_watch_clear(dev, dirfd, &wd);
- if (r < 0)
+ if (r <= 0)
return r;
/* Then, remove inotify watch. */

View File

@ -0,0 +1,35 @@
From b555b473a4c206db28d75d82f2a7fc43accf998f Mon Sep 17 00:00:00 2001
From: msizanoen <msizanoen@qtmlabs.xyz>
Date: Wed, 12 Feb 2025 22:09:01 +0700
Subject: [PATCH] login: Continue watching leader pidfd after stop
This ensures that garbage collection will be triggered when the leader
process dies.
(cherry picked from commit b2a4109031c1bd79c498f8642df150deeebe1708)
---
src/login/logind-session.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 351b64b60b..e825d39f6c 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -90,6 +90,9 @@ static int session_dispatch_leader_pidfd(sd_event_source *es, int fd, uint32_t r
Session *s = ASSERT_PTR(userdata);
assert(s->leader.fd == fd);
+
+ s->leader_pidfd_event_source = sd_event_source_unref(s->leader_pidfd_event_source);
+
session_stop(s, /* force= */ false);
return 1;
@@ -950,7 +953,6 @@ int session_stop(Session *s, bool force) {
return 0;
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
- s->leader_pidfd_event_source = sd_event_source_unref(s->leader_pidfd_event_source);
if (s->seat)
seat_evict_position(s->seat, s);

View File

@ -0,0 +1,35 @@
From 528d7d616fab8466111c8767010143e1beb1e22d Mon Sep 17 00:00:00 2001
From: msizanoen <msizanoen@qtmlabs.xyz>
Date: Wed, 12 Feb 2025 21:27:25 +0700
Subject: [PATCH] login: Queue session for garbage collection on leader death
This ensures sessions are cleaned up properly in case the user service
manager was manually stopped.
(cherry picked from commit a6bccda28d398925397d3a8f0c7491ba03941f23)
---
src/login/logind-session.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index e825d39f6c..57cc37ccc4 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -95,6 +95,8 @@ static int session_dispatch_leader_pidfd(sd_event_source *es, int fd, uint32_t r
session_stop(s, /* force= */ false);
+ session_add_to_gc_queue(s);
+
return 1;
}
@@ -1263,6 +1265,8 @@ static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents,
session_remove_fifo(s);
session_stop(s, /* force = */ false);
+ session_add_to_gc_queue(s);
+
return 1;
}

View File

@ -0,0 +1,180 @@
From 47be0e801ef7761a2472fd704400e4fd3b737625 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
Date: Sun, 19 Jan 2025 15:42:47 +0000
Subject: [PATCH] ukify: print debug/progress messages to stderr
Otherwise json will be interleaved with plain text messages
(cherry picked from commit 7d64e2f368ec7c683fee95d21f527c406b8eb5e6)
---
src/ukify/ukify.py | 39 +++++++++++++++++++++------------------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index 6ad4298ebe..9570898011 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -324,7 +324,7 @@ class Uname:
filename,
]
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
try:
notes = subprocess.check_output(cmd, stderr=subprocess.PIPE, text=True)
except subprocess.CalledProcessError as e:
@@ -355,7 +355,7 @@ class Uname:
for func in (cls.scrape_x86, cls.scrape_elf, cls.scrape_generic):
try:
version = func(filename, opts=opts)
- print(f'Found uname version: {version}')
+ print(f'Found uname version: {version}', file=sys.stderr)
return version
except ValueError as e:
print(str(e))
@@ -495,7 +495,7 @@ class PeSign(SignTool):
'-o', output_f,
] # fmt: skip
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
subprocess.check_call(cmd)
@staticmethod
@@ -505,7 +505,7 @@ class PeSign(SignTool):
tool = find_tool('pesign', opts=opts)
cmd = [tool, '-i', opts.linux, '-S']
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
info = subprocess.check_output(cmd, text=True)
return 'No signatures found.' in info
@@ -527,7 +527,7 @@ class SbSign(SignTool):
'--output', output_f,
] # fmt: skip
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
subprocess.check_call(cmd)
@staticmethod
@@ -537,7 +537,7 @@ class SbSign(SignTool):
tool = find_tool('sbverify', opts=opts)
cmd = [tool, '--list', opts.linux]
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
info = subprocess.check_output(cmd, text=True)
return 'No signature table present' in info
@@ -579,7 +579,7 @@ class SystemdSbSign(SignTool):
'--output', output_f,
] # fmt: skip
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
subprocess.check_call(cmd)
@staticmethod
@@ -626,7 +626,7 @@ def check_splash(filename: Optional[Path]) -> None:
return
img = Image.open(filename, formats=['BMP'])
- print(f'Splash image {filename} is {img.width}×{img.height} pixels')
+ print(f'Splash image {filename} is {img.width}×{img.height} pixels', file=sys.stderr)
def check_inputs(opts: UkifyConfig) -> None:
@@ -769,7 +769,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) ->
*(f'--phase={phase_path}' for phase_path in itertools.chain.from_iterable(pp_groups)),
]
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
subprocess.check_call(cmd)
# PCR signing
@@ -807,7 +807,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) ->
extra += [f'--phase={phase_path}' for phase_path in group or ()]
- print('+', shell_join(cmd + extra)) # type: ignore
+ print('+', shell_join(cmd + extra), file=sys.stderr) # type: ignore
pcrsig = subprocess.check_output(cmd + extra, text=True) # type: ignore
pcrsig = json.loads(pcrsig)
pcrsigs += [pcrsig]
@@ -1120,7 +1120,7 @@ def make_uki(opts: UkifyConfig) -> None:
signtool.sign(os.fspath(opts.linux), os.fspath(linux), opts=opts)
if opts.uname is None and opts.linux is not None:
- print('Kernel version not specified, starting autodetection 😖.')
+ print('Kernel version not specified, starting autodetection 😖.', file=sys.stderr)
opts.uname = Uname.scrape(opts.linux, opts=opts)
uki = UKI(opts.stub)
@@ -1138,7 +1138,7 @@ def make_uki(opts: UkifyConfig) -> None:
if opts.certificate_provider:
cmd += ['--certificate-source', f'provider:{opts.certificate_provider}']
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
pcrpkey = subprocess.check_output(cmd)
else:
pcrpkey = Path(opts.pcr_public_keys[0])
@@ -1150,7 +1150,7 @@ def make_uki(opts: UkifyConfig) -> None:
if opts.signing_provider:
cmd += ['--private-key-source', f'provider:{opts.signing_provider}']
- print('+', shell_join(cmd))
+ print('+', shell_join(cmd), file=sys.stderr)
pcrpkey = subprocess.check_output(cmd)
hwids = None
@@ -1249,7 +1249,10 @@ def make_uki(opts: UkifyConfig) -> None:
if n not in to_import:
continue
- print(f"Copying section '{n}' from '{profile}': {pesection.Misc_VirtualSize} bytes")
+ print(
+ f"Copying section '{n}' from '{profile}': {pesection.Misc_VirtualSize} bytes",
+ file=sys.stderr,
+ )
uki.add_section(
Section.create(n, pesection.get_data(length=pesection.Misc_VirtualSize), measure=True)
)
@@ -1278,7 +1281,7 @@ def make_uki(opts: UkifyConfig) -> None:
os.umask(umask := os.umask(0))
os.chmod(opts.output, 0o777 & ~umask)
- print(f'Wrote {"signed" if sign_args_present else "unsigned"} {opts.output}')
+ print(f'Wrote {"signed" if sign_args_present else "unsigned"} {opts.output}', file=sys.stderr)
@contextlib.contextmanager
@@ -1930,14 +1933,14 @@ def apply_config(namespace: argparse.Namespace, filename: Union[str, Path, None]
if namespace.config:
# Config set by the user, use that.
filename = namespace.config
- print(f'Using config file: {filename}')
+ print(f'Using config file: {filename}', file=sys.stderr)
else:
# Try to look for a config file then use the first one found.
for config_dir in DEFAULT_CONFIG_DIRS:
filename = Path(config_dir) / DEFAULT_CONFIG_FILE
if filename.is_file():
# Found a config file, use it.
- print(f'Using found config file: {filename}')
+ print(f'Using found config file: {filename}', file=sys.stderr)
break
else:
# No config file specified or found, nothing to do.
@@ -2061,7 +2064,7 @@ def finalize_options(opts: argparse.Namespace) -> None:
elif opts.linux or opts.initrd:
raise ValueError('--linux=/--initrd= options cannot be used with positional arguments')
else:
- print("Assuming obsolete command line syntax with no verb. Please use 'build'.")
+ print("Assuming obsolete command line syntax with no verb. Please use 'build'.", file=sys.stderr)
if opts.positional:
opts.linux = Path(opts.positional[0])
# If we have initrds from parsing config files, append our positional args at the end

View File

@ -0,0 +1,53 @@
From f01ba41caefd8e574a6eda2af9f577d2d24d03e6 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Wed, 29 Jan 2025 14:44:27 +0100
Subject: [PATCH] ukify: Calculate section size more correctly
We should only use Misc_VirtualSize if it's smaller than SizeOfRawData,
since in that case it'll be the non-aligned section size. Otherwise we
have to use SizeOfRawData to get the size on disk.
(cherry picked from commit 33b25fa11c408ae40f2aa4300220504329a23a52)
---
src/ukify/ukify.py | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index 9570898011..b246fe13ca 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -710,6 +710,10 @@ def pe_strip_section_name(name: bytes) -> str:
return name.rstrip(b'\x00').decode()
+def pe_section_size(section: pefile.SectionStructure) -> int:
+ return cast(int, min(section.Misc_VirtualSize, section.SizeOfRawData))
+
+
def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) -> None:
measure_tool = find_tool(
'systemd-measure',
@@ -1250,11 +1254,11 @@ def make_uki(opts: UkifyConfig) -> None:
continue
print(
- f"Copying section '{n}' from '{profile}': {pesection.Misc_VirtualSize} bytes",
+ f"Copying section '{n}' from '{profile}': {pe_section_size(pesection)} bytes",
file=sys.stderr,
)
uki.add_section(
- Section.create(n, pesection.get_data(length=pesection.Misc_VirtualSize), measure=True)
+ Section.create(n, pesection.get_data(length=pe_section_size(pesection)), measure=True)
)
call_systemd_measure(uki, opts=opts, profile_start=prev_len)
@@ -1434,8 +1438,7 @@ def inspect_section(
ttype = config.output_mode if config else DEFAULT_SECTIONS_TO_SHOW.get(name, 'binary')
- size = section.Misc_VirtualSize
- # TODO: Use ignore_padding once we can depend on a newer version of pefile
+ size = pe_section_size(section)
data = section.get_data(length=size)
digest = sha256(data).hexdigest()

View File

@ -0,0 +1,281 @@
From 158c9ca6a9f28fce35422cf5e55d6fa55e402f41 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Wed, 12 Feb 2025 11:09:36 +0100
Subject: [PATCH] mkosi: Update to latest
In https://github.com/systemd/mkosi/pull/3497, mkosi has started parsing
options passed after the verb as regular mkosi options instead of options
for the invoked command. We adapt to this change by adding '--' as a delimiter
everywhere where required.
(cherry picked from commit b429f82eaf774d9b9f67c201770074a9ec72647e)
---
.github/workflows/coverage.yml | 16 ++++++------
.github/workflows/mkosi.yml | 12 ++++-----
docs/HACKING.md | 40 +++++++++++++++---------------
test/README.testsuite | 14 +++++------
test/fmf/integration-tests/test.sh | 8 +++---
5 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 6503059ef4..1cce9a97f3 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -16,7 +16,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- - uses: systemd/mkosi@0de0aa905625317ff10cc4b44ec9379a7aa65aa6
+ - uses: systemd/mkosi@d501139032aa659fa8d34bdb850f4eb6b5f458ed
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location
@@ -74,23 +74,23 @@ jobs:
run: mkosi summary
- name: Build tools tree
- run: sudo mkosi -f sandbox true
+ run: sudo mkosi -f sandbox -- true
- name: Configure meson
run: |
- sudo mkosi sandbox \
+ sudo mkosi sandbox -- \
meson setup \
--buildtype=debugoptimized \
-Dintegration-tests=true \
build
- name: Build image
- run: sudo mkosi sandbox meson compile -C build mkosi
+ run: sudo mkosi sandbox -- meson compile -C build mkosi
- name: Initial coverage report
run: |
sudo mkdir -p build/test/coverage
- sudo mkosi sandbox \
+ sudo mkosi sandbox -- \
lcov \
--directory build/mkosi.builddir/arch~rolling~x86-64 \
--capture \
@@ -107,7 +107,7 @@ jobs:
# --preserve-env makes sure all the github actions environment variables are propagated which are
# used in integration-test-wrapper.py to construct the `gh` command line to download the journals
# of failed tests.
- sudo --preserve-env mkosi sandbox \
+ sudo --preserve-env mkosi sandbox -- \
meson test \
-C build \
--no-rebuild \
@@ -136,10 +136,10 @@ jobs:
lcov_args+=(--add-tracefile "${file}")
done < <(find build/test/coverage -name "TEST-*.coverage-info")
- sudo mkosi sandbox lcov --ignore-errors inconsistent,inconsistent "${lcov_args[@]}" --output-file build/test/coverage/everything.coverage-info
+ sudo mkosi sandbox -- lcov --ignore-errors inconsistent,inconsistent "${lcov_args[@]}" --output-file build/test/coverage/everything.coverage-info
- name: List coverage report
- run: sudo mkosi sandbox lcov --ignore-errors inconsistent,inconsistent --list build/test/coverage/everything.coverage-info
+ run: sudo mkosi sandbox -- lcov --ignore-errors inconsistent,inconsistent --list build/test/coverage/everything.coverage-info
- name: Coveralls
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
index d662d65dad..2b00498243 100644
--- a/.github/workflows/mkosi.yml
+++ b/.github/workflows/mkosi.yml
@@ -120,7 +120,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- - uses: systemd/mkosi@0de0aa905625317ff10cc4b44ec9379a7aa65aa6
+ - uses: systemd/mkosi@d501139032aa659fa8d34bdb850f4eb6b5f458ed
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location
@@ -188,22 +188,22 @@ jobs:
run: mkosi summary
- name: Build tools tree
- run: sudo mkosi -f sandbox true
+ run: sudo mkosi -f sandbox -- true
- name: Configure meson
run: |
- sudo mkosi sandbox \
+ sudo mkosi sandbox -- \
meson setup \
--buildtype=debugoptimized \
-Dintegration-tests=true \
build
- name: Build image
- run: sudo mkosi sandbox meson compile -C build mkosi
+ run: sudo mkosi sandbox -- meson compile -C build mkosi
- name: Run integration tests
run: |
- if [[ "$(sudo mkosi sandbox meson test --help)" == *"--max-lines"* ]]; then
+ if [[ "$(sudo mkosi sandbox -- meson test --help)" == *"--max-lines"* ]]; then
MAX_LINES=(--max-lines 300)
else
MAX_LINES=()
@@ -212,7 +212,7 @@ jobs:
# --preserve-env makes sure all the github actions environment variables are propagated which are
# used in integration-test-wrapper.py to construct the `gh` command line to download the journals
# of failed tests.
- sudo --preserve-env mkosi sandbox \
+ sudo --preserve-env mkosi sandbox -- \
env \
TEST_PREFER_QEMU=${{ matrix.vm }} \
TEST_SKIP=${{ matrix.skip }} \
diff --git a/docs/HACKING.md b/docs/HACKING.md
index e534a51335..697ec9b545 100644
--- a/docs/HACKING.md
+++ b/docs/HACKING.md
@@ -39,18 +39,18 @@ chance that your distribution's packaged version of mkosi will be too old.
Then, you can build and run systemd executables as follows:
```sh
-$ mkosi -f sandbox meson setup build
-$ mkosi -f sandbox meson compile -C build
-$ mkosi -f sandbox build/systemctl --version
+$ mkosi -f sandbox -- meson setup build
+$ mkosi -f sandbox -- meson compile -C build
+$ mkosi -f sandbox -- build/systemctl --version
```
To build and boot an OS image with the latest systemd installed:
```sh
-$ mkosi -f genkey # Generate signing keys once.
-$ mkosi -f sandbox meson compile -C build mkosi # (re-)build the OS image
-$ mkosi boot # Boot the image with systemd-nspawn.
-$ mkosi vm # Boot the image with qemu.
+$ mkosi -f genkey # Generate signing keys once.
+$ mkosi -f sandbox -- meson compile -C build mkosi # (re-)build the OS image
+$ mkosi boot # Boot the image with systemd-nspawn.
+$ mkosi vm # Boot the image with qemu.
```
Putting this all together, here's a series of commands for preparing a patch for
@@ -61,15 +61,15 @@ $ git clone https://github.com/systemd/mkosi.git
$ ln -s $PWD/mkosi/bin/mkosi ~/.local/bin/mkosi # Make sure ~/.local/bin is in $PATH.
$ git clone https://github.com/systemd/systemd.git
$ cd systemd
-$ git checkout -b <BRANCH> # where BRANCH is the name of the branch
-$ $EDITOR src/core/main.c # or wherever you'd like to make your changes
-$ mkosi -f sandbox meson setup build # Set up meson
-$ mkosi -f genkey # Generate signing keys once.
-$ mkosi -f sandbox meson compile -C build mkosi # (re-)build the test image
-$ mkosi vm # Boot the image in qemu
-$ git add -p # interactively put together your patch
-$ git commit # commit it
-$ git push -u <REMOTE> # where REMOTE is your "fork" on GitHub
+$ git checkout -b <BRANCH> # where BRANCH is the name of the branch
+$ $EDITOR src/core/main.c # or wherever you'd like to make your changes
+$ mkosi -f sandbox -- meson setup build # Set up meson
+$ mkosi -f genkey # Generate signing keys once.
+$ mkosi -f sandbox -- meson compile -C build mkosi # (re-)build the test image
+$ mkosi vm # Boot the image in qemu
+$ git add -p # interactively put together your patch
+$ git commit # commit it
+$ git push -u <REMOTE> # where REMOTE is your "fork" on GitHub
```
And after that, head over to your repo on GitHub and click "Compare & pull
@@ -101,10 +101,10 @@ the following commands in another terminal on your host after booting the image
machine):
```sh
-mkosi -t none && mkosi ssh dnf upgrade --disablerepo="*" --assumeyes "/work/build/*.rpm" # CentOS/Fedora
-mkosi -t none && mkosi ssh apt-get install "/work/build/*.deb" # Debian/Ubuntu
-mkosi -t none && mkosi ssh pacman --upgrade --needed --noconfirm "/work/build/*.pkg.tar" # Arch Linux
-mkosi -t none && mkosi ssh zypper --non-interactive install --allow-unsigned-rpm "/work/build/*.rpm" # OpenSUSE
+mkosi -t none && mkosi ssh -- dnf upgrade --disablerepo="*" --assumeyes "/work/build/*.rpm" # CentOS/Fedora
+mkosi -t none && mkosi ssh -- apt-get install "/work/build/*.deb" # Debian/Ubuntu
+mkosi -t none && mkosi ssh -- pacman --upgrade --needed --noconfirm "/work/build/*.pkg.tar" # Arch Linux
+mkosi -t none && mkosi ssh -- zypper --non-interactive install --allow-unsigned-rpm "/work/build/*.rpm" # OpenSUSE
```
and optionally restart the daemon(s) you're working on using
diff --git a/test/README.testsuite b/test/README.testsuite
index 02f5404410..3a16255b96 100644
--- a/test/README.testsuite
+++ b/test/README.testsuite
@@ -11,7 +11,7 @@ reconfiguring meson to make sure it is picked up properly.
Next, we can build the integration test image with meson:
```shell
-$ mkosi -f sandbox meson compile -C build mkosi
+$ mkosi -f sandbox -- meson compile -C build mkosi
```
By default, the `mkosi` meson target which builds the integration test image depends on
@@ -32,24 +32,24 @@ directory (`OutputDirectory=`) to point to the other directory using `mkosi.loca
After the image has been built, the integration tests can be run with:
```shell
-$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox meson test -C build --no-rebuild --suite integration-tests --num-processes "$(($(nproc) / 4))"
+$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --no-rebuild --suite integration-tests --num-processes "$(($(nproc) / 4))"
```
As usual, specific tests can be run in meson by appending the name of the test
which is usually the name of the directory e.g.
```shell
-$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox meson test -C build --no-rebuild -v TEST-01-BASIC
+$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --no-rebuild -v TEST-01-BASIC
```
-See `mkosi -f sandbox meson introspect build --tests` for a list of tests.
+See `mkosi -f sandbox -- meson introspect build --tests` for a list of tests.
To interactively debug a failing integration test, the `--interactive` option
(`-i`) for `meson test` can be used. Note that this requires meson v1.5.0 or
newer:
```shell
-$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox meson test -C build --no-rebuild -i TEST-01-BASIC
+$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --no-rebuild -i TEST-01-BASIC
```
Due to limitations in meson, the integration tests do not yet depend on the
@@ -58,7 +58,7 @@ running the integration tests. To rebuild the image and rerun a test, the
following command can be used:
```shell
-$ mkosi -f sandbox meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox meson test -C build --no-rebuild -v TEST-01-BASIC
+$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --no-rebuild -v TEST-01-BASIC
```
The integration tests use the same mkosi configuration that's used when you run
@@ -72,7 +72,7 @@ To iterate on an integration test, let's first get a shell in the integration te
the following:
```shell
-$ mkosi -f sandbox meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 TEST_SHELL=1 mkosi -f sandbox meson test -C build --no-rebuild -i TEST-01-BASIC
+$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 TEST_SHELL=1 mkosi -f sandbox -- meson test -C build --no-rebuild -i TEST-01-BASIC
```
This will get us a shell in the integration test environment after booting the machine without running the
diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh
index aff79340f7..c5ba7507de 100755
--- a/test/fmf/integration-tests/test.sh
+++ b/test/fmf/integration-tests/test.sh
@@ -132,11 +132,11 @@ export TEST_SKIP="TEST-21-DFUZZER"
mkdir -p /etc/pacman.d/gnupg
mkosi summary
-mkosi -f sandbox true
-mkosi -f sandbox meson setup --buildtype=debugoptimized -Dintegration-tests=true build
+mkosi -f sandbox -- true
+mkosi -f sandbox -- meson setup --buildtype=debugoptimized -Dintegration-tests=true build
mkosi genkey
-mkosi -f sandbox meson compile -C build mkosi
-mkosi -f sandbox \
+mkosi -f sandbox -- meson compile -C build mkosi
+mkosi -f sandbox -- \
meson test \
-C build \
--no-rebuild \

View File

@ -0,0 +1,82 @@
From 8f8514c03f166c352ebdcb577c29d2dff88a37f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 13 Feb 2025 15:49:50 +0100
Subject: [PATCH] core/condition: fix segfault when key not found in os-release
'ConditionOSRelease=|ID_LIKE$=*rhel*' results in a segfault.
The key 'ID_LIKE' is not present in Fedora's os-release file.
I think the most reasonable behaviour is to treat missing keys as empty.
This matches the "shell-like" sprit, since in a shell empty keys would
by default be treated as empty too. Thus, "ID_LIKE=" would match, if
ID_LIKE is not present in the file, and ID_LIKE=!$foo" would also match.
The other option would be to make those matches fail, but I think that'd
make the feature harder to use, esp. with negative matches.
Documentation is updated to clarify the new behaviour.
https://bugzilla.redhat.com/show_bug.cgi?id=2345544
(cherry picked from commit de02b551adcf74e5677454fd36bf7653b1a4def1)
---
man/systemd.unit.xml | 2 ++
src/shared/condition.c | 4 +++-
src/test/test-condition.c | 18 ++++++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 2c7f0bd71f..d44eb028ca 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1960,6 +1960,8 @@
wildcard comparisons (<literal>*</literal>, <literal>?</literal>, <literal>[]</literal>) are
supported with the <literal>$=</literal> (match) and <literal>!$=</literal> (non-match).</para>
+ <para>If the given key is not found in the file, the match is done against an empty value.</para>
+
<xi:include href="version-info.xml" xpointer="v249"/>
</listitem>
</varlistentry>
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 9dfa1f8901..1a03fdbe37 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -273,7 +273,9 @@ static int condition_test_osrelease(Condition *c, char **env) {
if (r < 0)
return log_debug_errno(r, "Failed to parse os-release: %m");
- r = version_or_fnmatch_compare(operator, actual_value, word);
+ /* If not found, use "". This means that missing and empty assignments
+ * in the file have the same result. */
+ r = version_or_fnmatch_compare(operator, strempty(actual_value), word);
if (r < 0)
return r;
if (!r)
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
index fc27924621..eb94abe324 100644
--- a/src/test/test-condition.c
+++ b/src/test/test-condition.c
@@ -1095,6 +1095,24 @@ TEST(condition_test_os_release) {
ASSERT_OK_POSITIVE(condition_test(condition, environ));
condition_free(condition);
+ /* Test shell style globs */
+
+ ASSERT_NOT_NULL(condition = condition_new(CONDITION_OS_RELEASE, "ID_LIKE$=*THISHOPEFULLYWONTEXIST*", false, false));
+ ASSERT_OK_ZERO(condition_test(condition, environ));
+ condition_free(condition);
+
+ ASSERT_NOT_NULL(condition = condition_new(CONDITION_OS_RELEASE, "ID_THISHOPEFULLYWONTEXIST$=*rhel*", false, false));
+ ASSERT_OK_ZERO(condition_test(condition, environ));
+ condition_free(condition);
+
+ ASSERT_NOT_NULL(condition = condition_new(CONDITION_OS_RELEASE, "ID_LIKE!$=*THISHOPEFULLYWONTEXIST*", false, false));
+ ASSERT_OK_POSITIVE(condition_test(condition, environ));
+ condition_free(condition);
+
+ ASSERT_NOT_NULL(condition = condition_new(CONDITION_OS_RELEASE, "ID_THISHOPEFULLYWONTEXIST!$=*rhel*", false, false));
+ ASSERT_OK_POSITIVE(condition_test(condition, environ));
+ condition_free(condition);
+
/* load_os_release_pairs() removes quotes, we have to add them back,
* otherwise we get a string: "PRETTY_NAME=Debian GNU/Linux 10 (buster)"
* which is wrong, as the value is not quoted anymore. */

View File

@ -0,0 +1,16 @@
From 876ee10e0eb4bbb0920bdab7817a9f06cc34910f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 13 Feb 2025 18:48:27 +0100
Subject: [PATCH] meson: bump version to 257.3
---
meson.version | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson.version b/meson.version
index f813cadc5d..198eb843d0 100644
--- a/meson.version
+++ b/meson.version
@@ -1 +1 @@
-257.2
+257.3

View File

@ -1,4 +1,4 @@
From 3a8ccc456c8508b70ced7ee02023c7ff4c887999 Mon Sep 17 00:00:00 2001
From 889998fe8c67de3d346eeced121824a117dd5741 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 16 May 2024 14:24:38 +0200
Subject: [PATCH] ci: update workflows to run on source-git setup

View File

@ -1,4 +1,4 @@
From bb8b5a45670f68907549070551866e99999336c2 Mon Sep 17 00:00:00 2001
From edf345c8736485b43cf63310f7ac20f2fcdbe10d Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 16 May 2024 14:36:04 +0200
Subject: [PATCH] ci: setup source-git automation

View File

@ -1,4 +1,4 @@
From 3898fb729b4bae5fbbdfd433f595836dce0d475e Mon Sep 17 00:00:00 2001
From 2805c34051650355bc4e3a299ff23a9965a43af1 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 17 May 2024 13:55:40 +0200
Subject: [PATCH] ci: reconfigure Packit for RHEL 10

View File

@ -1,4 +1,4 @@
From af3c2d2ece5aa4f4c9869c0587be5aba50af6618 Mon Sep 17 00:00:00 2001
From 7178ac9b0ad716e4bdcf09a63c961109cbb02dfc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 9 Jan 2024 11:28:04 +0100
Subject: [PATCH] journal: again create user journals for users with high uids

View File

@ -1,4 +1,4 @@
From 8c1b874414f2f619412adaecdc5a349e1ff634ba Mon Sep 17 00:00:00 2001
From bbd480dc658d26fdd35c9635a08b5380aaccdcad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 18 Jun 2024 20:32:10 +0200
Subject: [PATCH] tmpfiles: make --purge hard to (mis-)use
@ -13,7 +13,7 @@ Related: RHEL-40924
1 file changed, 17 insertions(+)
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index bff05cda6f..9190f604a5 100644
index b699a1e5be..563bf01b45 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -4213,6 +4213,7 @@ static int parse_argv(int argc, char *argv[]) {

View File

@ -1,4 +1,4 @@
From 98b19314de99112cf315a2894562639dcadbe320 Mon Sep 17 00:00:00 2001
From 32882ddc3e34baeeb1fd65c2ed783f10463ccc8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 14 Dec 2022 22:24:53 +0100
Subject: [PATCH] fedora: use system-auth in pam systemd-user

View File

@ -1,4 +1,4 @@
From 8263ecf730ea5ab77caa8467c5c28f24f4a865a3 Mon Sep 17 00:00:00 2001
From fda607614c4854678e1bfe1c27e82996e86a59fb Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 25 Jun 2024 14:00:45 +0200
Subject: [PATCH] net-naming-scheme: start rhel10 naming and include rhel8 and

View File

@ -1,4 +1,4 @@
From 564e24369d0c1ddc8536d577550331e5b8a0d0e0 Mon Sep 17 00:00:00 2001
From d1043fe3a970d6396d4df91aff7714f5e3010830 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Wed, 12 Jun 2024 14:23:30 +0200
Subject: [PATCH] rules: copy 40-redhat.rules from RHEL 9

View File

@ -1,4 +1,4 @@
From b3f9d8462a14cef1455dbdd3d89c01c9674a7d0f Mon Sep 17 00:00:00 2001
From a86ee384de6953b4bfdfd37e083887959d74e9ae Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 10:58:28 +0200
Subject: [PATCH] logind: set RemoveIPC to false by default

View File

@ -1,4 +1,4 @@
From 23091e70f1770b23ad650e3977341b834742d909 Mon Sep 17 00:00:00 2001
From 523094024f847593eb62219b1980cdef44da618d Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 5 Aug 2021 17:11:47 +0200
Subject: [PATCH] tmpfiles: don't create resolv.conf -> stub-resolv.conf

View File

@ -1,4 +1,4 @@
From 3485ef0a5796a5c72876bdf63156952b0ffea714 Mon Sep 17 00:00:00 2001
From 2bcaf0f03302e84da5c2c2eaa3e04cb36b597f72 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Thu, 11 Mar 2021 15:48:23 +0100
Subject: [PATCH] rc-local: order after network-online.target

View File

@ -1,4 +1,4 @@
From 61b82fbe22fbc6ec00b075df25a878052ad2f6f1 Mon Sep 17 00:00:00 2001
From e40b94a3e7402147ce78e7224973fdb0d7386db2 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Thu, 15 Jul 2021 11:15:17 +0200
Subject: [PATCH] random-util: increase random seed size to 1024

View File

@ -1,4 +1,4 @@
From 172467141cad31672cbb23398696cd56814347f7 Mon Sep 17 00:00:00 2001
From b8cf88743e39a156b6e5d6e51805f25a774988cb Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Thu, 2 May 2019 14:11:54 +0200
Subject: [PATCH] journal: don't enable systemd-journald-audit.socket by

View File

@ -1,4 +1,4 @@
From e94102b01e89ce625b4947857d0148165adec1ac Mon Sep 17 00:00:00 2001
From 0fd88aa06db2982be08817d7b9e461141ef9b5b7 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Thu, 5 Aug 2021 15:26:13 +0200
Subject: [PATCH] journald.conf: don't touch current audit settings

View File

@ -1,4 +1,4 @@
From b4c80df8978ea29893edb45cd163dfe5d93cbb27 Mon Sep 17 00:00:00 2001
From 338c2b90dff6f57a197b12f1d0df11f7d842f5bd Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 12 Feb 2019 16:58:16 +0100
Subject: [PATCH] rules: add elevator= kernel command line parameter

View File

@ -1,4 +1,4 @@
From 73538e27e83432aae86db0cf3af31e397a4d7c69 Mon Sep 17 00:00:00 2001
From e81e90faf12aaaa0ea2b7002cced4752226fdc15 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 13:19:39 +0200
Subject: [PATCH] pid1: bump DefaultTasksMax to 80% of the kernel pid.max value

View File

@ -1,4 +1,4 @@
From 75e43ad53bce62ad58112cdfcecbc1917250a731 Mon Sep 17 00:00:00 2001
From 2899425fa34da1b713bcac3568b18a8137cce391 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 21 Sep 2021 15:01:19 +0200
Subject: [PATCH] udev/net-setup-link: change the default MACAddressPolicy to

View File

@ -1,4 +1,4 @@
From 54af0d04d5194cdf9a26cbe4fd7c751f7cdae497 Mon Sep 17 00:00:00 2001
From ddb64e87a3ae6610ea9e2722f7ce8d3e23c715f2 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 22 Feb 2022 13:24:11 +0100
Subject: [PATCH] core: decrease log level of messages about use of

View File

@ -1,4 +1,4 @@
From 17c66b80f5a9bf38a1d4226ab4f54038253b4f93 Mon Sep 17 00:00:00 2001
From ff7a67e1aa5c71c0f40d7f80922a98884394da63 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Mon, 8 Jul 2024 14:44:45 +0200
Subject: [PATCH] taint: remove unmerged-bin

View File

@ -1,4 +1,4 @@
From ed45de428287869a531db8a230874fa31db02178 Mon Sep 17 00:00:00 2001
From fddcb74610ef948369589d470642faa188bc0501 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Mon, 8 Jul 2024 13:13:10 +0200
Subject: [PATCH] presets: remove resolved

View File

@ -1,4 +1,4 @@
From d93bd311a97296483c7d99d572545ce38edcaa65 Mon Sep 17 00:00:00 2001
From 111fdc464b7e470597db4477cedbe54e3c2fb4e8 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 16 Jul 2024 10:08:06 +0200
Subject: [PATCH] ci: run mkosi test only for Fedora and CentOS Stream
@ -11,7 +11,7 @@ Related: RHEL-40924
1 file changed, 2 insertions(+), 34 deletions(-)
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
index d662d65dad..77ccf03717 100644
index 2b00498243..7a764e82a7 100644
--- a/.github/workflows/mkosi.yml
+++ b/.github/workflows/mkosi.yml
@@ -8,7 +8,7 @@ on:

View File

@ -1,4 +1,4 @@
From 9b4672695dd83f8e5a7fb7ff55c477542907a850 Mon Sep 17 00:00:00 2001
From 6b3e22ba2834f02d8513d44c65bf95b186deeb40 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 16 Jul 2024 10:09:23 +0200
Subject: [PATCH] taint: remove unused variable `usr_sbin`

View File

@ -1,4 +1,4 @@
From 77cb42b21dc039c6c12ebeadfb8433fdd6ba805e Mon Sep 17 00:00:00 2001
From d2a27c0be47ed2f47a7f4c52d44fd05f8dc92cf2 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 17 Jul 2024 12:19:03 +0200
Subject: [PATCH] packit: drop the libarchive workaround

View File

@ -1,4 +1,4 @@
From 9e174bfea4f0dc91e3a807d425f090d904beb986 Mon Sep 17 00:00:00 2001
From 733ed7a01bcb70f20d535f914cc11fbd4149a676 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 5 Apr 2024 15:56:58 +0200
Subject: [PATCH] coredump: by default process and store core files up to 1GiB

View File

@ -1,4 +1,4 @@
From f815901eda09adb11b0957b4243b877d9dc971a4 Mon Sep 17 00:00:00 2001
From 0f3fae206bb81459e33fc54cfa3c374fbca9bdf3 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Tue, 15 May 2018 09:24:20 +0200
Subject: [PATCH] Avoid /tmp being mounted as tmpfs without the user's will

View File

@ -1,4 +1,4 @@
From 626d6691fe357a848e9910d6497eb9892e85db58 Mon Sep 17 00:00:00 2001
From 6e50633c85c58faf3f247cdc21ea59edb888b5d0 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Mon, 5 Sep 2016 12:47:09 +0200
Subject: [PATCH] unit: don't add Requires for tmp.mount

View File

@ -1,4 +1,4 @@
From 34f26684f30b23cf59545b8fba68cbee7655abe0 Mon Sep 17 00:00:00 2001
From d3105aa57bfea2eceecc450f226c916e4d42886a Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Tue, 22 Jan 2019 10:28:42 +0100
Subject: [PATCH] units: add [Install] section to tmp.mount

View File

@ -1,4 +1,4 @@
From 882020f9dc77c6212ab33cf2edca2e5488aa488b Mon Sep 17 00:00:00 2001
From 3cc7226bfbfd32be28cef53d49c646d768868930 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 22 Sep 2021 14:38:00 +0200
Subject: [PATCH] units: don't enable tmp.mount statically in local-fs.target

View File

@ -1,4 +1,4 @@
From 761136b13a86095663988d9d1080a9235d5f98f6 Mon Sep 17 00:00:00 2001
From ab60f607bba1153287a20ab27a440bbcbce51207 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 8 Aug 2024 13:12:58 +0200
Subject: [PATCH] netif-naming-scheme: add rhel-9.5 scheme

View File

@ -1,4 +1,4 @@
From 1bf9dcf0b954a29078a0d81b9d1d0b508353f9f4 Mon Sep 17 00:00:00 2001
From 36e9a4f8f81753bf7688cf512b26efecb1cdcc73 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Thu, 22 Aug 2024 13:42:11 +0200
Subject: [PATCH] netif-naming-scheme: rename rhel-10.0 to rhel-10.0.beta

View File

@ -1,4 +1,4 @@
From 30d6ee692d1ec4c914a1dd7718827208121ba623 Mon Sep 17 00:00:00 2001
From 83dcfb7f301b6131fbc69ea5b4b0b773005b69a3 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Thu, 22 Aug 2024 13:47:56 +0200
Subject: [PATCH] net-naming-scheme: disable NAMING_FIRMWARE_NODE_SUN

View File

@ -1,4 +1,4 @@
From 6233005b0c87d963d0e9920869338b48364fbcf2 Mon Sep 17 00:00:00 2001
From afc67dabfe5b51fe9fe02438fd14b4fe8ae6eae8 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Mon, 16 Dec 2024 15:08:50 +0100
Subject: [PATCH] netif-naming-scheme: introduce rhel-10.0 scheme

View File

@ -1,4 +1,4 @@
From 4055f81a331d519e557bc1761811e9291a68bc9a Mon Sep 17 00:00:00 2001
From fa30772d110fbc6fb5f85b13ed99e1f73df6888f Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Mon, 6 Jan 2025 09:09:11 +0100
Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-9.6

View File

@ -1,4 +1,4 @@
From 305b85d3fa788342fb65326fec677f73f739810e Mon Sep 17 00:00:00 2001
From a2208a909829860b7c0488f8f403a8d4301dce88 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 14 Jan 2025 13:26:05 +0100
Subject: [PATCH] ci: use ubuntu 22:04 for deploy of man pages

View File

@ -1,4 +1,4 @@
From 4f52f9d4e24227648967d4f79644fd35a01e1460 Mon Sep 17 00:00:00 2001
From ed7ade53472721fcde5b324660c89164280ad854 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Wed, 15 Jan 2025 15:35:00 +0100
Subject: [PATCH] ci: fix Packit

View File

@ -1,4 +1,4 @@
From d9ea9b2c99571518f1ea3e63fcffd11ecbd3e282 Mon Sep 17 00:00:00 2001
From ee0b5e44b263718912a1cb8081f6b9127d10836a Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 16 Jan 2025 14:42:48 +0100
Subject: [PATCH] ci: drop testing farm test

View File

@ -1,4 +1,4 @@
From bb1289d5263891bddf0568f29d00ac0b95632f9b Mon Sep 17 00:00:00 2001
From f4d3078bd16a814364e653c1e1c2e53af301f0e7 Mon Sep 17 00:00:00 2001
From: Ronan Pigott <ronan@rjp.ie>
Date: Thu, 28 Nov 2024 12:53:32 -0700
Subject: [PATCH] dbus: stash the subscriber list when we disconenct from the

View File

@ -1,4 +1,4 @@
From e0f31135e2c1929844dca4cb2cc8a5c2a2395013 Mon Sep 17 00:00:00 2001
From c6e2ecacb40767e3327813808c60653181e32f78 Mon Sep 17 00:00:00 2001
From: Ronan Pigott <ronan@rjp.ie>
Date: Wed, 11 Dec 2024 12:47:10 -0700
Subject: [PATCH] manager: s/deserialized_subscribed/subscribed_as_strv

View File

@ -1,4 +1,4 @@
From ba46905dd7c33d6e3bcfccfd87cfcc2b4d8b3e52 Mon Sep 17 00:00:00 2001
From d502fb075bb28704030598e58b93e6b274ef9bb1 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Sat, 11 Jan 2025 16:52:05 +0100
Subject: [PATCH] shared/bus-util: move bus_message_read_id128() to

View File

@ -1,4 +1,4 @@
From 2ea8cc2b4d6a266fbd06b727a3fbc74301930f98 Mon Sep 17 00:00:00 2001
From 42319407ae279478143e30d9c2878140b23e969c Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Sat, 11 Jan 2025 17:10:43 +0100
Subject: [PATCH] shared/bus-util: move bus_message_hash_ops to

View File

@ -1,4 +1,4 @@
From c53d1e0bdb9a48fa1b902d85848b1bdd252d1606 Mon Sep 17 00:00:00 2001
From e0c7b4d3ca67508c319fa28ef562dfc0c9982765 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Sat, 11 Jan 2025 18:04:37 +0100
Subject: [PATCH] shared/bus-util: move string set append/get funcs to

View File

@ -1,4 +1,4 @@
From 14c41b05308e6b8911be1d9703fd5aab7b6ee902 Mon Sep 17 00:00:00 2001
From fb16bc1ebc0f6d3747e52be6238ced202ce2bbb5 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 13 Jan 2025 16:35:13 +0100
Subject: [PATCH] shared/serialize: make input params const

View File

@ -1,4 +1,4 @@
From d59a5e3674de4e7973c10cf3122a75259022ee01 Mon Sep 17 00:00:00 2001
From 3e782a6a5e9ab272280e1dbd15a433d15ecf8961 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 13 Jan 2025 16:35:58 +0100
Subject: [PATCH] shared/serialize: introduce serialize_id128()

View File

@ -1,4 +1,4 @@
From 76809cbbc63d43836f16d4d9ba9ccce9582122ee Mon Sep 17 00:00:00 2001
From 24cb20f7d53015dace0a2a7621c7671ab54b1e81 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Sat, 11 Jan 2025 16:26:55 +0100
Subject: [PATCH] bus-util: do not reset the count returned by

View File

@ -1,4 +1,4 @@
From 5486bfede7481152ce3b22ed4286791d53fea3b4 Mon Sep 17 00:00:00 2001
From 66d8a57b8bc706ce0454689562a8f86850ffef5a Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 13 Jan 2025 17:06:21 +0100
Subject: [PATCH] core/manager: use FOREACH_ARRAY at one more place

View File

@ -1,4 +1,4 @@
From 494158868273df13f4bace55a555683b579e2506 Mon Sep 17 00:00:00 2001
From ce620175b0cd9e90461058b04700a204531900a5 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Sat, 11 Jan 2025 18:38:49 +0100
Subject: [PATCH] core/manager: drop duplicate bus track deserialization

View File

@ -1,4 +1,4 @@
From d3c951a20af778bdc065c94ee1d1540730b51e53 Mon Sep 17 00:00:00 2001
From e92f809870c24f13eee4dbf50d0725eab9c8d8ea Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 13 Jan 2025 16:42:34 +0100
Subject: [PATCH] bus-util: introduce bus_get_instance_id()

View File

@ -1,4 +1,4 @@
From 42933b1d439e7197e9fc6bc66a945932105c1a91 Mon Sep 17 00:00:00 2001
From ec9f1ba4bf2b17aa2d10c1196271ce164f4e7c91 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 13 Jan 2025 17:06:35 +0100
Subject: [PATCH] core: serialize API bus id and validate before deserializing

View File

@ -1,4 +1,4 @@
From 18246c12768c55d28281a15dd26cbc777ef1789f Mon Sep 17 00:00:00 2001
From e67e2c131c1ebc4dd820e2580baac9e7bbf4564c Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 13 Jan 2025 17:30:51 +0100
Subject: [PATCH] core/manager: restore bus track deserialization cleanup in

View File

@ -1,4 +1,4 @@
From 02bdc612e1c1d9a484c758384ad6375c1ede5e9f Mon Sep 17 00:00:00 2001
From 7a1733c162f1258a85eef648ed283fffc56ff5c3 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Wed, 15 Jan 2025 15:06:46 +0100
Subject: [PATCH] shared/bus-util: add missing `set.h` include

View File

@ -1,4 +1,4 @@
From 511e1fad5fdac4b078fca5e2347ed5bac582e4b9 Mon Sep 17 00:00:00 2001
From fdefe7c099925a6432f97d860217e6b1b429c279 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 11 Jan 2025 05:27:44 +0900
Subject: [PATCH] udevadm-test: add missing oom check

View File

@ -1,4 +1,4 @@
From 2c0eb3137cb1a886763b4d254bfe1871d4872a3b Mon Sep 17 00:00:00 2001
From 24e7457de660efd3e6906c7fa4708d55d7e45f93 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 11 Jan 2025 03:57:34 +0900
Subject: [PATCH] udev-rules: replace 'type *func()' -> 'type* func()'

View File

@ -1,4 +1,4 @@
From dffdf9bcba4cdd2b27b65f210525fd45fc492904 Mon Sep 17 00:00:00 2001
From 19e40fd51b249a05aae478c733aec343cfc39d54 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 11 Jan 2025 06:07:55 +0900
Subject: [PATCH] udev-rules: do not change maximum log level when running in

View File

@ -1,4 +1,4 @@
From 8b8b65c0da68c96900e694d94571abe4d59fe0da Mon Sep 17 00:00:00 2001
From 17214f471355ed135c503fe64687749b8b0dbe86 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 13 Jan 2025 05:09:15 +0900
Subject: [PATCH] udevadm-test: introduce -v/--verbose option to show verbose

View File

@ -1,4 +1,4 @@
From 0286607e910e964c9eb05b719ce37954dd4d9e2b Mon Sep 17 00:00:00 2001
From cdbd8b3bdec0c3f2ca0258acedc88a0191be176b Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 13 Jan 2025 05:12:40 +0900
Subject: [PATCH] udev-rules: show original token string in log_event_error()

View File

@ -1,4 +1,4 @@
From b1d0e76a3a2bde484cb69e2138cbb8d7b966130e Mon Sep 17 00:00:00 2001
From 5f21939ebe4ca3c23c33383336030b45b72f86b5 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 12 Jan 2025 00:12:52 +0900
Subject: [PATCH] udev-rules: logs result of format substitution

View File

@ -1,4 +1,4 @@
From 42b0f1bcc8126420d0eb657261a300d506f7c093 Mon Sep 17 00:00:00 2001
From a10de9d393f4996bc9735e8cd2f10e1edb5c7284 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 13 Jan 2025 04:03:11 +0900
Subject: [PATCH] udev-rules: add more trace logs for string match

View File

@ -1,4 +1,4 @@
From 93ae29d07b292ee76d0dd82277db54a6ee78eace Mon Sep 17 00:00:00 2001
From b1983b3bf0a5328edfb999c35a923cbc883ed7d4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 15 Jan 2025 22:09:05 +0900
Subject: [PATCH] udev-rules: introduce udev_replace_chars_and_log()

View File

@ -1,4 +1,4 @@
From 224d090a512006eccbd1dfc2e669e7ada8f6ebf4 Mon Sep 17 00:00:00 2001
From c2163f365b7f565358d6f5d9ba78cce087cf4cf9 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 15 Jan 2025 23:43:37 +0900
Subject: [PATCH] udev-rules: ignore whole command result if it is too long and

View File

@ -1,4 +1,4 @@
From 9a88f822a6e604434abc51b9eee4e6087a6e8483 Mon Sep 17 00:00:00 2001
From ee390c8b143a7aebe76dfdb009d7fcfbd931a6ea Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 15 Jan 2025 23:47:05 +0900
Subject: [PATCH] udev-rules: update log messages

View File

@ -1,4 +1,4 @@
From fabb5fa7a0f6a7480688488ae8724ec93167b857 Mon Sep 17 00:00:00 2001
From 2e8cb0b6ed4a75962dcb91fb2737d4c098893618 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 13 Jan 2025 05:18:25 +0900
Subject: [PATCH] udev-rules: add trace logs for GOTO and parent conditions

View File

@ -0,0 +1,318 @@
From d7038446b87ee770bc01a288fac81d86723c9838 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 06:05:38 +0900
Subject: [PATCH] udev: move enums to udev-def.h
No functional change, just refactoring and preparation for later
commits.
(cherry picked from commit 0bdcca5aee60422167065be156990f2a88e0ed95)
Resolves: RHEL-75774
---
src/udev/test-udev-rule-runner.c | 1 +
src/udev/udev-builtin.h | 24 +-------------
src/udev/udev-def.h | 57 ++++++++++++++++++++++++++++++++
src/udev/udev-event.c | 2 ++
src/udev/udev-event.h | 12 ++-----
src/udev/udev-format.c | 1 +
src/udev/udev-manager.c | 1 +
src/udev/udev-manager.h | 3 +-
src/udev/udev-rules.c | 1 +
src/udev/udev-rules.h | 21 +-----------
src/udev/udev-spawn.c | 1 +
src/udev/udev-worker.c | 1 +
src/udev/udevadm-test.c | 1 +
src/udev/udevd.c | 1 +
14 files changed, 74 insertions(+), 53 deletions(-)
create mode 100644 src/udev/udev-def.h
diff --git a/src/udev/test-udev-rule-runner.c b/src/udev/test-udev-rule-runner.c
index db41813511..d123c8ad1b 100644
--- a/src/udev/test-udev-rule-runner.c
+++ b/src/udev/test-udev-rule-runner.c
@@ -25,6 +25,7 @@
#include "string-util.h"
#include "tests.h"
#include "udev-event.h"
+#include "udev-rules.h"
#include "udev-spawn.h"
#include "version.h"
diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h
index b4ddba095a..2433dfa4d4 100644
--- a/src/udev/udev-builtin.h
+++ b/src/udev/udev-builtin.h
@@ -7,31 +7,9 @@
#include "sd-netlink.h"
#include "macro.h"
+#include "udev-def.h"
#include "udev-event.h"
-typedef enum UdevBuiltinCommand {
-#if HAVE_BLKID
- UDEV_BUILTIN_BLKID,
-#endif
- UDEV_BUILTIN_BTRFS,
- UDEV_BUILTIN_HWDB,
- UDEV_BUILTIN_INPUT_ID,
- UDEV_BUILTIN_KEYBOARD,
-#if HAVE_KMOD
- UDEV_BUILTIN_KMOD,
-#endif
- UDEV_BUILTIN_NET_DRIVER,
- UDEV_BUILTIN_NET_ID,
- UDEV_BUILTIN_NET_LINK,
- UDEV_BUILTIN_PATH_ID,
- UDEV_BUILTIN_USB_ID,
-#if HAVE_ACL
- UDEV_BUILTIN_UACCESS,
-#endif
- _UDEV_BUILTIN_MAX,
- _UDEV_BUILTIN_INVALID = -EINVAL,
-} UdevBuiltinCommand;
-
typedef struct UdevBuiltin {
const char *name;
int (*cmd)(UdevEvent *event, int argc, char *argv[]);
diff --git a/src/udev/udev-def.h b/src/udev/udev-def.h
new file mode 100644
index 0000000000..6ff3feacec
--- /dev/null
+++ b/src/udev/udev-def.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
+#include <errno.h>
+
+#define UDEV_NAME_SIZE 512
+#define UDEV_PATH_SIZE 1024
+#define UDEV_LINE_SIZE 16384
+
+typedef enum EventMode {
+ EVENT_UDEV_WORKER,
+ EVENT_UDEVADM_TEST,
+ EVENT_UDEVADM_TEST_BUILTIN,
+ EVENT_TEST_RULE_RUNNER,
+ EVENT_TEST_SPAWN,
+ _EVENT_MODE_MAX,
+ _EVENT_MODE_INVALID = -EINVAL,
+} EventMode;
+
+typedef enum UdevRuleEscapeType {
+ ESCAPE_UNSET,
+ ESCAPE_NONE, /* OPTIONS="string_escape=none" */
+ ESCAPE_REPLACE, /* OPTIONS="string_escape=replace" */
+ _ESCAPE_TYPE_MAX,
+ _ESCAPE_TYPE_INVALID = -EINVAL,
+} UdevRuleEscapeType;
+
+typedef enum ResolveNameTiming {
+ RESOLVE_NAME_NEVER,
+ RESOLVE_NAME_LATE,
+ RESOLVE_NAME_EARLY,
+ _RESOLVE_NAME_TIMING_MAX,
+ _RESOLVE_NAME_TIMING_INVALID = -EINVAL,
+} ResolveNameTiming;
+
+typedef enum UdevBuiltinCommand {
+#if HAVE_BLKID
+ UDEV_BUILTIN_BLKID,
+#endif
+ UDEV_BUILTIN_BTRFS,
+ UDEV_BUILTIN_HWDB,
+ UDEV_BUILTIN_INPUT_ID,
+ UDEV_BUILTIN_KEYBOARD,
+#if HAVE_KMOD
+ UDEV_BUILTIN_KMOD,
+#endif
+ UDEV_BUILTIN_NET_DRIVER,
+ UDEV_BUILTIN_NET_ID,
+ UDEV_BUILTIN_NET_LINK,
+ UDEV_BUILTIN_PATH_ID,
+ UDEV_BUILTIN_USB_ID,
+#if HAVE_ACL
+ UDEV_BUILTIN_UACCESS,
+#endif
+ _UDEV_BUILTIN_MAX,
+ _UDEV_BUILTIN_INVALID = -EINVAL,
+} UdevBuiltinCommand;
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 607071a8cf..7fa86ddd84 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -12,8 +12,10 @@
#include "strv.h"
#include "udev-event.h"
#include "udev-node.h"
+#include "udev-rules.h"
#include "udev-trace.h"
#include "udev-util.h"
+#include "udev-worker.h"
#include "user-util.h"
UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h
index 22388fe904..88a7cfe497 100644
--- a/src/udev/udev-event.h
+++ b/src/udev/udev-event.h
@@ -14,17 +14,11 @@
#include "hashmap.h"
#include "macro.h"
#include "time-util.h"
-#include "udev-rules.h"
-#include "udev-worker.h"
+#include "udev-def.h"
#include "user-util.h"
-typedef enum EventMode {
- EVENT_UDEV_WORKER,
- EVENT_UDEVADM_TEST,
- EVENT_UDEVADM_TEST_BUILTIN,
- EVENT_TEST_RULE_RUNNER,
- EVENT_TEST_SPAWN,
-} EventMode;
+typedef struct UdevRules UdevRules;
+typedef struct UdevWorker UdevWorker;
typedef struct UdevEvent {
UdevWorker *worker;
diff --git a/src/udev/udev-format.c b/src/udev/udev-format.c
index 4bfa6d7a3e..8637d802fc 100644
--- a/src/udev/udev-format.c
+++ b/src/udev/udev-format.c
@@ -8,6 +8,7 @@
#include "udev-event.h"
#include "udev-format.h"
#include "udev-util.h"
+#include "udev-worker.h"
typedef enum {
FORMAT_SUBST_DEVNODE,
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 32bc0db345..5b1135c9e8 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -29,6 +29,7 @@
#include "udev-event.h"
#include "udev-manager.h"
#include "udev-node.h"
+#include "udev-rules.h"
#include "udev-spawn.h"
#include "udev-trace.h"
#include "udev-util.h"
diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h
index 5921d333d1..5519eb33bb 100644
--- a/src/udev/udev-manager.h
+++ b/src/udev/udev-manager.h
@@ -10,9 +10,10 @@
#include "macro.h"
#include "time-util.h"
#include "udev-ctrl.h"
-#include "udev-rules.h"
+#include "udev-def.h"
typedef struct Event Event;
+typedef struct UdevRules UdevRules;
typedef struct Worker Worker;
typedef struct Manager {
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 4f2021b8c4..6345b80cba 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -39,6 +39,7 @@
#include "udev-spawn.h"
#include "udev-trace.h"
#include "udev-util.h"
+#include "udev-worker.h"
#include "user-util.h"
#include "virt.h"
diff --git a/src/udev/udev-rules.h b/src/udev/udev-rules.h
index 61d517d9da..3bd4b04ab3 100644
--- a/src/udev/udev-rules.h
+++ b/src/udev/udev-rules.h
@@ -4,31 +4,12 @@
#include "alloc-util.h"
#include "hashmap.h"
#include "time-util.h"
-
-#define UDEV_NAME_SIZE 512
-#define UDEV_PATH_SIZE 1024
-#define UDEV_LINE_SIZE 16384
+#include "udev-def.h"
typedef struct UdevRuleFile UdevRuleFile;
typedef struct UdevRules UdevRules;
typedef struct UdevEvent UdevEvent;
-typedef enum {
- ESCAPE_UNSET,
- ESCAPE_NONE, /* OPTIONS="string_escape=none" */
- ESCAPE_REPLACE, /* OPTIONS="string_escape=replace" */
- _ESCAPE_TYPE_MAX,
- _ESCAPE_TYPE_INVALID = -EINVAL,
-} UdevRuleEscapeType;
-
-typedef enum ResolveNameTiming {
- RESOLVE_NAME_NEVER,
- RESOLVE_NAME_LATE,
- RESOLVE_NAME_EARLY,
- _RESOLVE_NAME_TIMING_MAX,
- _RESOLVE_NAME_TIMING_INVALID = -EINVAL,
-} ResolveNameTiming;
-
int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos, bool *ret_is_case_insensitive);
int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_checks, UdevRuleFile **ret);
unsigned udev_rule_file_get_issues(UdevRuleFile *rule_file);
diff --git a/src/udev/udev-spawn.c b/src/udev/udev-spawn.c
index d2a422f7e8..b95141cf21 100644
--- a/src/udev/udev-spawn.c
+++ b/src/udev/udev-spawn.c
@@ -14,6 +14,7 @@
#include "udev-event.h"
#include "udev-spawn.h"
#include "udev-trace.h"
+#include "udev-worker.h"
typedef struct Spawn {
sd_device *device;
diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c
index fc1bfd684c..0c57551a37 100644
--- a/src/udev/udev-worker.c
+++ b/src/udev/udev-worker.c
@@ -18,6 +18,7 @@
#include "signal-util.h"
#include "string-util.h"
#include "udev-event.h"
+#include "udev-rules.h"
#include "udev-spawn.h"
#include "udev-trace.h"
#include "udev-util.h"
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 7f3e534d2b..863eab87a5 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -26,6 +26,7 @@
#include "udev-builtin.h"
#include "udev-event.h"
#include "udev-format.h"
+#include "udev-rules.h"
#include "udevadm-util.h"
#include "udevadm.h"
#include "user-util.h"
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index c46fcaa038..bd0cefe8b5 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -24,6 +24,7 @@
#include "signal-util.h"
#include "syslog-util.h"
#include "udev-manager.h"
+#include "udev-rules.h"
#include "udev-util.h"
#include "udevd.h"
#include "version.h"

View File

@ -0,0 +1,194 @@
From 3e4a9e13ab88f6656e2f57ac1450832494726713 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 05:02:53 +0900
Subject: [PATCH] udev: move listen_fds() to udev-manager.c
Also
- drop redundant error message when manager_init() failed,
- close unexpected fds.
No functional change, just refactoring.
(cherry picked from commit a2840b9599f2c764600c3168017918c2cf213ead)
Resolves: RHEL-75774
---
src/udev/udev-manager.c | 57 ++++++++++++++++++++++++++++++++++++++++-
src/udev/udev-manager.h | 2 +-
src/udev/udevd.c | 45 ++------------------------------
3 files changed, 59 insertions(+), 45 deletions(-)
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 5b1135c9e8..6e1935a731 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -1228,15 +1228,69 @@ void manager_adjust_arguments(Manager *manager) {
}
}
-int manager_init(Manager *manager, int fd_ctrl, int fd_uevent) {
+static int listen_fds(int *ret_ctrl, int *ret_netlink) {
+ _cleanup_strv_free_ char **names = NULL;
+ _cleanup_close_ int ctrl_fd = -EBADF, netlink_fd = -EBADF;
+
+ assert(ret_ctrl);
+ assert(ret_netlink);
+
+ int n = sd_listen_fds_with_names(/* unset_environment = */ true, &names);
+ if (n < 0)
+ return n;
+
+ if (strv_length(names) != (size_t) n)
+ return -EIO;
+
+ for (int i = 0; i < n; i++) {
+ int fd = SD_LISTEN_FDS_START + i;
+
+ if (sd_is_socket(fd, AF_UNIX, SOCK_SEQPACKET, -1) > 0) {
+ if (ctrl_fd >= 0) {
+ log_debug("Received multiple seqpacket socket (%s), ignoring.", names[i]);
+ goto unused;
+ }
+
+ ctrl_fd = fd;
+ continue;
+ }
+
+ if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
+ if (netlink_fd >= 0) {
+ log_debug("Received multiple netlink socket (%s), ignoring.", names[i]);
+ goto unused;
+ }
+
+ netlink_fd = fd;
+ continue;
+ }
+
+ log_debug("Received unexpected fd (%s), ignoring.", names[i]);
+
+ unused:
+ close_and_notify_warn(fd, names[i]);
+ }
+
+ *ret_ctrl = TAKE_FD(ctrl_fd);
+ *ret_netlink = TAKE_FD(netlink_fd);
+ return 0;
+}
+
+int manager_init(Manager *manager) {
+ _cleanup_close_ int fd_ctrl = -EBADF, fd_uevent = -EBADF;
_cleanup_free_ char *cgroup = NULL;
int r;
assert(manager);
+ r = listen_fds(&fd_ctrl, &fd_uevent);
+ if (r < 0)
+ return log_error_errno(r, "Failed to listen on fds: %m");
+
r = udev_ctrl_new_from_fd(&manager->ctrl, fd_ctrl);
if (r < 0)
return log_error_errno(r, "Failed to initialize udev control socket: %m");
+ TAKE_FD(fd_ctrl);
r = udev_ctrl_enable_receiving(manager->ctrl);
if (r < 0)
@@ -1245,6 +1299,7 @@ int manager_init(Manager *manager, int fd_ctrl, int fd_uevent) {
r = device_monitor_new_full(&manager->monitor, MONITOR_GROUP_KERNEL, fd_uevent);
if (r < 0)
return log_error_errno(r, "Failed to initialize device monitor: %m");
+ TAKE_FD(fd_uevent);
(void) sd_device_monitor_set_description(manager->monitor, "manager");
diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h
index 5519eb33bb..7c20e29594 100644
--- a/src/udev/udev-manager.h
+++ b/src/udev/udev-manager.h
@@ -54,7 +54,7 @@ Manager* manager_free(Manager *manager);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
void manager_adjust_arguments(Manager *manager);
-int manager_init(Manager *manager, int fd_ctrl, int fd_uevent);
+int manager_init(Manager *manager);
int manager_main(Manager *manager);
bool devpath_conflict(const char *a, const char *b);
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index bd0cefe8b5..ef1c07a2ca 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -8,8 +8,6 @@
#include <getopt.h>
#include <unistd.h>
-#include "sd-daemon.h"
-
#include "conf-parser.h"
#include "env-file.h"
#include "errno-util.h"
@@ -32,40 +30,6 @@
static bool arg_debug = false;
static int arg_daemonize = false;
-static int listen_fds(int *ret_ctrl, int *ret_netlink) {
- int ctrl_fd = -EBADF, netlink_fd = -EBADF;
-
- assert(ret_ctrl);
- assert(ret_netlink);
-
- int n = sd_listen_fds(true);
- if (n < 0)
- return n;
-
- for (int fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) {
- if (sd_is_socket(fd, AF_UNIX, SOCK_SEQPACKET, -1) > 0) {
- if (ctrl_fd >= 0)
- return -EINVAL;
- ctrl_fd = fd;
- continue;
- }
-
- if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
- if (netlink_fd >= 0)
- return -EINVAL;
- netlink_fd = fd;
- continue;
- }
-
- return -EINVAL;
- }
-
- *ret_ctrl = ctrl_fd;
- *ret_netlink = netlink_fd;
-
- return 0;
-}
-
static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming);
static int manager_parse_udev_config(Manager *manager) {
@@ -287,7 +251,6 @@ static int parse_argv(int argc, char *argv[], Manager *manager) {
int run_udevd(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *manager = NULL;
- int fd_ctrl = -EBADF, fd_uevent = -EBADF;
int r;
log_setup();
@@ -331,13 +294,9 @@ int run_udevd(int argc, char *argv[]) {
if (r < 0 && r != -EEXIST)
return log_error_errno(r, "Failed to create /run/udev: %m");
- r = listen_fds(&fd_ctrl, &fd_uevent);
- if (r < 0)
- return log_error_errno(r, "Failed to listen on fds: %m");
-
- r = manager_init(manager, fd_ctrl, fd_uevent);
+ r = manager_init(manager);
if (r < 0)
- return log_error_errno(r, "Failed to create manager: %m");
+ return r;
if (arg_daemonize) {
pid_t pid;

View File

@ -0,0 +1,491 @@
From 54b98a2405e68ee9cf3d8af27b8b315659a2c656 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 5 Dec 2024 00:44:14 +0900
Subject: [PATCH] udev: several coding style fixes
- use 'type* func()' rather than 'type *func()',
- merge variable declarations,
- etc.
(cherry picked from commit 7ab25935f3ce677483cb9044126ac7b4b3680d8d)
Resolves: RHEL-75774
---
src/udev/dmi_memory_id/dmi_memory_id.c | 2 +-
src/udev/net/link-config.c | 2 +-
src/udev/net/link-config.h | 2 +-
src/udev/udev-builtin-hwdb.c | 7 +--
src/udev/udev-builtin-input_id.c | 79 +++++++++++++-------------
src/udev/udev-builtin-keyboard.c | 6 +-
src/udev/udev-builtin-path_id.c | 36 ++++++------
src/udev/udev-builtin-usb_id.c | 30 +++-------
src/udev/udev-event.c | 4 +-
src/udev/udev-event.h | 4 +-
src/udev/udev-format.c | 2 +-
src/udev/udev-rules.c | 2 +-
src/udev/udev-rules.h | 2 +-
13 files changed, 75 insertions(+), 103 deletions(-)
diff --git a/src/udev/dmi_memory_id/dmi_memory_id.c b/src/udev/dmi_memory_id/dmi_memory_id.c
index 71cec5fc47..e62222a307 100644
--- a/src/udev/dmi_memory_id/dmi_memory_id.c
+++ b/src/udev/dmi_memory_id/dmi_memory_id.c
@@ -89,7 +89,7 @@ static bool verify_checksum(const uint8_t *buf, size_t len) {
* Type-independent Stuff
*/
-static const char *dmi_string(const struct dmi_header *dm, uint8_t s) {
+static const char* dmi_string(const struct dmi_header *dm, uint8_t s) {
const char *bp = (const char *) dm->data;
if (s == 0)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 7787f66981..c2bec61347 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -372,7 +372,7 @@ bool link_config_should_reload(LinkConfigContext *ctx) {
return !stats_by_path_equal(ctx->stats_by_path, stats_by_path);
}
-Link *link_free(Link *link) {
+Link* link_free(Link *link) {
if (!link)
return NULL;
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 3152bec72a..5aaa7c51a0 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -103,7 +103,7 @@ int link_config_load(LinkConfigContext *ctx);
bool link_config_should_reload(LinkConfigContext *ctx);
int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, sd_device *device_db_clone, Link **ret);
-Link *link_free(Link *link);
+Link* link_free(Link *link);
DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
int link_get_config(LinkConfigContext *ctx, Link *link);
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index e33a7febd6..fbee04b4a8 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -50,7 +50,7 @@ int udev_builtin_hwdb_lookup(
return n;
}
-static const char *modalias_usb(sd_device *dev, char *s, size_t size) {
+static const char* modalias_usb(sd_device *dev, char *s, size_t size) {
const char *v, *p, *n = NULL;
uint16_t vn, pn;
@@ -130,10 +130,7 @@ static int builtin_hwdb(UdevEvent *event, int argc, char *argv[]) {
{ "lookup-prefix", required_argument, NULL, 'p' },
{}
};
- const char *filter = NULL;
- const char *device = NULL;
- const char *subsystem = NULL;
- const char *prefix = NULL;
+ const char *filter = NULL, *device = NULL, *subsystem = NULL, *prefix = NULL;
_cleanup_(sd_device_unrefp) sd_device *srcdev = NULL;
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
int r;
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 876af195e2..c204d656f0 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -75,15 +75,14 @@ static void extract_info(sd_device *dev, EventMode mode) {
*/
static void get_cap_mask(
sd_device *pdev,
- const char* attr,
+ const char *attr,
unsigned long *bitmask,
size_t bitmask_size,
EventMode mode) {
const char *v;
- char text[4096];
+ char text[4096], *word;
unsigned i;
- char* word;
unsigned long val;
int r;
@@ -151,37 +150,36 @@ static struct input_id get_input_id(sd_device *dev) {
static bool test_pointers(
sd_device *dev,
const struct input_id *id,
- const unsigned long* bitmask_ev,
- const unsigned long* bitmask_abs,
- const unsigned long* bitmask_key,
- const unsigned long* bitmask_rel,
- const unsigned long* bitmask_props,
+ const unsigned long *bitmask_ev,
+ const unsigned long *bitmask_abs,
+ const unsigned long *bitmask_key,
+ const unsigned long *bitmask_rel,
+ const unsigned long *bitmask_props,
EventMode mode) {
- bool has_abs_coordinates = false;
- bool has_rel_coordinates = false;
- bool has_mt_coordinates = false;
- size_t num_joystick_axes = 0;
- size_t num_joystick_buttons = 0;
- bool has_pad_buttons = false;
- bool is_direct = false;
- bool has_touch = false;
- bool has_3d_coordinates = false;
- bool has_keys = false;
- bool has_stylus = false;
- bool has_pen = false;
- bool finger_but_no_pen = false;
- bool has_mouse_button = false;
- bool is_mouse = false;
- bool is_abs_mouse = false;
- bool is_touchpad = false;
- bool is_touchscreen = false;
- bool is_tablet = false;
- bool is_tablet_pad = false;
- bool is_joystick = false;
- bool is_accelerometer = false;
- bool is_pointing_stick = false;
- bool has_wheel = false;
+ size_t num_joystick_axes = 0, num_joystick_buttons = 0;
+ bool has_abs_coordinates = false,
+ has_rel_coordinates = false,
+ has_mt_coordinates = false,
+ has_pad_buttons = false,
+ is_direct = false,
+ has_touch = false,
+ has_3d_coordinates = false,
+ has_keys = false,
+ has_stylus = false,
+ has_pen = false,
+ finger_but_no_pen = false,
+ has_mouse_button = false,
+ is_mouse = false,
+ is_abs_mouse = false,
+ is_touchpad = false,
+ is_touchscreen = false,
+ is_tablet = false,
+ is_tablet_pad = false,
+ is_joystick = false,
+ is_accelerometer = false,
+ is_pointing_stick = false,
+ has_wheel = false;
has_keys = test_bit(EV_KEY, bitmask_ev);
has_abs_coordinates = test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs);
@@ -335,8 +333,8 @@ static bool test_pointers(
/* key like devices */
static bool test_key(
sd_device *dev,
- const unsigned long* bitmask_ev,
- const unsigned long* bitmask_key,
+ const unsigned long *bitmask_ev,
+ const unsigned long *bitmask_key,
EventMode mode) {
bool found = false;
@@ -378,14 +376,13 @@ static bool test_key(
static int builtin_input_id(UdevEvent *event, int argc, char *argv[]) {
sd_device *pdev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
- unsigned long bitmask_ev[NBITS(EV_MAX)];
- unsigned long bitmask_abs[NBITS(ABS_MAX)];
- unsigned long bitmask_key[NBITS(KEY_MAX)];
- unsigned long bitmask_rel[NBITS(REL_MAX)];
- unsigned long bitmask_props[NBITS(INPUT_PROP_MAX)];
+ unsigned long bitmask_ev[NBITS(EV_MAX)],
+ bitmask_abs[NBITS(ABS_MAX)],
+ bitmask_key[NBITS(KEY_MAX)],
+ bitmask_rel[NBITS(REL_MAX)],
+ bitmask_props[NBITS(INPUT_PROP_MAX)];
const char *sysname;
- bool is_pointer;
- bool is_key;
+ bool is_pointer, is_key;
/* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index e1e6de0426..1595a8f031 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -20,8 +20,7 @@ static const struct key_name *keyboard_lookup_key(const char *str, GPERF_LEN_TYP
static int install_force_release(sd_device *dev, const unsigned *release, unsigned release_count) {
sd_device *atkbd;
const char *cur;
- char codes[4096];
- char *s;
+ char *s, codes[4096];
size_t l;
unsigned i;
int r;
@@ -161,8 +160,7 @@ static int set_trackpoint_sensitivity(sd_device *dev, const char *value) {
static int builtin_keyboard(UdevEvent *event, int argc, char *argv[]) {
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
- unsigned release[1024];
- unsigned release_count = 0;
+ unsigned release[1024], release_count = 0;
_cleanup_close_ int fd = -EBADF;
const char *node;
int has_abs = -1, r;
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index 77abff004e..8ba5f2e358 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -82,7 +82,7 @@ static int format_lun_number(sd_device *dev, char **path) {
return 0;
}
-static sd_device *skip_subsystem(sd_device *dev, const char *subsys) {
+static sd_device* skip_subsystem(sd_device *dev, const char *subsys) {
sd_device *parent;
assert(dev);
@@ -107,7 +107,7 @@ static sd_device *skip_subsystem(sd_device *dev, const char *subsys) {
return dev;
}
-static sd_device *handle_scsi_fibre_channel(sd_device *parent, char **path) {
+static sd_device* handle_scsi_fibre_channel(sd_device *parent, char **path) {
sd_device *targetdev;
_cleanup_(sd_device_unrefp) sd_device *fcdev = NULL;
const char *port, *sysname;
@@ -130,7 +130,7 @@ static sd_device *handle_scsi_fibre_channel(sd_device *parent, char **path) {
return parent;
}
-static sd_device *handle_scsi_sas_wide_port(sd_device *parent, char **path) {
+static sd_device* handle_scsi_sas_wide_port(sd_device *parent, char **path) {
sd_device *targetdev, *target_parent;
_cleanup_(sd_device_unrefp) sd_device *sasdev = NULL;
const char *sas_address, *sysname;
@@ -155,12 +155,10 @@ static sd_device *handle_scsi_sas_wide_port(sd_device *parent, char **path) {
return parent;
}
-static sd_device *handle_scsi_sas(sd_device *parent, char **path) {
+static sd_device* handle_scsi_sas(sd_device *parent, char **path) {
sd_device *targetdev, *target_parent, *port, *expander;
_cleanup_(sd_device_unrefp) sd_device *target_sasdev = NULL, *expander_sasdev = NULL, *port_sasdev = NULL;
- const char *sas_address = NULL;
- const char *phy_id;
- const char *sysname;
+ const char *sas_address = NULL, *phy_id, *sysname;
unsigned num_phys;
_cleanup_free_ char *lun = NULL;
@@ -216,12 +214,11 @@ static sd_device *handle_scsi_sas(sd_device *parent, char **path) {
return parent;
}
-static sd_device *handle_scsi_iscsi(sd_device *parent, char **path) {
+static sd_device* handle_scsi_iscsi(sd_device *parent, char **path) {
sd_device *transportdev;
_cleanup_(sd_device_unrefp) sd_device *sessiondev = NULL, *conndev = NULL;
- const char *target, *connname, *addr, *port;
+ const char *target, *connname, *addr, *port, *sysname, *sysnum;
_cleanup_free_ char *lun = NULL;
- const char *sysname, *sysnum;
assert(parent);
assert(path);
@@ -260,7 +257,7 @@ static sd_device *handle_scsi_iscsi(sd_device *parent, char **path) {
return parent;
}
-static sd_device *handle_scsi_ata(sd_device *parent, char **path, char **compat_path) {
+static sd_device* handle_scsi_ata(sd_device *parent, char **path, char **compat_path) {
sd_device *targetdev, *target_parent;
_cleanup_(sd_device_unrefp) sd_device *atadev = NULL;
const char *port_no, *sysname, *name;
@@ -302,7 +299,7 @@ static sd_device *handle_scsi_ata(sd_device *parent, char **path, char **compat_
return parent;
}
-static sd_device *handle_scsi_default(sd_device *parent, char **path) {
+static sd_device* handle_scsi_default(sd_device *parent, char **path) {
sd_device *hostdev;
int host, bus, target, lun;
const char *name, *base, *pos;
@@ -376,9 +373,8 @@ static sd_device *handle_scsi_default(sd_device *parent, char **path) {
return hostdev;
}
-static sd_device *handle_scsi_hyperv(sd_device *parent, char **path, size_t guid_str_len) {
- sd_device *hostdev;
- sd_device *vmbusdev;
+static sd_device* handle_scsi_hyperv(sd_device *parent, char **path, size_t guid_str_len) {
+ sd_device *hostdev, *vmbusdev;
const char *guid_str;
_cleanup_free_ char *lun = NULL;
char guid[39];
@@ -412,7 +408,7 @@ static sd_device *handle_scsi_hyperv(sd_device *parent, char **path, size_t guid
return parent;
}
-static sd_device *handle_scsi(sd_device *parent, char **path, char **compat_path, bool *supported_parent) {
+static sd_device* handle_scsi(sd_device *parent, char **path, char **compat_path, bool *supported_parent) {
const char *id, *name;
if (!device_is_devtype(parent, "scsi_device"))
@@ -455,7 +451,7 @@ static sd_device *handle_scsi(sd_device *parent, char **path, char **compat_path
return handle_scsi_default(parent, path);
}
-static sd_device *handle_cciss(sd_device *parent, char **path) {
+static sd_device* handle_cciss(sd_device *parent, char **path) {
const char *str;
unsigned controller, disk;
@@ -526,7 +522,7 @@ static int get_usb_revision(sd_device *dev) {
}
}
-static sd_device *handle_usb(sd_device *parent, char **path) {
+static sd_device* handle_usb(sd_device *parent, char **path) {
const char *str, *port;
int r;
@@ -564,7 +560,7 @@ static sd_device *handle_usb(sd_device *parent, char **path) {
return parent;
}
-static sd_device *handle_bcma(sd_device *parent, char **path) {
+static sd_device* handle_bcma(sd_device *parent, char **path) {
const char *sysname;
unsigned core;
@@ -578,7 +574,7 @@ static sd_device *handle_bcma(sd_device *parent, char **path) {
}
/* Handle devices of AP bus in System z platform. */
-static sd_device *handle_ap(sd_device *parent, char **path) {
+static sd_device* handle_ap(sd_device *parent, char **path) {
const char *type, *func;
assert(parent);
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index 2413f9ce9e..9abdec3591 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -225,31 +225,15 @@ static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) {
* is concatenated with the identification with an underscore '_'.
*/
static int builtin_usb_id(UdevEvent *event, int argc, char *argv[]) {
- sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
- char vendor_str[64] = "";
- char vendor_str_enc[256];
- const char *vendor_id;
- char model_str[64] = "";
- char model_str_enc[256];
- const char *product_id;
- char serial_str[UDEV_NAME_SIZE] = "";
- char packed_if_str[UDEV_NAME_SIZE] = "";
- char revision_str[64] = "";
- char type_str[64] = "";
- char instance_str[64] = "";
- const char *ifnum = NULL;
- const char *driver = NULL;
- char serial[256];
-
- sd_device *dev_interface, *dev_usb;
- const char *if_class, *if_subclass;
+ sd_device *dev_interface, *dev_usb, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
+ const char *syspath, *sysname, *interface_syspath, *vendor_id, *product_id,
+ *ifnum = NULL, *driver = NULL, *if_class, *if_subclass;
+ char *s, model_str[64] = "", model_str_enc[256], serial_str[UDEV_NAME_SIZE] = "",
+ packed_if_str[UDEV_NAME_SIZE] = "", revision_str[64] = "", type_str[64] = "",
+ instance_str[64] = "", serial[256], vendor_str[64] = "", vendor_str_enc[256];
unsigned if_class_num;
- int protocol = 0;
+ int r, protocol = 0;
size_t l;
- char *s;
-
- const char *syspath, *sysname, *interface_syspath;
- int r;
r = sd_device_get_syspath(dev, &syspath);
if (r < 0)
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 7fa86ddd84..9141a9d2a7 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -18,7 +18,7 @@
#include "udev-worker.h"
#include "user-util.h"
-UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
+UdevEvent* udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
int log_level = worker ? worker->log_level : log_get_max_level();
UdevEvent *event;
@@ -44,7 +44,7 @@ UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
return event;
}
-UdevEvent *udev_event_free(UdevEvent *event) {
+UdevEvent* udev_event_free(UdevEvent *event) {
if (!event)
return NULL;
diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h
index 88a7cfe497..186cfa541f 100644
--- a/src/udev/udev-event.h
+++ b/src/udev/udev-event.h
@@ -53,8 +53,8 @@ typedef struct UdevEvent {
EventMode event_mode;
} UdevEvent;
-UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode);
-UdevEvent *udev_event_free(UdevEvent *event);
+UdevEvent* udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode);
+UdevEvent* udev_event_free(UdevEvent *event);
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free);
int udev_event_execute_rules(UdevEvent *event, UdevRules *rules);
diff --git a/src/udev/udev-format.c b/src/udev/udev-format.c
index 8637d802fc..c09ea44d91 100644
--- a/src/udev/udev-format.c
+++ b/src/udev/udev-format.c
@@ -58,7 +58,7 @@ static const struct subst_map_entry map[] = {
{ .name = "sys", .fmt = 'S', .type = FORMAT_SUBST_SYS },
};
-static const char *format_type_to_string(FormatSubstitutionType t) {
+static const char* format_type_to_string(FormatSubstitutionType t) {
FOREACH_ELEMENT(entry, map)
if (entry->type == t)
return entry->name;
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 6345b80cba..041c642aa9 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -457,7 +457,7 @@ static UdevRuleFile* udev_rule_file_free(UdevRuleFile *rule_file) {
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevRuleFile*, udev_rule_file_free);
-UdevRules *udev_rules_free(UdevRules *rules) {
+UdevRules* udev_rules_free(UdevRules *rules) {
if (!rules)
return NULL;
diff --git a/src/udev/udev-rules.h b/src/udev/udev-rules.h
index 3bd4b04ab3..67d7e5b178 100644
--- a/src/udev/udev-rules.h
+++ b/src/udev/udev-rules.h
@@ -15,7 +15,7 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_che
unsigned udev_rule_file_get_issues(UdevRuleFile *rule_file);
UdevRules* udev_rules_new(ResolveNameTiming resolve_name_timing);
int udev_rules_load(UdevRules **ret_rules, ResolveNameTiming resolve_name_timing);
-UdevRules *udev_rules_free(UdevRules *rules);
+UdevRules* udev_rules_free(UdevRules *rules);
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevRules*, udev_rules_free);
#define udev_rules_free_and_replace(a, b) free_and_replace_full(a, b, udev_rules_free)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
From 9702ed206cb97d6b437965abaf139a2628055e75 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 5 Dec 2024 03:12:03 +0900
Subject: [PATCH] udev: introduce reference counter for UdevEvent
No functional change, preparation for later commits.
(cherry picked from commit 4a90166488a4018effbf471df5e057f901f0b52d)
Resolves: RHEL-75774
---
src/udev/test-udev-rule-runner.c | 2 +-
src/udev/test-udev-spawn.c | 2 +-
src/udev/udev-event.c | 5 ++++-
src/udev/udev-event.h | 8 +++++---
src/udev/udev-worker.c | 2 +-
src/udev/udevadm-test-builtin.c | 2 +-
src/udev/udevadm-test.c | 2 +-
7 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/udev/test-udev-rule-runner.c b/src/udev/test-udev-rule-runner.c
index d123c8ad1b..9a04abf590 100644
--- a/src/udev/test-udev-rule-runner.c
+++ b/src/udev/test-udev-rule-runner.c
@@ -89,7 +89,7 @@ static int fake_filesystems(void) {
static int run(int argc, char *argv[]) {
_cleanup_(udev_rules_freep) UdevRules *rules = NULL;
- _cleanup_(udev_event_freep) UdevEvent *event = NULL;
+ _cleanup_(udev_event_unrefp) UdevEvent *event = NULL;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
const char *devpath, *devname, *action;
int r;
diff --git a/src/udev/test-udev-spawn.c b/src/udev/test-udev-spawn.c
index a6079e3c61..a2b9aad3a7 100644
--- a/src/udev/test-udev-spawn.c
+++ b/src/udev/test-udev-spawn.c
@@ -12,7 +12,7 @@
static void test_event_spawn_core(bool with_pidfd, const char *cmd, char *result_buf, size_t buf_size) {
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
- _cleanup_(udev_event_freep) UdevEvent *event = NULL;
+ _cleanup_(udev_event_unrefp) UdevEvent *event = NULL;
assert_se(setenv("SYSTEMD_PIDFD", yes_no(with_pidfd), 1) >= 0);
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 9141a9d2a7..6a7c34b162 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -29,6 +29,7 @@ UdevEvent* udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
return NULL;
*event = (UdevEvent) {
+ .n_ref = 1,
.worker = worker,
.rtnl = worker ? sd_netlink_ref(worker->rtnl) : NULL,
.dev = sd_device_ref(dev),
@@ -44,7 +45,7 @@ UdevEvent* udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
return event;
}
-UdevEvent* udev_event_free(UdevEvent *event) {
+static UdevEvent* udev_event_free(UdevEvent *event) {
if (!event)
return NULL;
@@ -60,6 +61,8 @@ UdevEvent* udev_event_free(UdevEvent *event) {
return mfree(event);
}
+DEFINE_TRIVIAL_REF_UNREF_FUNC(UdevEvent, udev_event, udev_event_free);
+
static int device_rename(sd_device *device, const char *name) {
_cleanup_free_ char *new_syspath = NULL;
const char *s;
diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h
index 186cfa541f..11e2c700e6 100644
--- a/src/udev/udev-event.h
+++ b/src/udev/udev-event.h
@@ -21,9 +21,10 @@ typedef struct UdevRules UdevRules;
typedef struct UdevWorker UdevWorker;
typedef struct UdevEvent {
+ unsigned n_ref;
+
UdevWorker *worker;
sd_netlink *rtnl;
-
sd_device *dev;
sd_device *dev_parent;
sd_device *dev_db_clone;
@@ -54,8 +55,9 @@ typedef struct UdevEvent {
} UdevEvent;
UdevEvent* udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode);
-UdevEvent* udev_event_free(UdevEvent *event);
-DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free);
+UdevEvent* udev_event_ref(UdevEvent *event);
+UdevEvent* udev_event_unref(UdevEvent *event);
+DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_unref);
int udev_event_execute_rules(UdevEvent *event, UdevRules *rules);
diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c
index 0c57551a37..44287e4774 100644
--- a/src/udev/udev-worker.c
+++ b/src/udev/udev-worker.c
@@ -171,7 +171,7 @@ static int worker_mark_block_device_read_only(sd_device *dev) {
}
static int worker_process_device(UdevWorker *worker, sd_device *dev) {
- _cleanup_(udev_event_freep) UdevEvent *udev_event = NULL;
+ _cleanup_(udev_event_unrefp) UdevEvent *udev_event = NULL;
_cleanup_close_ int fd_lock = -EBADF;
int r;
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
index 5815f2cc78..382897efd4 100644
--- a/src/udev/udevadm-test-builtin.c
+++ b/src/udev/udevadm-test-builtin.c
@@ -74,7 +74,7 @@ static int parse_argv(int argc, char *argv[]) {
}
int builtin_main(int argc, char *argv[], void *userdata) {
- _cleanup_(udev_event_freep) UdevEvent *event = NULL;
+ _cleanup_(udev_event_unrefp) UdevEvent *event = NULL;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
UdevBuiltinCommand cmd;
int r;
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 863eab87a5..09d1150dd7 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -99,7 +99,7 @@ static int parse_argv(int argc, char *argv[]) {
int test_main(int argc, char *argv[], void *userdata) {
_cleanup_(udev_rules_freep) UdevRules *rules = NULL;
- _cleanup_(udev_event_freep) UdevEvent *event = NULL;
+ _cleanup_(udev_event_unrefp) UdevEvent *event = NULL;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
sigset_t mask, sigmask_orig;
int r;

View File

@ -0,0 +1,447 @@
From f4fb3eb1a5c51cf8828720c7c4ee7e03e6eb9726 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 5 Dec 2024 03:12:42 +0900
Subject: [PATCH] udev/net: make Link object take reference to UdevEvent
No functional change, just refactoring.
(cherry picked from commit ab70e42999d9587aac025d2d15da3490d401cb1a)
Resolves: RHEL-75774
---
src/udev/net/link-config.c | 132 ++++++++++---------------
src/udev/net/link-config.h | 20 ++--
src/udev/udev-builtin-net_setup_link.c | 6 +-
3 files changed, 66 insertions(+), 92 deletions(-)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 55eeb9de81..7d4e334503 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -376,21 +376,18 @@ Link* link_free(Link *link) {
if (!link)
return NULL;
- sd_device_unref(link->device);
- sd_device_unref(link->device_db_clone);
+ udev_event_unref(link->event);
free(link->kind);
- strv_free(link->altnames);
return mfree(link);
}
-int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, sd_device *device_db_clone, Link **ret) {
+int link_new(LinkConfigContext *ctx, UdevEvent *event, Link **ret) {
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
_cleanup_(link_freep) Link *link = NULL;
int r;
assert(ctx);
- assert(rtnl);
- assert(device);
- assert(device_db_clone);
+ assert(event);
assert(ret);
link = new(Link, 1);
@@ -398,31 +395,30 @@ int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, sd_de
return -ENOMEM;
*link = (Link) {
- .device = sd_device_ref(device),
- .device_db_clone = sd_device_ref(device_db_clone),
+ .event = udev_event_ref(event),
};
- r = sd_device_get_sysname(device, &link->ifname);
+ r = sd_device_get_sysname(dev, &link->ifname);
if (r < 0)
return r;
- r = sd_device_get_ifindex(device, &link->ifindex);
+ r = sd_device_get_ifindex(dev, &link->ifindex);
if (r < 0)
return r;
- r = sd_device_get_action(device, &link->action);
+ r = sd_device_get_action(dev, &link->action);
if (r < 0)
return r;
- r = device_unsigned_attribute(device, "name_assign_type", &link->name_assign_type);
+ r = device_unsigned_attribute(dev, "name_assign_type", &link->name_assign_type);
if (r < 0)
log_link_debug_errno(link, r, "Failed to get \"name_assign_type\" attribute, ignoring: %m");
- r = device_unsigned_attribute(device, "addr_assign_type", &link->addr_assign_type);
+ r = device_unsigned_attribute(dev, "addr_assign_type", &link->addr_assign_type);
if (r < 0)
log_link_debug_errno(link, r, "Failed to get \"addr_assign_type\" attribute, ignoring: %m");
- r = rtnl_get_link_info(rtnl, link->ifindex, &link->iftype, &link->flags,
+ r = rtnl_get_link_info(&event->rtnl, link->ifindex, &link->iftype, &link->flags,
&link->kind, &link->hw_addr, &link->permanent_hw_addr);
if (r < 0)
return r;
@@ -433,7 +429,7 @@ int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, sd_de
log_link_debug_errno(link, r, "Failed to get permanent hardware address, ignoring: %m");
}
- r = sd_device_get_property_value(link->device, "ID_NET_DRIVER", &link->driver);
+ r = sd_device_get_property_value(dev, "ID_NET_DRIVER", &link->driver);
if (r < 0 && r != -ENOENT)
log_link_debug_errno(link, r, "Failed to get driver, ignoring: %m");
@@ -454,7 +450,7 @@ int link_get_config(LinkConfigContext *ctx, Link *link) {
LIST_FOREACH(configs, config, ctx->configs) {
r = net_match_config(
&config->match,
- link->device,
+ link->event->dev,
&link->hw_addr,
&link->permanent_hw_addr,
link->driver,
@@ -483,23 +479,19 @@ int link_get_config(LinkConfigContext *ctx, Link *link) {
return -ENOENT;
}
-static int link_apply_ethtool_settings(Link *link, int *ethtool_fd, EventMode mode) {
- LinkConfig *config;
- const char *name;
+static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) {
+ LinkConfig *config = ASSERT_PTR(ASSERT_PTR(link)->config);
+ const char *name = ASSERT_PTR(link->ifname);
int r;
- assert(link);
- assert(link->config);
+ assert(link->event);
assert(ethtool_fd);
- if (mode != EVENT_UDEV_WORKER) {
+ if (link->event->event_mode != EVENT_UDEV_WORKER) {
log_link_debug(link, "Running in test mode, skipping application of ethtool settings.");
return 0;
}
- config = link->config;
- name = link->ifname;
-
r = ethtool_set_glinksettings(ethtool_fd, name,
config->autonegotiation, config->advertise,
config->speed, config->duplex, config->port, config->mdi);
@@ -589,7 +581,8 @@ static int link_generate_new_hw_addr(Link *link, struct hw_addr_data *ret) {
assert(link);
assert(link->config);
- assert(link->device);
+ assert(link->event);
+ assert(link->event->dev);
assert(ret);
if (link->hw_addr.length == 0)
@@ -655,7 +648,7 @@ static int link_generate_new_hw_addr(Link *link, struct hw_addr_data *ret) {
else {
uint64_t result;
- r = net_get_unique_predictable_data(link->device,
+ r = net_get_unique_predictable_data(link->event->dev,
naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS),
&result);
if (r < 0)
@@ -689,25 +682,21 @@ finalize:
return 0;
}
-static int link_apply_rtnl_settings(Link *link, sd_netlink **rtnl, EventMode mode) {
+static int link_apply_rtnl_settings(Link *link) {
struct hw_addr_data hw_addr = {};
- LinkConfig *config;
+ LinkConfig *config = ASSERT_PTR(ASSERT_PTR(link)->config);
int r;
- assert(link);
- assert(link->config);
- assert(rtnl);
+ assert(link->event);
- if (mode != EVENT_UDEV_WORKER) {
+ if (link->event->event_mode != EVENT_UDEV_WORKER) {
log_link_debug(link, "Running in test mode, skipping application of rtnl settings.");
return 0;
}
- config = link->config;
-
(void) link_generate_new_hw_addr(link, &hw_addr);
- r = rtnl_set_link_properties(rtnl, link->ifindex, config->alias, &hw_addr,
+ r = rtnl_set_link_properties(&link->event->rtnl, link->ifindex, config->alias, &hw_addr,
config->txqueues, config->rxqueues, config->txqueuelen,
config->mtu, config->gso_max_size, config->gso_max_segments);
if (r < 0)
@@ -741,15 +730,8 @@ static bool enable_name_policy(void) {
}
static int link_generate_new_name(Link *link) {
- LinkConfig *config;
- sd_device *device;
-
- assert(link);
- assert(link->config);
- assert(link->device);
-
- config = link->config;
- device = link->device;
+ LinkConfig *config = ASSERT_PTR(ASSERT_PTR(link)->config);;
+ sd_device *device = ASSERT_PTR(ASSERT_PTR(link->event)->dev);
if (link->action != SD_DEVICE_ADD) {
log_link_debug(link, "Not applying Name= and NamePolicy= on '%s' uevent.",
@@ -822,14 +804,11 @@ no_rename:
static int link_generate_alternative_names(Link *link) {
_cleanup_strv_free_ char **altnames = NULL;
- LinkConfig *config;
- sd_device *device;
+ LinkConfig *config = ASSERT_PTR(ASSERT_PTR(link)->config);
+ sd_device *device = ASSERT_PTR(ASSERT_PTR(link->event)->dev);
int r;
- assert(link);
- config = ASSERT_PTR(link->config);
- device = ASSERT_PTR(link->device);
- assert(!link->altnames);
+ assert(!ASSERT_PTR(link->event)->altnames);
if (link->action != SD_DEVICE_ADD) {
log_link_debug(link, "Not applying AlternativeNames= and AlternativeNamesPolicy= on '%s' uevent.",
@@ -873,7 +852,7 @@ static int link_generate_alternative_names(Link *link) {
}
}
- link->altnames = TAKE_PTR(altnames);
+ link->event->altnames = TAKE_PTR(altnames);
return 0;
}
@@ -906,28 +885,28 @@ static int sr_iov_configure(Link *link, sd_netlink **rtnl, SRIOV *sr_iov) {
return 0;
}
-static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl, EventMode mode) {
+static int link_apply_sr_iov_config(Link *link) {
SRIOV *sr_iov;
uint32_t n;
int r;
assert(link);
assert(link->config);
- assert(link->device);
+ assert(ASSERT_PTR(link->event)->dev);
- if (mode != EVENT_UDEV_WORKER) {
+ if (link->event->event_mode != EVENT_UDEV_WORKER) {
log_link_debug(link, "Running in test mode, skipping application of SR-IOV settings.");
return 0;
}
- r = sr_iov_set_num_vfs(link->device, link->config->sr_iov_num_vfs, link->config->sr_iov_by_section);
+ r = sr_iov_set_num_vfs(link->event->dev, link->config->sr_iov_num_vfs, link->config->sr_iov_by_section);
if (r < 0)
log_link_warning_errno(link, r, "Failed to set the number of SR-IOV virtual functions, ignoring: %m");
if (ordered_hashmap_isempty(link->config->sr_iov_by_section))
return 0;
- r = sr_iov_get_num_vfs(link->device, &n);
+ r = sr_iov_get_num_vfs(link->event->dev, &n);
if (r < 0) {
log_link_warning_errno(link, r, "Failed to get the number of SR-IOV virtual functions, ignoring [SR-IOV] sections: %m");
return 0;
@@ -943,7 +922,7 @@ static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl, EventMode mod
continue;
}
- r = sr_iov_configure(link, rtnl, sr_iov);
+ r = sr_iov_configure(link, &link->event->rtnl, sr_iov);
if (r < 0)
log_link_warning_errno(link, r,
"Failed to configure SR-IOV virtual function %"PRIu32", ignoring: %m",
@@ -953,15 +932,15 @@ static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl, EventMode mod
return 0;
}
-static int link_apply_rps_cpu_mask(Link *link, EventMode mode) {
+static int link_apply_rps_cpu_mask(Link *link) {
_cleanup_free_ char *mask_str = NULL;
LinkConfig *config;
int r;
- assert(link);
- config = ASSERT_PTR(link->config);
+ config = ASSERT_PTR(ASSERT_PTR(link)->config);
+ assert(ASSERT_PTR(link->event)->dev);
- if (mode != EVENT_UDEV_WORKER) {
+ if (link->event->event_mode != EVENT_UDEV_WORKER) {
log_link_debug(link, "Running in test mode, skipping application of RPS setting.");
return 0;
}
@@ -977,7 +956,7 @@ static int link_apply_rps_cpu_mask(Link *link, EventMode mode) {
log_link_debug(link, "Applying RPS CPU mask: %s", mask_str);
/* Currently, this will set CPU mask to all rx queue of matched device. */
- FOREACH_DEVICE_SYSATTR(link->device, attr) {
+ FOREACH_DEVICE_SYSATTR(link->event->dev, attr) {
const char *c;
c = path_startswith(attr, "queues/");
@@ -993,7 +972,7 @@ static int link_apply_rps_cpu_mask(Link *link, EventMode mode) {
if (!path_equal(c, "/rps_cpus"))
continue;
- r = sd_device_set_sysattr_value(link->device, attr, mask_str);
+ r = sd_device_set_sysattr_value(link->event->dev, attr, mask_str);
if (r < 0)
log_link_warning_errno(link, r, "Failed to write %s sysfs attribute, ignoring: %m", attr);
}
@@ -1001,12 +980,9 @@ static int link_apply_rps_cpu_mask(Link *link, EventMode mode) {
return 0;
}
-static int link_apply_udev_properties(Link *link, UdevEvent *event) {
- LinkConfig *config;
-
- assert(link);
-
- config = ASSERT_PTR(link->config);
+static int link_apply_udev_properties(Link *link) {
+ LinkConfig *config = ASSERT_PTR(ASSERT_PTR(link)->config);
+ UdevEvent *event = ASSERT_PTR(link->event);
/* 1. apply ImportProperty=. */
STRV_FOREACH(p, config->import_properties)
@@ -1055,19 +1031,17 @@ static int link_apply_udev_properties(Link *link, UdevEvent *event) {
return 0;
}
-int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, UdevEvent *event) {
+int link_apply_config(LinkConfigContext *ctx, Link *link) {
int r;
assert(ctx);
- assert(rtnl);
assert(link);
- assert(event);
- r = link_apply_ethtool_settings(link, &ctx->ethtool_fd, event->event_mode);
+ r = link_apply_ethtool_settings(link, &ctx->ethtool_fd);
if (r < 0)
return r;
- r = link_apply_rtnl_settings(link, rtnl, event->event_mode);
+ r = link_apply_rtnl_settings(link);
if (r < 0)
return r;
@@ -1079,15 +1053,15 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, Ude
if (r < 0)
return r;
- r = link_apply_sr_iov_config(link, rtnl, event->event_mode);
+ r = link_apply_sr_iov_config(link);
if (r < 0)
return r;
- r = link_apply_rps_cpu_mask(link, event->event_mode);
+ r = link_apply_rps_cpu_mask(link);
if (r < 0)
return r;
- return link_apply_udev_properties(link, event);
+ return link_apply_udev_properties(link);
}
int config_parse_udev_property(
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index a60e183e4b..fd796bbaa5 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -26,16 +26,15 @@ typedef enum MACAddressPolicy {
} MACAddressPolicy;
typedef struct Link {
- int ifindex;
- const char *ifname;
- const char *new_name;
- char **altnames;
-
+ UdevEvent *event;
LinkConfig *config;
- sd_device *device;
- sd_device *device_db_clone;
+
+ /* from sd_device */
+ const char *ifname;
+ int ifindex;
sd_device_action_t action;
+ /* from rtnl */
char *kind;
const char *driver;
uint16_t iftype;
@@ -44,6 +43,9 @@ typedef struct Link {
struct hw_addr_data permanent_hw_addr;
unsigned name_assign_type;
unsigned addr_assign_type;
+
+ /* generated name */
+ const char *new_name;
} Link;
struct LinkConfig {
@@ -102,12 +104,12 @@ int link_load_one(LinkConfigContext *ctx, const char *filename);
int link_config_load(LinkConfigContext *ctx);
bool link_config_should_reload(LinkConfigContext *ctx);
-int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, sd_device *device_db_clone, Link **ret);
+int link_new(LinkConfigContext *ctx, UdevEvent *event, Link **ret);
Link* link_free(Link *link);
DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
int link_get_config(LinkConfigContext *ctx, Link *link);
-int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, UdevEvent *event);
+int link_apply_config(LinkConfigContext *ctx, Link *link);
const char* mac_address_policy_to_string(MACAddressPolicy p) _const_;
MACAddressPolicy mac_address_policy_from_string(const char *p) _pure_;
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
index 4500a69c68..572e171e07 100644
--- a/src/udev/udev-builtin-net_setup_link.c
+++ b/src/udev/udev-builtin-net_setup_link.c
@@ -41,7 +41,7 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv) {
return 0;
}
- r = link_new(ctx, &event->rtnl, dev, event->dev_db_clone, &link);
+ r = link_new(ctx, event, &link);
if (r == -ENODEV) {
log_device_debug_errno(dev, r, "Link vanished while getting information, ignoring.");
return 0;
@@ -59,14 +59,12 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv) {
return log_device_error_errno(dev, r, "Failed to get link config: %m");
}
- r = link_apply_config(ctx, &event->rtnl, link, event);
+ r = link_apply_config(ctx, link);
if (r == -ENODEV)
log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring.");
else if (r < 0)
log_device_warning_errno(dev, r, "Could not apply link configuration, ignoring: %m");
- event->altnames = TAKE_PTR(link->altnames);
-
return 0;
}

View File

@ -0,0 +1,764 @@
From ce2b557c15680ec67accc5242d34dc651c2be3e7 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 02:33:47 +0900
Subject: [PATCH] udev: move parsers for config file, kerenel command line, and
positional arguments to udev-config.c
No functional change, just refactoring and preparation for later
commits.
(cherry picked from commit 394a678aec3b8bba0f0b1a8d7b9427c62468fe68)
Resolves: RHEL-75774
---
src/udev/meson.build | 1 +
src/udev/udev-config.c | 311 ++++++++++++++++++++++++++++++++++++++++
src/udev/udev-config.h | 11 ++
src/udev/udev-manager.c | 49 +------
src/udev/udev-manager.h | 1 -
src/udev/udevd.c | 250 +-------------------------------
6 files changed, 326 insertions(+), 297 deletions(-)
create mode 100644 src/udev/udev-config.c
create mode 100644 src/udev/udev-config.h
diff --git a/src/udev/meson.build b/src/udev/meson.build
index 921dfac39c..d7acbae6bb 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -19,6 +19,7 @@ udevadm_sources = files(
libudevd_core_sources = files(
'net/link-config.c',
+ 'udev-config.c',
'udev-ctrl.c',
'udev-event.c',
'udev-format.c',
diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c
new file mode 100644
index 0000000000..b774e7676e
--- /dev/null
+++ b/src/udev/udev-config.c
@@ -0,0 +1,311 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include "conf-parser.h"
+#include "cpu-set-util.h"
+#include "limits-util.h"
+#include "parse-util.h"
+#include "pretty-print.h"
+#include "proc-cmdline.h"
+#include "signal-util.h"
+#include "syslog-util.h"
+#include "udev-config.h"
+#include "udev-manager.h"
+#include "udev-rules.h"
+#include "udev-util.h"
+#include "udev-worker.h"
+#include "version.h"
+
+#define WORKER_NUM_MAX UINT64_C(2048)
+
+static bool arg_debug = false;
+bool arg_daemonize = false;
+
+static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming);
+
+static int manager_parse_udev_config(Manager *manager) {
+ int r, log_val = -1;
+
+ assert(manager);
+
+ const ConfigTableItem config_table[] = {
+ { NULL, "udev_log", config_parse_log_level, 0, &log_val },
+ { NULL, "children_max", config_parse_unsigned, 0, &manager->children_max },
+ { NULL, "exec_delay", config_parse_sec, 0, &manager->exec_delay_usec },
+ { NULL, "event_timeout", config_parse_sec, 0, &manager->timeout_usec },
+ { NULL, "resolve_names", config_parse_resolve_name_timing, 0, &manager->resolve_name_timing },
+ { NULL, "timeout_signal", config_parse_signal, 0, &manager->timeout_signal },
+ {}
+ };
+
+ r = udev_parse_config_full(config_table);
+ if (r < 0)
+ return r;
+
+ if (log_val >= 0)
+ log_set_max_level(log_val);
+
+ return 0;
+}
+
+/*
+ * read the kernel command line, in case we need to get into debug mode
+ * udev.log_level=<level> syslog priority
+ * udev.children_max=<number of workers> events are fully serialized if set to 1
+ * udev.exec_delay=<number of seconds> delay execution of every executed program
+ * udev.event_timeout=<number of seconds> seconds to wait before terminating an event
+ * udev.blockdev_read_only<=bool> mark all block devices read-only when they appear
+ */
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
+ Manager *manager = ASSERT_PTR(data);
+ int r;
+
+ assert(key);
+
+ if (proc_cmdline_key_streq(key, "udev.log_level") ||
+ proc_cmdline_key_streq(key, "udev.log_priority")) { /* kept for backward compatibility */
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = log_level_from_string(value);
+ if (r >= 0)
+ manager->log_level = r;
+
+ } else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = parse_sec(value, &manager->timeout_usec);
+
+ } else if (proc_cmdline_key_streq(key, "udev.children_max")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = safe_atou(value, &manager->children_max);
+
+ } else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = parse_sec(value, &manager->exec_delay_usec);
+
+ } else if (proc_cmdline_key_streq(key, "udev.timeout_signal")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = signal_from_string(value);
+ if (r > 0)
+ manager->timeout_signal = r;
+
+ } else if (proc_cmdline_key_streq(key, "udev.blockdev_read_only")) {
+
+ if (!value)
+ manager->blockdev_read_only = true;
+ else {
+ r = parse_boolean(value);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse udev.blockdev-read-only argument, ignoring: %s", value);
+ else
+ manager->blockdev_read_only = r;
+ }
+
+ if (manager->blockdev_read_only)
+ log_notice("All physical block devices will be marked read-only.");
+
+ return 0;
+
+ } else {
+ if (startswith(key, "udev."))
+ log_warning("Unknown udev kernel command line option \"%s\", ignoring.", key);
+
+ return 0;
+ }
+
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse \"%s=%s\", ignoring: %m", key, value);
+
+ return 0;
+}
+
+static int help(void) {
+ _cleanup_free_ char *link = NULL;
+ int r;
+
+ r = terminal_urlify_man("systemd-udevd.service", "8", &link);
+ if (r < 0)
+ return log_oom();
+
+ printf("%s [OPTIONS...]\n\n"
+ "Rule-based manager for device events and files.\n\n"
+ " -h --help Print this message\n"
+ " -V --version Print version of the program\n"
+ " -d --daemon Detach and run in the background\n"
+ " -D --debug Enable debug output\n"
+ " -c --children-max=INT Set maximum number of workers\n"
+ " -e --exec-delay=SECONDS Seconds to wait before executing RUN=\n"
+ " -t --event-timeout=SECONDS Seconds to wait before terminating an event\n"
+ " -N --resolve-names=early|late|never\n"
+ " When to resolve users and groups\n"
+ "\nSee the %s for details.\n",
+ program_invocation_short_name,
+ link);
+
+ return 0;
+}
+
+static int parse_argv(int argc, char *argv[], Manager *manager) {
+ enum {
+ ARG_TIMEOUT_SIGNAL,
+ };
+
+ static const struct option options[] = {
+ { "daemon", no_argument, NULL, 'd' },
+ { "debug", no_argument, NULL, 'D' },
+ { "children-max", required_argument, NULL, 'c' },
+ { "exec-delay", required_argument, NULL, 'e' },
+ { "event-timeout", required_argument, NULL, 't' },
+ { "resolve-names", required_argument, NULL, 'N' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "timeout-signal", required_argument, NULL, ARG_TIMEOUT_SIGNAL },
+ {}
+ };
+
+ int c, r;
+
+ assert(argc >= 0);
+ assert(argv);
+ assert(manager);
+
+ while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
+ switch (c) {
+
+ case 'd':
+ arg_daemonize = true;
+ break;
+ case 'c':
+ r = safe_atou(optarg, &manager->children_max);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", optarg);
+ break;
+ case 'e':
+ r = parse_sec(optarg, &manager->exec_delay_usec);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", optarg);
+ break;
+ case ARG_TIMEOUT_SIGNAL:
+ r = signal_from_string(optarg);
+ if (r <= 0)
+ log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", optarg);
+ else
+ manager->timeout_signal = r;
+
+ break;
+ case 't':
+ r = parse_sec(optarg, &manager->timeout_usec);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", optarg);
+ break;
+ case 'D':
+ arg_debug = true;
+ break;
+ case 'N': {
+ ResolveNameTiming t;
+
+ t = resolve_name_timing_from_string(optarg);
+ if (t < 0)
+ log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
+ else
+ manager->resolve_name_timing = t;
+ break;
+ }
+ case 'h':
+ return help();
+ case 'V':
+ printf("%s\n", GIT_VERSION);
+ return 0;
+ case '?':
+ return -EINVAL;
+ default:
+ assert_not_reached();
+
+ }
+ }
+
+ return 1;
+}
+
+void manager_set_default_children_max(Manager *manager) {
+ uint64_t cpu_limit, mem_limit, cpu_count = 1;
+ int r;
+
+ assert(manager);
+
+ if (manager->children_max != 0)
+ return;
+
+ r = cpus_in_affinity_mask();
+ if (r < 0)
+ log_warning_errno(r, "Failed to determine number of local CPUs, ignoring: %m");
+ else
+ cpu_count = r;
+
+ cpu_limit = cpu_count * 2 + 16;
+ mem_limit = MAX(physical_memory() / (128*1024*1024), UINT64_C(10));
+
+ manager->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
+ log_debug("Set children_max to %u", manager->children_max);
+}
+
+static void manager_adjust_config(Manager *manager) {
+ assert(manager);
+
+ if (manager->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
+ log_debug("Timeout (%s) for processing event is too small, using the default: %s",
+ FORMAT_TIMESPAN(manager->timeout_usec, 1),
+ FORMAT_TIMESPAN(DEFAULT_WORKER_TIMEOUT_USEC, 1));
+
+ manager->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
+ }
+
+ if (manager->exec_delay_usec >= manager->timeout_usec) {
+ log_debug("Delay (%s) for executing RUN= commands is too large compared with the timeout (%s) for event execution, ignoring the delay.",
+ FORMAT_TIMESPAN(manager->exec_delay_usec, 1),
+ FORMAT_TIMESPAN(manager->timeout_usec, 1));
+
+ manager->exec_delay_usec = 0;
+ }
+
+ manager_set_default_children_max(manager);
+}
+
+int manager_load(Manager *manager, int argc, char *argv[]) {
+ int r;
+
+ assert(manager);
+
+ manager_parse_udev_config(manager);
+
+ r = parse_argv(argc, argv, manager);
+ if (r <= 0)
+ return r;
+
+ r = proc_cmdline_parse(parse_proc_cmdline_item, manager, PROC_CMDLINE_STRIP_RD_PREFIX);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
+
+ if (arg_debug) {
+ log_set_target(LOG_TARGET_CONSOLE);
+ log_set_max_level(LOG_DEBUG);
+ }
+
+ manager_adjust_config(manager);
+ return 1;
+}
diff --git a/src/udev/udev-config.h b/src/udev/udev-config.h
new file mode 100644
index 0000000000..9a8a18821f
--- /dev/null
+++ b/src/udev/udev-config.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
+#include <stdbool.h>
+
+extern bool arg_daemonize;
+
+typedef struct Manager Manager;
+
+int manager_load(Manager *manager, int argc, char *argv[]);
+void manager_set_default_children_max(Manager *manager);
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 6e1935a731..23a57dbed3 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -3,7 +3,6 @@
#include "blockdev-util.h"
#include "cgroup-util.h"
#include "common-signal.h"
-#include "cpu-set-util.h"
#include "daemon-util.h"
#include "device-monitor-private.h"
#include "device-private.h"
@@ -15,7 +14,6 @@
#include "hashmap.h"
#include "inotify-util.h"
#include "iovec-util.h"
-#include "limits-util.h"
#include "list.h"
#include "mkdir.h"
#include "process-util.h"
@@ -25,6 +23,7 @@
#include "string-util.h"
#include "syslog-util.h"
#include "udev-builtin.h"
+#include "udev-config.h"
#include "udev-ctrl.h"
#include "udev-event.h"
#include "udev-manager.h"
@@ -36,8 +35,6 @@
#include "udev-watch.h"
#include "udev-worker.h"
-#define WORKER_NUM_MAX UINT64_C(2048)
-
#define EVENT_RETRY_INTERVAL_USEC (200 * USEC_PER_MSEC)
#define EVENT_RETRY_TIMEOUT_USEC (3 * USEC_PER_MINUTE)
@@ -845,28 +842,6 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
return 1;
}
-static void manager_set_default_children_max(Manager *manager) {
- uint64_t cpu_limit, mem_limit, cpu_count = 1;
- int r;
-
- assert(manager);
-
- if (manager->children_max != 0)
- return;
-
- r = cpus_in_affinity_mask();
- if (r < 0)
- log_warning_errno(r, "Failed to determine number of local CPUs, ignoring: %m");
- else
- cpu_count = r;
-
- cpu_limit = cpu_count * 2 + 16;
- mem_limit = MAX(physical_memory() / (128*1024*1024), UINT64_C(10));
-
- manager->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
- log_debug("Set children_max to %u", manager->children_max);
-}
-
/* receive the udevd message from userspace */
static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) {
Manager *manager = ASSERT_PTR(userdata);
@@ -1208,26 +1183,6 @@ Manager* manager_new(void) {
return manager;
}
-void manager_adjust_arguments(Manager *manager) {
- assert(manager);
-
- if (manager->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
- log_debug("Timeout (%s) for processing event is too small, using the default: %s",
- FORMAT_TIMESPAN(manager->timeout_usec, 1),
- FORMAT_TIMESPAN(DEFAULT_WORKER_TIMEOUT_USEC, 1));
-
- manager->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
- }
-
- if (manager->exec_delay_usec >= manager->timeout_usec) {
- log_debug("Delay (%s) for executing RUN= commands is too large compared with the timeout (%s) for event execution, ignoring the delay.",
- FORMAT_TIMESPAN(manager->exec_delay_usec, 1),
- FORMAT_TIMESPAN(manager->timeout_usec, 1));
-
- manager->exec_delay_usec = 0;
- }
-}
-
static int listen_fds(int *ret_ctrl, int *ret_netlink) {
_cleanup_strv_free_ char **names = NULL;
_cleanup_close_ int ctrl_fd = -EBADF, netlink_fd = -EBADF;
@@ -1319,8 +1274,6 @@ int manager_init(Manager *manager) {
int manager_main(Manager *manager) {
int fd_worker, r;
- manager_set_default_children_max(manager);
-
/* unnamed socket from workers to the main daemon */
r = socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
if (r < 0)
diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h
index 7c20e29594..14b458bcdb 100644
--- a/src/udev/udev-manager.h
+++ b/src/udev/udev-manager.h
@@ -53,7 +53,6 @@ Manager* manager_new(void);
Manager* manager_free(Manager *manager);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
-void manager_adjust_arguments(Manager *manager);
int manager_init(Manager *manager);
int manager_main(Manager *manager);
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index ef1c07a2ca..018a3cd6e7 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -5,250 +5,17 @@
* Copyright © 2009 Scott James Remnant <scott@netsplit.com>
*/
-#include <getopt.h>
-#include <unistd.h>
-
-#include "conf-parser.h"
-#include "env-file.h"
#include "errno-util.h"
#include "fd-util.h"
#include "mkdir.h"
-#include "parse-util.h"
-#include "pretty-print.h"
-#include "proc-cmdline.h"
#include "process-util.h"
#include "rlimit-util.h"
#include "selinux-util.h"
-#include "signal-util.h"
-#include "syslog-util.h"
+#include "udev-config.h"
#include "udev-manager.h"
-#include "udev-rules.h"
-#include "udev-util.h"
#include "udevd.h"
#include "version.h"
-static bool arg_debug = false;
-static int arg_daemonize = false;
-
-static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming);
-
-static int manager_parse_udev_config(Manager *manager) {
- int r, log_val = -1;
-
- assert(manager);
-
- const ConfigTableItem config_table[] = {
- { NULL, "udev_log", config_parse_log_level, 0, &log_val },
- { NULL, "children_max", config_parse_unsigned, 0, &manager->children_max },
- { NULL, "exec_delay", config_parse_sec, 0, &manager->exec_delay_usec },
- { NULL, "event_timeout", config_parse_sec, 0, &manager->timeout_usec },
- { NULL, "resolve_names", config_parse_resolve_name_timing, 0, &manager->resolve_name_timing },
- { NULL, "timeout_signal", config_parse_signal, 0, &manager->timeout_signal },
- {}
- };
-
- r = udev_parse_config_full(config_table);
- if (r < 0)
- return r;
-
- if (log_val >= 0)
- log_set_max_level(log_val);
-
- return 0;
-}
-
-/*
- * read the kernel command line, in case we need to get into debug mode
- * udev.log_level=<level> syslog priority
- * udev.children_max=<number of workers> events are fully serialized if set to 1
- * udev.exec_delay=<number of seconds> delay execution of every executed program
- * udev.event_timeout=<number of seconds> seconds to wait before terminating an event
- * udev.blockdev_read_only<=bool> mark all block devices read-only when they appear
- */
-static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
- Manager *manager = ASSERT_PTR(data);
- int r;
-
- assert(key);
-
- if (proc_cmdline_key_streq(key, "udev.log_level") ||
- proc_cmdline_key_streq(key, "udev.log_priority")) { /* kept for backward compatibility */
-
- if (proc_cmdline_value_missing(key, value))
- return 0;
-
- r = log_level_from_string(value);
- if (r >= 0)
- log_set_max_level(r);
-
- } else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
-
- if (proc_cmdline_value_missing(key, value))
- return 0;
-
- r = parse_sec(value, &manager->timeout_usec);
-
- } else if (proc_cmdline_key_streq(key, "udev.children_max")) {
-
- if (proc_cmdline_value_missing(key, value))
- return 0;
-
- r = safe_atou(value, &manager->children_max);
-
- } else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
-
- if (proc_cmdline_value_missing(key, value))
- return 0;
-
- r = parse_sec(value, &manager->exec_delay_usec);
-
- } else if (proc_cmdline_key_streq(key, "udev.timeout_signal")) {
-
- if (proc_cmdline_value_missing(key, value))
- return 0;
-
- r = signal_from_string(value);
- if (r > 0)
- manager->timeout_signal = r;
-
- } else if (proc_cmdline_key_streq(key, "udev.blockdev_read_only")) {
-
- if (!value)
- manager->blockdev_read_only = true;
- else {
- r = parse_boolean(value);
- if (r < 0)
- log_warning_errno(r, "Failed to parse udev.blockdev-read-only argument, ignoring: %s", value);
- else
- manager->blockdev_read_only = r;
- }
-
- if (manager->blockdev_read_only)
- log_notice("All physical block devices will be marked read-only.");
-
- return 0;
-
- } else {
- if (startswith(key, "udev."))
- log_warning("Unknown udev kernel command line option \"%s\", ignoring.", key);
-
- return 0;
- }
-
- if (r < 0)
- log_warning_errno(r, "Failed to parse \"%s=%s\", ignoring: %m", key, value);
-
- return 0;
-}
-
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-udevd.service", "8", &link);
- if (r < 0)
- return log_oom();
-
- printf("%s [OPTIONS...]\n\n"
- "Rule-based manager for device events and files.\n\n"
- " -h --help Print this message\n"
- " -V --version Print version of the program\n"
- " -d --daemon Detach and run in the background\n"
- " -D --debug Enable debug output\n"
- " -c --children-max=INT Set maximum number of workers\n"
- " -e --exec-delay=SECONDS Seconds to wait before executing RUN=\n"
- " -t --event-timeout=SECONDS Seconds to wait before terminating an event\n"
- " -N --resolve-names=early|late|never\n"
- " When to resolve users and groups\n"
- "\nSee the %s for details.\n",
- program_invocation_short_name,
- link);
-
- return 0;
-}
-
-static int parse_argv(int argc, char *argv[], Manager *manager) {
- enum {
- ARG_TIMEOUT_SIGNAL,
- };
-
- static const struct option options[] = {
- { "daemon", no_argument, NULL, 'd' },
- { "debug", no_argument, NULL, 'D' },
- { "children-max", required_argument, NULL, 'c' },
- { "exec-delay", required_argument, NULL, 'e' },
- { "event-timeout", required_argument, NULL, 't' },
- { "resolve-names", required_argument, NULL, 'N' },
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'V' },
- { "timeout-signal", required_argument, NULL, ARG_TIMEOUT_SIGNAL },
- {}
- };
-
- int c, r;
-
- assert(argc >= 0);
- assert(argv);
- assert(manager);
-
- while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
- switch (c) {
-
- case 'd':
- arg_daemonize = true;
- break;
- case 'c':
- r = safe_atou(optarg, &manager->children_max);
- if (r < 0)
- log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", optarg);
- break;
- case 'e':
- r = parse_sec(optarg, &manager->exec_delay_usec);
- if (r < 0)
- log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", optarg);
- break;
- case ARG_TIMEOUT_SIGNAL:
- r = signal_from_string(optarg);
- if (r <= 0)
- log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", optarg);
- else
- manager->timeout_signal = r;
-
- break;
- case 't':
- r = parse_sec(optarg, &manager->timeout_usec);
- if (r < 0)
- log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", optarg);
- break;
- case 'D':
- arg_debug = true;
- break;
- case 'N': {
- ResolveNameTiming t;
-
- t = resolve_name_timing_from_string(optarg);
- if (t < 0)
- log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
- else
- manager->resolve_name_timing = t;
- break;
- }
- case 'h':
- return help();
- case 'V':
- printf("%s\n", GIT_VERSION);
- return 0;
- case '?':
- return -EINVAL;
- default:
- assert_not_reached();
-
- }
- }
-
- return 1;
-}
-
int run_udevd(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *manager = NULL;
int r;
@@ -259,23 +26,10 @@ int run_udevd(int argc, char *argv[]) {
if (!manager)
return log_oom();
- manager_parse_udev_config(manager);
-
- r = parse_argv(argc, argv, manager);
+ r = manager_load(manager, argc, argv);
if (r <= 0)
return r;
- r = proc_cmdline_parse(parse_proc_cmdline_item, manager, PROC_CMDLINE_STRIP_RD_PREFIX);
- if (r < 0)
- log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
-
- if (arg_debug) {
- log_set_target(LOG_TARGET_CONSOLE);
- log_set_max_level(LOG_DEBUG);
- }
-
- manager_adjust_arguments(manager);
-
r = must_be_root();
if (r < 0)
return r;

View File

@ -0,0 +1,629 @@
From 623edeade94ef18f503ccac4296629b31bdd7515 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 02:26:02 +0900
Subject: [PATCH] udev-config: introduce UdevConfig
Then, save configurations by their source: udev.conf, command line
arguments, kernel command line options, and udev control.
Preparation to support reloading udev.conf in a later commit.
(cherry picked from commit 04fa5c1580ad388af3477ecfd7d4aa7d7f5cee30)
Resolves: RHEL-75774
---
src/udev/udev-config.c | 142 ++++++++++++++++++++++++----------------
src/udev/udev-config.h | 21 +++++-
src/udev/udev-event.c | 2 +-
src/udev/udev-manager.c | 40 +++++------
src/udev/udev-manager.h | 13 ++--
src/udev/udev-spawn.c | 14 ++--
src/udev/udev-worker.c | 4 +-
src/udev/udev-worker.h | 7 +-
8 files changed, 142 insertions(+), 101 deletions(-)
diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c
index b774e7676e..eced080547 100644
--- a/src/udev/udev-config.c
+++ b/src/udev/udev-config.c
@@ -25,29 +25,20 @@ bool arg_daemonize = false;
static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming);
-static int manager_parse_udev_config(Manager *manager) {
- int r, log_val = -1;
-
- assert(manager);
+static void manager_parse_udev_config(UdevConfig *config) {
+ assert(config);
const ConfigTableItem config_table[] = {
- { NULL, "udev_log", config_parse_log_level, 0, &log_val },
- { NULL, "children_max", config_parse_unsigned, 0, &manager->children_max },
- { NULL, "exec_delay", config_parse_sec, 0, &manager->exec_delay_usec },
- { NULL, "event_timeout", config_parse_sec, 0, &manager->timeout_usec },
- { NULL, "resolve_names", config_parse_resolve_name_timing, 0, &manager->resolve_name_timing },
- { NULL, "timeout_signal", config_parse_signal, 0, &manager->timeout_signal },
+ { NULL, "udev_log", config_parse_log_level, 0, &config->log_level },
+ { NULL, "children_max", config_parse_unsigned, 0, &config->children_max },
+ { NULL, "exec_delay", config_parse_sec, 0, &config->exec_delay_usec },
+ { NULL, "event_timeout", config_parse_sec, 0, &config->timeout_usec },
+ { NULL, "resolve_names", config_parse_resolve_name_timing, 0, &config->resolve_name_timing },
+ { NULL, "timeout_signal", config_parse_signal, 0, &config->timeout_signal },
{}
};
- r = udev_parse_config_full(config_table);
- if (r < 0)
- return r;
-
- if (log_val >= 0)
- log_set_max_level(log_val);
-
- return 0;
+ (void) udev_parse_config_full(config_table);
}
/*
@@ -59,7 +50,7 @@ static int manager_parse_udev_config(Manager *manager) {
* udev.blockdev_read_only<=bool> mark all block devices read-only when they appear
*/
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
- Manager *manager = ASSERT_PTR(data);
+ UdevConfig *config = ASSERT_PTR(data);
int r;
assert(key);
@@ -72,28 +63,28 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
r = log_level_from_string(value);
if (r >= 0)
- manager->log_level = r;
+ config->log_level = r;
} else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
if (proc_cmdline_value_missing(key, value))
return 0;
- r = parse_sec(value, &manager->timeout_usec);
+ r = parse_sec(value, &config->timeout_usec);
} else if (proc_cmdline_key_streq(key, "udev.children_max")) {
if (proc_cmdline_value_missing(key, value))
return 0;
- r = safe_atou(value, &manager->children_max);
+ r = safe_atou(value, &config->children_max);
} else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
if (proc_cmdline_value_missing(key, value))
return 0;
- r = parse_sec(value, &manager->exec_delay_usec);
+ r = parse_sec(value, &config->exec_delay_usec);
} else if (proc_cmdline_key_streq(key, "udev.timeout_signal")) {
@@ -102,21 +93,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
r = signal_from_string(value);
if (r > 0)
- manager->timeout_signal = r;
+ config->timeout_signal = r;
} else if (proc_cmdline_key_streq(key, "udev.blockdev_read_only")) {
if (!value)
- manager->blockdev_read_only = true;
+ config->blockdev_read_only = true;
else {
r = parse_boolean(value);
if (r < 0)
log_warning_errno(r, "Failed to parse udev.blockdev-read-only argument, ignoring: %s", value);
else
- manager->blockdev_read_only = r;
+ config->blockdev_read_only = r;
}
- if (manager->blockdev_read_only)
+ if (config->blockdev_read_only)
log_notice("All physical block devices will be marked read-only.");
return 0;
@@ -160,7 +151,7 @@ static int help(void) {
return 0;
}
-static int parse_argv(int argc, char *argv[], Manager *manager) {
+static int parse_argv(int argc, char *argv[], UdevConfig *config) {
enum {
ARG_TIMEOUT_SIGNAL,
};
@@ -182,7 +173,7 @@ static int parse_argv(int argc, char *argv[], Manager *manager) {
assert(argc >= 0);
assert(argv);
- assert(manager);
+ assert(config);
while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
switch (c) {
@@ -191,12 +182,12 @@ static int parse_argv(int argc, char *argv[], Manager *manager) {
arg_daemonize = true;
break;
case 'c':
- r = safe_atou(optarg, &manager->children_max);
+ r = safe_atou(optarg, &config->children_max);
if (r < 0)
log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", optarg);
break;
case 'e':
- r = parse_sec(optarg, &manager->exec_delay_usec);
+ r = parse_sec(optarg, &config->exec_delay_usec);
if (r < 0)
log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", optarg);
break;
@@ -205,16 +196,17 @@ static int parse_argv(int argc, char *argv[], Manager *manager) {
if (r <= 0)
log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", optarg);
else
- manager->timeout_signal = r;
+ config->timeout_signal = r;
break;
case 't':
- r = parse_sec(optarg, &manager->timeout_usec);
+ r = parse_sec(optarg, &config->timeout_usec);
if (r < 0)
log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", optarg);
break;
case 'D':
arg_debug = true;
+ config->log_level = LOG_DEBUG;
break;
case 'N': {
ResolveNameTiming t;
@@ -223,7 +215,7 @@ static int parse_argv(int argc, char *argv[], Manager *manager) {
if (t < 0)
log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
else
- manager->resolve_name_timing = t;
+ config->resolve_name_timing = t;
break;
}
case 'h':
@@ -242,13 +234,50 @@ static int parse_argv(int argc, char *argv[], Manager *manager) {
return 1;
}
-void manager_set_default_children_max(Manager *manager) {
+#define MERGE_NON_NEGATIVE(name, default_value) \
+ manager->config.name = \
+ manager->config_by_control.name >= 0 ? manager->config_by_control.name : \
+ manager->config_by_kernel.name >= 0 ? manager->config_by_kernel.name : \
+ manager->config_by_command.name >= 0 ? manager->config_by_command.name : \
+ manager->config_by_udev_conf.name >= 0 ? manager->config_by_udev_conf.name : \
+ default_value;
+
+#define MERGE_NON_ZERO(name, default_value) \
+ manager->config.name = \
+ manager->config_by_control.name ?: \
+ manager->config_by_kernel.name ?: \
+ manager->config_by_command.name ?: \
+ manager->config_by_udev_conf.name ?: \
+ default_value;
+
+#define MERGE_BOOL(name) \
+ manager->config.name = \
+ manager->config_by_control.name || \
+ manager->config_by_kernel.name || \
+ manager->config_by_command.name || \
+ manager->config_by_udev_conf.name;
+
+static void manager_merge_config(Manager *manager) {
+ assert(manager);
+
+ /* udev.conf has the lowest priority, then followed by command line arguments, kernel command line
+ options, and values set by udev control. */
+
+ MERGE_NON_NEGATIVE(log_level, log_get_max_level());
+ MERGE_NON_NEGATIVE(resolve_name_timing, RESOLVE_NAME_EARLY);
+ MERGE_NON_ZERO(exec_delay_usec, 0);
+ MERGE_NON_ZERO(timeout_usec, DEFAULT_WORKER_TIMEOUT_USEC);
+ MERGE_NON_ZERO(timeout_signal, SIGKILL);
+ MERGE_BOOL(blockdev_read_only);
+}
+
+void udev_config_set_default_children_max(UdevConfig *config) {
uint64_t cpu_limit, mem_limit, cpu_count = 1;
int r;
- assert(manager);
+ assert(config);
- if (manager->children_max != 0)
+ if (config->children_max != 0)
return;
r = cpus_in_affinity_mask();
@@ -260,30 +289,30 @@ void manager_set_default_children_max(Manager *manager) {
cpu_limit = cpu_count * 2 + 16;
mem_limit = MAX(physical_memory() / (128*1024*1024), UINT64_C(10));
- manager->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
- log_debug("Set children_max to %u", manager->children_max);
+ config->children_max = MIN3(cpu_limit, mem_limit, WORKER_NUM_MAX);
+ log_debug("Set children_max to %u", config->children_max);
}
-static void manager_adjust_config(Manager *manager) {
- assert(manager);
+static void manager_adjust_config(UdevConfig *config) {
+ assert(config);
- if (manager->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
+ if (config->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
log_debug("Timeout (%s) for processing event is too small, using the default: %s",
- FORMAT_TIMESPAN(manager->timeout_usec, 1),
+ FORMAT_TIMESPAN(config->timeout_usec, 1),
FORMAT_TIMESPAN(DEFAULT_WORKER_TIMEOUT_USEC, 1));
- manager->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
+ config->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
}
- if (manager->exec_delay_usec >= manager->timeout_usec) {
+ if (config->exec_delay_usec >= config->timeout_usec) {
log_debug("Delay (%s) for executing RUN= commands is too large compared with the timeout (%s) for event execution, ignoring the delay.",
- FORMAT_TIMESPAN(manager->exec_delay_usec, 1),
- FORMAT_TIMESPAN(manager->timeout_usec, 1));
+ FORMAT_TIMESPAN(config->exec_delay_usec, 1),
+ FORMAT_TIMESPAN(config->timeout_usec, 1));
- manager->exec_delay_usec = 0;
+ config->exec_delay_usec = 0;
}
- manager_set_default_children_max(manager);
+ udev_config_set_default_children_max(config);
}
int manager_load(Manager *manager, int argc, char *argv[]) {
@@ -291,21 +320,22 @@ int manager_load(Manager *manager, int argc, char *argv[]) {
assert(manager);
- manager_parse_udev_config(manager);
+ manager_parse_udev_config(&manager->config_by_udev_conf);
- r = parse_argv(argc, argv, manager);
+ r = parse_argv(argc, argv, &manager->config_by_command);
if (r <= 0)
return r;
- r = proc_cmdline_parse(parse_proc_cmdline_item, manager, PROC_CMDLINE_STRIP_RD_PREFIX);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, &manager->config_by_kernel, PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
- if (arg_debug) {
+ manager_merge_config(manager);
+
+ if (arg_debug)
log_set_target(LOG_TARGET_CONSOLE);
- log_set_max_level(LOG_DEBUG);
- }
- manager_adjust_config(manager);
+ log_set_max_level(manager->config.log_level);
+ manager_adjust_config(&manager->config);
return 1;
}
diff --git a/src/udev/udev-config.h b/src/udev/udev-config.h
index 9a8a18821f..3b0997eeb0 100644
--- a/src/udev/udev-config.h
+++ b/src/udev/udev-config.h
@@ -3,9 +3,28 @@
#include <stdbool.h>
+#include "time-util.h"
+#include "udev-def.h"
+
extern bool arg_daemonize;
typedef struct Manager Manager;
+typedef struct UdevConfig {
+ int log_level;
+ ResolveNameTiming resolve_name_timing;
+ unsigned children_max;
+ usec_t exec_delay_usec;
+ usec_t timeout_usec;
+ int timeout_signal;
+ bool blockdev_read_only;
+} UdevConfig;
+
+#define UDEV_CONFIG_INIT \
+ (UdevConfig) { \
+ .log_level = -1, \
+ .resolve_name_timing = _RESOLVE_NAME_TIMING_INVALID, \
+ }
+
int manager_load(Manager *manager, int argc, char *argv[]);
-void manager_set_default_children_max(Manager *manager);
+void udev_config_set_default_children_max(UdevConfig *c);
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 6a7c34b162..e3661f5bf8 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -19,7 +19,7 @@
#include "user-util.h"
UdevEvent* udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) {
- int log_level = worker ? worker->log_level : log_get_max_level();
+ int log_level = worker ? worker->config.log_level : log_get_max_level();
UdevEvent *event;
assert(dev);
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 23a57dbed3..7f7079bcd2 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -240,7 +240,7 @@ static void notify_ready(Manager *manager) {
r = sd_notifyf(/* unset= */ false,
"READY=1\n"
- "STATUS=Processing with %u children at max", manager->children_max);
+ "STATUS=Processing with %u children at max", manager->config.children_max);
if (r < 0)
log_warning_errno(r, "Failed to send readiness notification, ignoring: %m");
}
@@ -278,7 +278,7 @@ static void manager_reload(Manager *manager, bool force) {
udev_builtin_exit();
udev_builtin_init();
- r = udev_rules_load(&rules, manager->resolve_name_timing);
+ r = udev_rules_load(&rules, manager->config.resolve_name_timing);
if (r < 0)
log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");
else
@@ -303,7 +303,7 @@ static int on_event_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
assert(event->manager);
assert(event->worker);
- kill_and_sigcont(event->worker->pid, event->manager->timeout_signal);
+ kill_and_sigcont(event->worker->pid, event->manager->config.timeout_signal);
event->worker->state = WORKER_KILLED;
log_device_error(event->dev, "Worker ["PID_FMT"] processing SEQNUM=%"PRIu64" killed", event->worker->pid, event->seqnum);
@@ -363,7 +363,7 @@ static void worker_attach_event(Worker *worker, Event *event) {
event->worker = worker;
(void) sd_event_add_time_relative(e, &event->timeout_warning_event, CLOCK_MONOTONIC,
- udev_warn_timeout(manager->timeout_usec), USEC_PER_SEC,
+ udev_warn_timeout(manager->config.timeout_usec), USEC_PER_SEC,
on_event_timeout_warning, event);
/* Manager.timeout_usec is also used as the timeout for running programs specified in
@@ -371,7 +371,7 @@ static void worker_attach_event(Worker *worker, Event *event) {
* kills a worker, to make it possible that the worker detects timed out of spawned programs,
* kills them, and finalizes the event. */
(void) sd_event_add_time_relative(e, &event->timeout_event, CLOCK_MONOTONIC,
- usec_add(manager->timeout_usec, extra_timeout_usec()), USEC_PER_SEC,
+ usec_add(manager->config.timeout_usec, extra_timeout_usec()), USEC_PER_SEC,
on_event_timeout, event);
}
@@ -405,11 +405,7 @@ static int worker_spawn(Manager *manager, Event *event) {
.rules = TAKE_PTR(manager->rules),
.pipe_fd = TAKE_FD(manager->worker_watch[WRITE_END]),
.inotify_fd = TAKE_FD(manager->inotify_fd),
- .exec_delay_usec = manager->exec_delay_usec,
- .timeout_usec = manager->timeout_usec,
- .timeout_signal = manager->timeout_signal,
- .log_level = manager->log_level,
- .blockdev_read_only = manager->blockdev_read_only,
+ .config = manager->config,
};
/* Worker process */
@@ -458,10 +454,10 @@ static int event_run(Event *event) {
return 1; /* event is now processing. */
}
- if (hashmap_size(manager->workers) >= manager->children_max) {
+ if (hashmap_size(manager->workers) >= manager->config.children_max) {
/* Avoid spamming the debug logs if the limit is already reached and
* many events still need to be processed */
- if (log_children_max_reached && manager->children_max > 1) {
+ if (log_children_max_reached && manager->config.children_max > 1) {
log_debug("Maximum number (%u) of children reached.", hashmap_size(manager->workers));
log_children_max_reached = false;
}
@@ -863,7 +859,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
break;
log_set_max_level(value->intval);
- manager->log_level = value->intval;
+ manager->config.log_level = manager->config_by_control.log_level = value->intval;
manager_kill_workers(manager, false);
break;
case UDEV_CTRL_STOP_EXEC_QUEUE:
@@ -934,10 +930,11 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
}
log_debug("Received udev control message (SET_MAX_CHILDREN), setting children_max=%i", value->intval);
- manager->children_max = value->intval;
+ manager->config_by_control.children_max = value->intval;
/* When 0 is specified, determine the maximum based on the system resources. */
- manager_set_default_children_max(manager);
+ udev_config_set_default_children_max(&manager->config_by_control);
+ manager->config.children_max = manager->config_by_control.children_max;
notify_ready(manager);
break;
@@ -1174,10 +1171,11 @@ Manager* manager_new(void) {
*manager = (Manager) {
.inotify_fd = -EBADF,
.worker_watch = EBADF_PAIR,
- .log_level = LOG_INFO,
- .resolve_name_timing = RESOLVE_NAME_EARLY,
- .timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC,
- .timeout_signal = SIGKILL,
+ .config_by_udev_conf = UDEV_CONFIG_INIT,
+ .config_by_command = UDEV_CONFIG_INIT,
+ .config_by_kernel = UDEV_CONFIG_INIT,
+ .config_by_control = UDEV_CONFIG_INIT,
+ .config = UDEV_CONFIG_INIT,
};
return manager;
@@ -1258,8 +1256,6 @@ int manager_init(Manager *manager) {
(void) sd_device_monitor_set_description(manager->monitor, "manager");
- manager->log_level = log_get_max_level();
-
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
if (r < 0)
log_debug_errno(r, "Failed to get cgroup, ignoring: %m");
@@ -1365,7 +1361,7 @@ int manager_main(Manager *manager) {
udev_builtin_init();
- r = udev_rules_load(&manager->rules, manager->resolve_name_timing);
+ r = udev_rules_load(&manager->rules, manager->config.resolve_name_timing);
if (r < 0)
return log_error_errno(r, "Failed to read udev rules: %m");
diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h
index 14b458bcdb..13c7242ea8 100644
--- a/src/udev/udev-manager.h
+++ b/src/udev/udev-manager.h
@@ -9,6 +9,7 @@
#include "hashmap.h"
#include "macro.h"
#include "time-util.h"
+#include "udev-config.h"
#include "udev-ctrl.h"
#include "udev-def.h"
@@ -21,7 +22,6 @@ typedef struct Manager {
Hashmap *workers;
LIST_HEAD(Event, events);
char *cgroup;
- int log_level;
UdevRules *rules;
Hashmap *properties;
@@ -38,12 +38,11 @@ typedef struct Manager {
usec_t last_usec;
- ResolveNameTiming resolve_name_timing;
- unsigned children_max;
- usec_t exec_delay_usec;
- usec_t timeout_usec;
- int timeout_signal;
- bool blockdev_read_only;
+ UdevConfig config_by_udev_conf;
+ UdevConfig config_by_command;
+ UdevConfig config_by_kernel;
+ UdevConfig config_by_control;
+ UdevConfig config;
bool stop_exec_queue;
bool exit;
diff --git a/src/udev/udev-spawn.c b/src/udev/udev-spawn.c
index b95141cf21..2d0f6455a5 100644
--- a/src/udev/udev-spawn.c
+++ b/src/udev/udev-spawn.c
@@ -240,8 +240,8 @@ int udev_event_spawn(
return 0;
}
- int timeout_signal = event->worker ? event->worker->timeout_signal : SIGKILL;
- usec_t timeout_usec = event->worker ? event->worker->timeout_usec : DEFAULT_WORKER_TIMEOUT_USEC;
+ int timeout_signal = event->worker ? event->worker->config.timeout_signal : SIGKILL;
+ usec_t timeout_usec = event->worker ? event->worker->config.timeout_usec : DEFAULT_WORKER_TIMEOUT_USEC;
usec_t now_usec = now(CLOCK_MONOTONIC);
usec_t age_usec = usec_sub_unsigned(now_usec, event->birth_usec);
usec_t cmd_timeout_usec = usec_sub_unsigned(timeout_usec, age_usec);
@@ -349,20 +349,20 @@ void udev_event_execute_run(UdevEvent *event) {
if (r < 0)
log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command);
} else {
- if (event->worker && event->worker->exec_delay_usec > 0) {
+ if (event->worker && event->worker->config.exec_delay_usec > 0) {
usec_t now_usec = now(CLOCK_MONOTONIC);
usec_t age_usec = usec_sub_unsigned(now_usec, event->birth_usec);
- if (event->worker->exec_delay_usec >= usec_sub_unsigned(event->worker->timeout_usec, age_usec)) {
+ if (event->worker->config.exec_delay_usec >= usec_sub_unsigned(event->worker->config.timeout_usec, age_usec)) {
log_device_warning(event->dev,
"Cannot delay execution of \"%s\" for %s, skipping.",
- command, FORMAT_TIMESPAN(event->worker->exec_delay_usec, USEC_PER_SEC));
+ command, FORMAT_TIMESPAN(event->worker->config.exec_delay_usec, USEC_PER_SEC));
continue;
}
log_device_debug(event->dev, "Delaying execution of \"%s\" for %s.",
- command, FORMAT_TIMESPAN(event->worker->exec_delay_usec, USEC_PER_SEC));
- (void) usleep_safe(event->worker->exec_delay_usec);
+ command, FORMAT_TIMESPAN(event->worker->config.exec_delay_usec, USEC_PER_SEC));
+ (void) usleep_safe(event->worker->config.exec_delay_usec);
}
log_device_debug(event->dev, "Running command \"%s\"", command);
diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c
index 44287e4774..fc9072e5fd 100644
--- a/src/udev/udev-worker.c
+++ b/src/udev/udev-worker.c
@@ -195,7 +195,7 @@ static int worker_process_device(UdevWorker *worker, sd_device *dev) {
if (r < 0)
return r;
- if (worker->blockdev_read_only)
+ if (worker->config.blockdev_read_only)
(void) worker_mark_block_device_read_only(dev);
/* Disable watch during event processing. */
@@ -322,7 +322,7 @@ static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *
log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m");
/* Reset the log level, as it might be changed by "OPTIONS=log_level=". */
- log_set_max_level(worker->log_level);
+ log_set_max_level(worker->config.log_level);
return 1;
}
diff --git a/src/udev/udev-worker.h b/src/udev/udev-worker.h
index e9aefc5b04..d9dd88d472 100644
--- a/src/udev/udev-worker.h
+++ b/src/udev/udev-worker.h
@@ -10,6 +10,7 @@
#include "errno-list.h"
#include "hashmap.h"
#include "time-util.h"
+#include "udev-config.h"
#define DEFAULT_WORKER_TIMEOUT_USEC (3 * USEC_PER_MINUTE)
#define MIN_WORKER_TIMEOUT_USEC (1 * USEC_PER_MSEC)
@@ -27,11 +28,7 @@ typedef struct UdevWorker {
int pipe_fd;
int inotify_fd; /* Do not close! */
- usec_t exec_delay_usec;
- usec_t timeout_usec;
- int timeout_signal;
- int log_level;
- bool blockdev_read_only;
+ UdevConfig config;
} UdevWorker;
/* passed from worker to main process */

View File

@ -0,0 +1,136 @@
From 8224a238bb1ddd9328ba6d0c5aabb972dd49a06c Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 04:31:31 +0900
Subject: [PATCH] udev: reload .rules files and builtins only when necessary
Previously, even if e.g. .rules files are unchanged, all .rules files
are reloaded when other kind of config files like .link files or
.hwdb.bin are changed, vice versa.
(cherry picked from commit 0f72af536f957b5755551de5f1815baef8f377b7)
Resolves: RHEL-75774
---
src/udev/udev-builtin.c | 23 ++++++++++++++++++++---
src/udev/udev-builtin.h | 3 ++-
src/udev/udev-def.h | 23 +++++++++++++++++++++++
src/udev/udev-manager.c | 15 +++++++++------
4 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
index 2118c2f3df..3d22ddf945 100644
--- a/src/udev/udev-builtin.c
+++ b/src/udev/udev-builtin.c
@@ -54,11 +54,28 @@ void udev_builtin_exit(void) {
initialized = false;
}
-bool udev_builtin_should_reload(void) {
+UdevReloadFlags udev_builtin_should_reload(void) {
+ UdevReloadFlags flags = 0;
+
for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++)
if (builtins[i] && builtins[i]->should_reload && builtins[i]->should_reload())
- return true;
- return false;
+ flags |= 1u << i;
+
+ if (flags != 0)
+ flags |= UDEV_RELOAD_KILL_WORKERS;
+
+ return flags;
+}
+
+void udev_builtin_reload(UdevReloadFlags flags) {
+ for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++) {
+ if (!FLAGS_SET(flags, 1u << i) || !builtins[i])
+ continue;
+ if (builtins[i]->exit)
+ builtins[i]->exit();
+ if (builtins[i]->init)
+ builtins[i]->init();
+ }
}
void udev_builtin_list(void) {
diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h
index 8c2016e5f0..3b5f3bd120 100644
--- a/src/udev/udev-builtin.h
+++ b/src/udev/udev-builtin.h
@@ -59,7 +59,8 @@ const char* udev_builtin_name(UdevBuiltinCommand cmd);
bool udev_builtin_run_once(UdevBuiltinCommand cmd);
int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command);
void udev_builtin_list(void);
-bool udev_builtin_should_reload(void);
+UdevReloadFlags udev_builtin_should_reload(void);
+void udev_builtin_reload(UdevReloadFlags flags);
int udev_builtin_add_property(UdevEvent *event, const char *key, const char *val);
int udev_builtin_add_propertyf(UdevEvent *event, const char *key, const char *valf, ...) _printf_(3, 4);
int udev_builtin_import_property(UdevEvent *event, const char *key);
diff --git a/src/udev/udev-def.h b/src/udev/udev-def.h
index 6ff3feacec..9d9fc78247 100644
--- a/src/udev/udev-def.h
+++ b/src/udev/udev-def.h
@@ -55,3 +55,26 @@ typedef enum UdevBuiltinCommand {
_UDEV_BUILTIN_MAX,
_UDEV_BUILTIN_INVALID = -EINVAL,
} UdevBuiltinCommand;
+
+typedef enum UdevReloadFlags {
+#if HAVE_BLKID
+ UDEV_RELOAD_BUILTIN_BLKID = 1u << UDEV_BUILTIN_BLKID,
+#endif
+ UDEV_RELOAD_BUILTIN_BTRFS = 1u << UDEV_BUILTIN_BTRFS,
+ UDEV_RELOAD_BUILTIN_HWDB = 1u << UDEV_BUILTIN_HWDB,
+ UDEV_RELOAD_BUILTIN_INPUT_ID = 1u << UDEV_BUILTIN_INPUT_ID,
+ UDEV_RELOAD_BUILTIN_KEYBOARD = 1u << UDEV_BUILTIN_KEYBOARD,
+#if HAVE_KMOD
+ UDEV_RELOAD_BUILTIN_KMOD = 1u << UDEV_BUILTIN_KMOD,
+#endif
+ UDEV_RELOAD_BUILTIN_DRIVER = 1u << UDEV_BUILTIN_NET_DRIVER,
+ UDEV_RELOAD_BUILTIN_NET_ID = 1u << UDEV_BUILTIN_NET_ID,
+ UDEV_RELOAD_BUILTIN_NET_LINK = 1u << UDEV_BUILTIN_NET_LINK,
+ UDEV_RELOAD_BUILTIN_PATH_ID = 1u << UDEV_BUILTIN_PATH_ID,
+ UDEV_RELOAD_BUILTIN_USB_ID = 1u << UDEV_BUILTIN_USB_ID,
+#if HAVE_ACL
+ UDEV_RELOAD_BUILTIN_UACCESS = 1u << UDEV_BUILTIN_UACCESS,
+#endif
+ UDEV_RELOAD_KILL_WORKERS = 1u << (_UDEV_BUILTIN_MAX + 0),
+ UDEV_RELOAD_RULES = 1u << (_UDEV_BUILTIN_MAX + 1),
+} UdevReloadFlags;
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 7f7079bcd2..c691b8ebed 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -262,22 +262,25 @@ static void manager_reload(Manager *manager, bool force) {
/* Reload SELinux label database, to make the child inherit the up-to-date database. */
mac_selinux_maybe_reload();
- /* Nothing changed. It is not necessary to reload. */
- if (!udev_rules_should_reload(manager->rules) && !udev_builtin_should_reload()) {
-
+ UdevReloadFlags flags = udev_builtin_should_reload();
+ if (udev_rules_should_reload(manager->rules))
+ flags |= UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
+ if (flags == 0) {
+ /* Nothing changed. It is not necessary to reload. */
if (!force)
return;
/* If we eat this up, then tell our service manager to just continue */
(void) notify_reloading_full("Skipping configuration reloading, nothing changed.");
- } else {
+ } else
(void) notify_reloading();
+ if (FLAGS_SET(flags, UDEV_RELOAD_KILL_WORKERS))
manager_kill_workers(manager, false);
- udev_builtin_exit();
- udev_builtin_init();
+ udev_builtin_reload(flags);
+ if (FLAGS_SET(flags, UDEV_RELOAD_RULES)) {
r = udev_rules_load(&rules, manager->config.resolve_name_timing);
if (r < 0)
log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");

View File

@ -0,0 +1,87 @@
From 1ac71b3069f39c3b1e681eab90419ef500659cbe Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 04:29:13 +0900
Subject: [PATCH] udev: also reload udev.conf when explicitly requested
When reloading is explicitly requested, e.g. by 'udevadm control --reload',
then also reload udev.conf.
(cherry picked from commit e95861d909e17d56eddc20331a62f67f0d37d950)
Resolves: RHEL-75774
---
src/udev/udev-config.c | 24 ++++++++++++++++++++++++
src/udev/udev-config.h | 1 +
src/udev/udev-manager.c | 16 ++++++++--------
3 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c
index eced080547..891cf92535 100644
--- a/src/udev/udev-config.c
+++ b/src/udev/udev-config.c
@@ -339,3 +339,27 @@ int manager_load(Manager *manager, int argc, char *argv[]) {
manager_adjust_config(&manager->config);
return 1;
}
+
+UdevReloadFlags manager_reload_config(Manager *manager) {
+ assert(manager);
+
+ UdevConfig old = manager->config;
+
+ manager->config_by_udev_conf = UDEV_CONFIG_INIT;
+ manager_parse_udev_config(&manager->config_by_udev_conf);
+ manager_merge_config(manager);
+ log_set_max_level(manager->config.log_level);
+ manager_adjust_config(&manager->config);
+
+ if (manager->config.resolve_name_timing != old.resolve_name_timing)
+ return UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
+
+ if (manager->config.log_level != old.log_level ||
+ manager->config.exec_delay_usec != old.exec_delay_usec ||
+ manager->config.timeout_usec != old.timeout_usec ||
+ manager->config.timeout_signal != old.timeout_signal ||
+ manager->config.blockdev_read_only != old.blockdev_read_only)
+ return UDEV_RELOAD_KILL_WORKERS;
+
+ return 0;
+}
diff --git a/src/udev/udev-config.h b/src/udev/udev-config.h
index 3b0997eeb0..1c7a74b106 100644
--- a/src/udev/udev-config.h
+++ b/src/udev/udev-config.h
@@ -27,4 +27,5 @@ typedef struct UdevConfig {
}
int manager_load(Manager *manager, int argc, char *argv[]);
+UdevReloadFlags manager_reload_config(Manager *manager);
void udev_config_set_default_children_max(UdevConfig *c);
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index c691b8ebed..4fc316e106 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -265,15 +265,15 @@ static void manager_reload(Manager *manager, bool force) {
UdevReloadFlags flags = udev_builtin_should_reload();
if (udev_rules_should_reload(manager->rules))
flags |= UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
- if (flags == 0) {
- /* Nothing changed. It is not necessary to reload. */
- if (!force)
- return;
+ if (flags == 0 && !force)
+ /* Neither .rules files nor config files for builtins e.g. .link files changed. It is not
+ * necessary to reload configs. Note, udev.conf is not checked in the above, hence reloaded
+ * when explicitly requested or at least one .rules file or friend is updated. */
+ return;
- /* If we eat this up, then tell our service manager to just continue */
- (void) notify_reloading_full("Skipping configuration reloading, nothing changed.");
- } else
- (void) notify_reloading();
+ (void) notify_reloading();
+
+ flags |= manager_reload_config(manager);
if (FLAGS_SET(flags, UDEV_RELOAD_KILL_WORKERS))
manager_kill_workers(manager, false);

View File

@ -0,0 +1,61 @@
From 37735cbe018e1596c74ccca47acb4c1a96e82fc6 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 4 Dec 2024 06:34:43 +0900
Subject: [PATCH] TEST-17: use 'udevadm control --reload' or 'systemctl reload
systemd-udevd.service' for reloading udev.conf
These should be equivalent. For coverage, one subtest uses systemctl and
another uses udevadm.
(cherry picked from commit ced0ef3b35faadc5c8c07f6dd24f69bd836d8399)
Resolves: RHEL-75774
---
test/units/TEST-17-UDEV.03.sh | 4 ++--
test/units/TEST-17-UDEV.device_is_processing.sh | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/units/TEST-17-UDEV.03.sh b/test/units/TEST-17-UDEV.03.sh
index d6b3162258..56ecf49e3b 100755
--- a/test/units/TEST-17-UDEV.03.sh
+++ b/test/units/TEST-17-UDEV.03.sh
@@ -27,7 +27,7 @@ event_timeout=10
timeout_signal=SIGABRT
EOF
- systemctl restart systemd-udevd.service
+ systemctl reload systemd-udevd.service
}
# shellcheck disable=SC2317
@@ -40,7 +40,7 @@ teardown() {
rm -rf "$TMPDIR"
rm -f "$TEST_RULE" "$TEST_CONF"
- systemctl restart systemd-udevd.service
+ systemctl reload systemd-udevd.service
}
run_test_timeout() {
diff --git a/test/units/TEST-17-UDEV.device_is_processing.sh b/test/units/TEST-17-UDEV.device_is_processing.sh
index 88e4b5a6bd..d3b48e780e 100755
--- a/test/units/TEST-17-UDEV.device_is_processing.sh
+++ b/test/units/TEST-17-UDEV.device_is_processing.sh
@@ -18,7 +18,7 @@ at_exit() {
# Forcibly kills sleep command invoked by the udev rule before restarting,
# otherwise systemctl restart below will takes longer.
killall -KILL sleep
- systemctl restart systemd-udevd.service
+ udevadm control --reload
ip link del "$IFNAME"
}
@@ -36,7 +36,7 @@ cat >/run/udev/rules.d/99-testsuite.rules <<EOF
SUBSYSTEM=="net", ACTION=="change", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000"
EOF
-systemctl restart systemd-udevd.service
+udevadm control --reload
ip link add "$IFNAME" type dummy
IFINDEX=$(ip -json link show "$IFNAME" | jq '.[].ifindex')

View File

@ -0,0 +1,45 @@
From 858ec72ef75569f4febb7ea95d433a9414faff0b Mon Sep 17 00:00:00 2001
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
Date: Thu, 26 Dec 2024 11:02:55 +0100
Subject: [PATCH] udevd: add missing header for glibc < 2.34
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
```
[77/1697] Compiling C object udevadm.p/src_udev_udevd.c.o
FAILED: udevadm.p/src_udev_udevd.c.o
cc -Iudevadm.p -I. -I.. -Isrc/basic -I../src/basic -Isrc/fundamental -I../src/fundamental -Isrc/systemd -I../src/systemd -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-journal -I../src/libsystemd/sd-json -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-path -I../src/libsystemd/sd-resolve -I../src/libsystemd/sd-varlink -Isrc/shared -I../src/shared -I/usr/include/blkid -I/usr/include/kmod -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu11 -O0 -g -Wno-missing-field-initializers -Wno-unused-parameter -Wno-nonnull-compare -Warray-bounds -Warray-bounds=2 -Wdate-time -Wendif-labels -Werror=format=2 -Werror=format-signedness -Werror=implicit-function-declaration -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Werror=missing-declarations -Werror=missing-prototypes -Werror=overflow -Werror=override-init -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=undef -Wfloat-equal -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-aliasing=2 -Wstrict-prototypes -Wsuggest-attribute=noreturn -Wunused-function -Wwrite-strings -Wzero-length-bounds -fdiagnostics-show-option -fno-common -fstack-protector -fstack-protector-strong --param=ssp-buffer-size=4 -Wno-unused-result -Werror=shadow -fno-strict-aliasing -fvisibility=hidden -fno-omit-frame-pointer -include config.h -pthread -MD -MQ udevadm.p/src_udev_udevd.c.o -MF udevadm.p/src_udev_udevd.c.o.d -o udevadm.p/src_udev_udevd.c.o -c ../src/udev/udevd.c
../src/udev/udevd.c: In function run_udevd:
../src/udev/udevd.c:67:23: error: implicit declaration of function fork [-Werror=implicit-function-declaration]
67 | pid = fork();
| ^~~~
../src/udev/udevd.c:75:24: error: implicit declaration of function setsid; did you mean setbit? [-Werror=implicit-function-declaration]
75 | (void) setsid();
| ^~~~~~
| setbit
../src/udev/udevd.c:75:24: warning: nested extern declaration of setsid [-Wnested-externs]
```
Follow-up for 394a678aec3b8bba0f0b1a8d7b9427c62468fe68
(cherry picked from commit 7cb72bdaeba6069eca99a4292b26dc5eb81bb67a)
Resolves: RHEL-75774
---
src/udev/udevd.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 018a3cd6e7..8f0e5cc0d6 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -5,6 +5,8 @@
* Copyright © 2009 Scott James Remnant <scott@netsplit.com>
*/
+#include <unistd.h>
+
#include "errno-util.h"
#include "fd-util.h"
#include "mkdir.h"

View File

@ -0,0 +1,50 @@
From b2c1e85214ee2d0d483ff54b0afade9738327c0d Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 22 Dec 2024 01:36:54 +0900
Subject: [PATCH] meson: sort source files
(cherry picked from commit 8567f1342bbaaacfc08e18513c943b3586ea4a6e)
Resolves: RHEL-75774
---
src/udev/meson.build | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/udev/meson.build b/src/udev/meson.build
index d7acbae6bb..54e12a45e4 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -19,16 +19,6 @@ udevadm_sources = files(
libudevd_core_sources = files(
'net/link-config.c',
- 'udev-config.c',
- 'udev-ctrl.c',
- 'udev-event.c',
- 'udev-format.c',
- 'udev-manager.c',
- 'udev-node.c',
- 'udev-rules.c',
- 'udev-spawn.c',
- 'udev-watch.c',
- 'udev-worker.c',
'udev-builtin-btrfs.c',
'udev-builtin-hwdb.c',
'udev-builtin-input_id.c',
@@ -39,6 +29,16 @@ libudevd_core_sources = files(
'udev-builtin-path_id.c',
'udev-builtin-usb_id.c',
'udev-builtin.c',
+ 'udev-config.c',
+ 'udev-ctrl.c',
+ 'udev-event.c',
+ 'udev-format.c',
+ 'udev-manager.c',
+ 'udev-node.c',
+ 'udev-rules.c',
+ 'udev-spawn.c',
+ 'udev-watch.c',
+ 'udev-worker.c',
)
if conf.get('HAVE_KMOD') == 1

View File

@ -0,0 +1,107 @@
From 4c3468fa6ab0a993f4bc15b503061bbbeedd19e7 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 4 Jan 2025 13:57:30 +0900
Subject: [PATCH] sd-json: introduce json_dispatch_log_level()
Then, use it in io.systemd.service.SetLogLevel method.
(cherry picked from commit 93081be64b858afea32079a8b32212a36b64de84)
Resolves: RHEL-75774
---
src/libsystemd/sd-json/json-util.c | 20 ++++++++++++++++++++
src/libsystemd/sd-json/json-util.h | 1 +
src/shared/varlink-io.systemd.service.c | 12 ++++--------
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/libsystemd/sd-json/json-util.c b/src/libsystemd/sd-json/json-util.c
index 67e50e6c51..1b22084d40 100644
--- a/src/libsystemd/sd-json/json-util.c
+++ b/src/libsystemd/sd-json/json-util.c
@@ -327,6 +327,26 @@ int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_di
return 0;
}
+int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
+ int *log_level = ASSERT_PTR(userdata), r, t;
+
+ if (sd_json_variant_is_null(variant)) {
+ *log_level = -1;
+ return 0;
+ }
+
+ r = sd_json_dispatch_int(name, variant, flags, &t);
+ if (r < 0)
+ return r;
+
+ /* If SD_JSON_RELAX is set allow a zero interface index, otherwise refuse. */
+ if (LOG_PRI(t) != t)
+ return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid log level.", strna(name));
+
+ *log_level = t;
+ return 0;
+}
+
int json_variant_new_devnum(sd_json_variant **ret, dev_t devnum) {
if (devnum == 0)
return sd_json_variant_new_null(ret);
diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h
index b3b4941dcc..9a2b7b5ff2 100644
--- a/src/libsystemd/sd-json/json-util.h
+++ b/src/libsystemd/sd-json/json-util.h
@@ -119,6 +119,7 @@ int json_dispatch_path(const char *name, sd_json_variant *variant, sd_json_dispa
int json_dispatch_pidref(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_devnum(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
+int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_strv_environment(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
static inline int json_variant_unbase64_iovec(sd_json_variant *v, struct iovec *ret) {
diff --git a/src/shared/varlink-io.systemd.service.c b/src/shared/varlink-io.systemd.service.c
index 666778bd41..62cfc9b637 100644
--- a/src/shared/varlink-io.systemd.service.c
+++ b/src/shared/varlink-io.systemd.service.c
@@ -2,7 +2,7 @@
#include <unistd.h>
-#include "macro.h"
+#include "json-util.h"
#include "varlink-io.systemd.service.h"
static SD_VARLINK_DEFINE_METHOD(Ping);
@@ -33,13 +33,12 @@ int varlink_method_ping(sd_varlink *link, sd_json_variant *parameters, sd_varlin
int varlink_method_set_log_level(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
static const sd_json_dispatch_field dispatch_table[] = {
- { "level", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int64, 0, SD_JSON_MANDATORY },
+ { "level", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_log_level, 0, SD_JSON_MANDATORY },
{}
};
- int64_t level;
+ int r, level;
uid_t uid;
- int r;
assert(link);
assert(parameters);
@@ -53,9 +52,6 @@ int varlink_method_set_log_level(sd_varlink *link, sd_json_variant *parameters,
if (r != 0)
return r;
- if (LOG_PRI(level) != level)
- return sd_varlink_error_invalid_parameter(link, parameters);
-
r = sd_varlink_get_peer_uid(link, &uid);
if (r < 0)
return r;
@@ -63,7 +59,7 @@ int varlink_method_set_log_level(sd_varlink *link, sd_json_variant *parameters,
if (uid != getuid() && uid != 0)
return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, parameters);
- log_debug("Received io.systemd.service.SetLogLevel(%" PRIi64 ")", level);
+ log_debug("Received io.systemd.service.SetLogLevel(%i)", level);
log_set_max_level(level);

View File

@ -0,0 +1,25 @@
From 2f84b078931b287b117c4aa3e21aa8a30b8fcd9b Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 22 Dec 2024 01:34:04 +0900
Subject: [PATCH] varlink: invert uid check to reduce call of getuid()
(cherry picked from commit 4ea611b8a4fa42bc782e2dc5d9c0bb470bb91683)
Resolves: RHEL-75774
---
src/shared/varlink-io.systemd.service.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/varlink-io.systemd.service.c b/src/shared/varlink-io.systemd.service.c
index 62cfc9b637..06e32f9bf6 100644
--- a/src/shared/varlink-io.systemd.service.c
+++ b/src/shared/varlink-io.systemd.service.c
@@ -56,7 +56,7 @@ int varlink_method_set_log_level(sd_varlink *link, sd_json_variant *parameters,
if (r < 0)
return r;
- if (uid != getuid() && uid != 0)
+ if (uid != 0 && uid != getuid())
return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, parameters);
log_debug("Received io.systemd.service.SetLogLevel(%i)", level);

View File

@ -0,0 +1,118 @@
From 30c1127bfa58f94c98e2fc5a10bc6c272c72d017 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 22 Dec 2024 03:34:43 +0900
Subject: [PATCH] string-util: modernize split_pair()
- use _cleanup_free_ attribute,
- rename output arguments,
- trigger assertion when an empty separator is passed.
(cherry picked from commit ac3f3026a99772fbe8d485b56de0a5819513a2c1)
Resolves: RHEL-75774
---
src/basic/string-util.c | 28 ++++++++++------------------
src/basic/string-util.h | 2 +-
src/test/test-string-util.c | 23 ++++++++++++-----------
3 files changed, 23 insertions(+), 30 deletions(-)
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 171a368059..7122d5145e 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -1044,34 +1044,26 @@ char* strrep(const char *s, unsigned n) {
return r;
}
-int split_pair(const char *s, const char *sep, char **l, char **r) {
- char *x, *a, *b;
-
+int split_pair(const char *s, const char *sep, char **ret_first, char **ret_second) {
assert(s);
- assert(sep);
- assert(l);
- assert(r);
-
- if (isempty(sep))
- return -EINVAL;
+ assert(!isempty(sep));
+ assert(ret_first);
+ assert(ret_second);
- x = strstr(s, sep);
+ const char *x = strstr(s, sep);
if (!x)
return -EINVAL;
- a = strndup(s, x - s);
+ _cleanup_free_ char *a = strndup(s, x - s);
if (!a)
return -ENOMEM;
- b = strdup(x + strlen(sep));
- if (!b) {
- free(a);
+ _cleanup_free_ char *b = strdup(x + strlen(sep));
+ if (!b)
return -ENOMEM;
- }
-
- *l = a;
- *r = b;
+ *ret_first = TAKE_PTR(a);
+ *ret_second = TAKE_PTR(b);
return 0;
}
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index cc6aa183c0..a1592b6e6d 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -214,7 +214,7 @@ char* strrep(const char *s, unsigned n);
_d_; \
})
-int split_pair(const char *s, const char *sep, char **l, char **r);
+int split_pair(const char *s, const char *sep, char **ret_first, char **ret_second);
int free_and_strdup(char **p, const char *s);
static inline int free_and_strdup_warn(char **p, const char *s) {
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index 999d3bacb8..b692af6cc0 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -572,21 +572,22 @@ TEST(in_charset) {
TEST(split_pair) {
_cleanup_free_ char *a = NULL, *b = NULL;
- assert_se(split_pair("", "", &a, &b) == -EINVAL);
- assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
- assert_se(split_pair("", "=", &a, &b) == -EINVAL);
- assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
+ ASSERT_SIGNAL(split_pair("", NULL, &a, &b), SIGABRT);
+ ASSERT_SIGNAL(split_pair("", "", &a, &b), SIGABRT);
+ ASSERT_SIGNAL(split_pair("foo=bar", "", &a, &b), SIGABRT);
+ ASSERT_SIGNAL(split_pair(NULL, "=", &a, &b), SIGABRT);
+ ASSERT_ERROR(split_pair("", "=", &a, &b), EINVAL);
+ ASSERT_OK(split_pair("foo=bar", "=", &a, &b));
ASSERT_STREQ(a, "foo");
ASSERT_STREQ(b, "bar");
- free(a);
- free(b);
- assert_se(split_pair("==", "==", &a, &b) >= 0);
+ a = mfree(a);
+ b = mfree(b);
+ ASSERT_OK(split_pair("==", "==", &a, &b));
ASSERT_STREQ(a, "");
ASSERT_STREQ(b, "");
- free(a);
- free(b);
-
- assert_se(split_pair("===", "==", &a, &b) >= 0);
+ a = mfree(a);
+ b = mfree(b);
+ ASSERT_OK(split_pair("===", "==", &a, &b));
ASSERT_STREQ(a, "");
ASSERT_STREQ(b, "=");
}

View File

@ -0,0 +1,310 @@
From b6876d46a4695c0626db089170ea28cb263d3cdb Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 22 Dec 2024 00:11:38 +0900
Subject: [PATCH] udev: split manager_init() and manager_main() into small
pieces
No functional change, just refactoring.
Co-authored-by: David Tardon <dtardon@redhat.com>
(cherry picked from commit 0079651876aa5df73fd787b272e91ae4a7898853)
Resolves: RHEL-75774
---
src/udev/udev-manager.c | 217 +++++++++++++++++++++++++++++-----------
1 file changed, 161 insertions(+), 56 deletions(-)
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 4fc316e106..d9bd9d6d7b 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -1232,32 +1232,66 @@ static int listen_fds(int *ret_ctrl, int *ret_netlink) {
return 0;
}
-int manager_init(Manager *manager) {
- _cleanup_close_ int fd_ctrl = -EBADF, fd_uevent = -EBADF;
- _cleanup_free_ char *cgroup = NULL;
+static int manager_init_ctrl(Manager *manager, int fd_ctrl) {
+ _cleanup_(udev_ctrl_unrefp) UdevCtrl *ctrl = NULL;
+ _cleanup_close_ int fd = fd_ctrl;
int r;
assert(manager);
- r = listen_fds(&fd_ctrl, &fd_uevent);
- if (r < 0)
- return log_error_errno(r, "Failed to listen on fds: %m");
+ /* This consumes passed file descriptor. */
- r = udev_ctrl_new_from_fd(&manager->ctrl, fd_ctrl);
+ r = udev_ctrl_new_from_fd(&ctrl, fd);
if (r < 0)
return log_error_errno(r, "Failed to initialize udev control socket: %m");
- TAKE_FD(fd_ctrl);
+ TAKE_FD(fd);
- r = udev_ctrl_enable_receiving(manager->ctrl);
+ r = udev_ctrl_enable_receiving(ctrl);
if (r < 0)
return log_error_errno(r, "Failed to bind udev control socket: %m");
- r = device_monitor_new_full(&manager->monitor, MONITOR_GROUP_KERNEL, fd_uevent);
+ manager->ctrl = TAKE_PTR(ctrl);
+ return 0;
+}
+
+static int manager_init_device_monitor(Manager *manager, int fd_uevent) {
+ _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
+ _cleanup_close_ int fd = fd_uevent;
+ int r;
+
+ assert(manager);
+
+ /* This consumes passed file descriptor. */
+
+ r = device_monitor_new_full(&monitor, MONITOR_GROUP_KERNEL, fd);
if (r < 0)
return log_error_errno(r, "Failed to initialize device monitor: %m");
- TAKE_FD(fd_uevent);
+ TAKE_FD(fd);
+
+ (void) sd_device_monitor_set_description(monitor, "manager");
+
+ manager->monitor = TAKE_PTR(monitor);
+ return 0;
+}
- (void) sd_device_monitor_set_description(manager->monitor, "manager");
+int manager_init(Manager *manager) {
+ _cleanup_close_ int fd_ctrl = -EBADF, fd_uevent = -EBADF;
+ _cleanup_free_ char *cgroup = NULL;
+ int r;
+
+ assert(manager);
+
+ r = listen_fds(&fd_ctrl, &fd_uevent);
+ if (r < 0)
+ return log_error_errno(r, "Failed to listen on fds: %m");
+
+ r = manager_init_ctrl(manager, TAKE_FD(fd_ctrl));
+ if (r < 0)
+ return r;
+
+ r = manager_init_device_monitor(manager, TAKE_FD(fd_uevent));
+ if (r < 0)
+ return r;
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
if (r < 0)
@@ -1270,95 +1304,166 @@ int manager_init(Manager *manager) {
return 0;
}
-int manager_main(Manager *manager) {
- int fd_worker, r;
+static int manager_start_ctrl(Manager *manager) {
+ int r;
+
+ assert(manager);
+ assert(manager->ctrl);
+
+ r = udev_ctrl_attach_event(manager->ctrl, manager->event);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach event to udev control: %m");
+
+ r = udev_ctrl_start(manager->ctrl, on_ctrl_msg, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start udev control: %m");
+
+ /* This needs to be after the inotify and uevent handling, to make sure that the ping is send back
+ * after fully processing the pending uevents (including the synthetic ones we may create due to
+ * inotify events). */
+ r = sd_event_source_set_priority(udev_ctrl_get_event_source(manager->ctrl), SD_EVENT_PRIORITY_IDLE);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set IDLE event priority for udev control event source: %m");
+
+ return 0;
+}
+
+static int manager_start_device_monitor(Manager *manager) {
+ int r;
+
+ assert(manager);
+ assert(manager->monitor);
+
+ r = sd_device_monitor_attach_event(manager->monitor, manager->event);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach event to device monitor: %m");
+
+ r = sd_device_monitor_start(manager->monitor, on_uevent, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start device monitor: %m");
+
+ return 0;
+}
+
+static int manager_start_inotify(Manager *manager) {
+ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
+ _cleanup_close_ int fd = -EBADF;
+ int r;
+
+ assert(manager);
+ assert(manager->event);
+
+ fd = inotify_init1(IN_CLOEXEC);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to create inotify descriptor: %m");
+
+ udev_watch_restore(fd);
+
+ r = sd_event_add_io(manager->event, &s, fd, EPOLLIN, on_inotify, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create inotify event source: %m");
+
+ (void) sd_event_source_set_description(s, "manager-inotify");
+
+ manager->inotify_fd = TAKE_FD(fd);
+ manager->inotify_event = TAKE_PTR(s);
+ return 0;
+}
+
+static int manager_start_worker_event(Manager *manager) {
+ int r;
+
+ assert(manager);
+ assert(manager->event);
/* unnamed socket from workers to the main daemon */
r = socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
if (r < 0)
return log_error_errno(errno, "Failed to create socketpair for communicating with workers: %m");
- fd_worker = manager->worker_watch[READ_END];
-
- r = setsockopt_int(fd_worker, SOL_SOCKET, SO_PASSCRED, true);
+ r = setsockopt_int(manager->worker_watch[READ_END], SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "Failed to enable SO_PASSCRED: %m");
- manager->inotify_fd = inotify_init1(IN_CLOEXEC);
- if (manager->inotify_fd < 0)
- return log_error_errno(errno, "Failed to create inotify descriptor: %m");
+ r = sd_event_add_io(manager->event, NULL, manager->worker_watch[READ_END], EPOLLIN, on_worker, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create worker event source: %m");
- udev_watch_restore(manager->inotify_fd);
+ return 0;
+}
+
+static int manager_setup_event(Manager *manager) {
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+ int r;
+
+ assert(manager);
/* block SIGCHLD for listening child events. */
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
- r = sd_event_default(&manager->event);
+ r = sd_event_default(&e);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
+ r = sd_event_add_signal(e, /* ret_event_source = */ NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGINT event source: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
+ r = sd_event_add_signal(e, /* ret_event_source = */ NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGTERM event source: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, on_sighup, manager);
+ r = sd_event_add_signal(e, /* ret_event_source = */ NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, on_sighup, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGHUP event source: %m");
- r = sd_event_set_watchdog(manager->event, true);
+ r = sd_event_add_post(e, /* ret_event_source = */ NULL, on_post, manager);
if (r < 0)
- return log_error_errno(r, "Failed to create watchdog event source: %m");
+ return log_error_errno(r, "Failed to create post event source: %m");
- r = udev_ctrl_attach_event(manager->ctrl, manager->event);
+ /* Eventually, we probably want to do more here on memory pressure, for example, kill idle workers immediately */
+ r = sd_event_add_memory_pressure(e, /* ret_event_source= */ NULL, /* callback= */ NULL, /* userdata= */ NULL);
if (r < 0)
- return log_error_errno(r, "Failed to attach event to udev control: %m");
+ log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to allocate memory pressure watch, ignoring: %m");
- r = udev_ctrl_start(manager->ctrl, on_ctrl_msg, manager);
+ r = sd_event_add_signal(e, /* ret_event_source= */ NULL,
+ (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, /* userdata= */ NULL);
if (r < 0)
- return log_error_errno(r, "Failed to start udev control: %m");
+ return log_error_errno(r, "Failed to allocate SIGRTMIN+18 event source, ignoring: %m");
- /* This needs to be after the inotify and uevent handling, to make sure
- * that the ping is send back after fully processing the pending uevents
- * (including the synthetic ones we may create due to inotify events).
- */
- r = sd_event_source_set_priority(udev_ctrl_get_event_source(manager->ctrl), SD_EVENT_PRIORITY_IDLE);
+ r = sd_event_set_watchdog(e, true);
if (r < 0)
- return log_error_errno(r, "Failed to set IDLE event priority for udev control event source: %m");
+ return log_error_errno(r, "Failed to create watchdog event source: %m");
- r = sd_event_add_io(manager->event, &manager->inotify_event, manager->inotify_fd, EPOLLIN, on_inotify, manager);
- if (r < 0)
- return log_error_errno(r, "Failed to create inotify event source: %m");
+ manager->event = TAKE_PTR(e);
+ return 0;
+}
- r = sd_device_monitor_attach_event(manager->monitor, manager->event);
- if (r < 0)
- return log_error_errno(r, "Failed to attach event to device monitor: %m");
+int manager_main(Manager *manager) {
+ int r;
- r = sd_device_monitor_start(manager->monitor, on_uevent, manager);
+ assert(manager);
+
+ r = manager_setup_event(manager);
if (r < 0)
- return log_error_errno(r, "Failed to start device monitor: %m");
+ return r;
- r = sd_event_add_io(manager->event, NULL, fd_worker, EPOLLIN, on_worker, manager);
+ r = manager_start_ctrl(manager);
if (r < 0)
- return log_error_errno(r, "Failed to create worker event source: %m");
+ return r;
- r = sd_event_add_post(manager->event, NULL, on_post, manager);
+ r = manager_start_device_monitor(manager);
if (r < 0)
- return log_error_errno(r, "Failed to create post event source: %m");
+ return r;
- /* Eventually, we probably want to do more here on memory pressure, for example, kill idle workers immediately */
- r = sd_event_add_memory_pressure(manager->event, /* ret_event_source= */ NULL, /* callback= */ NULL, /* userdata= */ NULL);
+ r = manager_start_inotify(manager);
if (r < 0)
- log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to allocate memory pressure watch, ignoring: %m");
+ return r;
- r = sd_event_add_signal(manager->event, /* ret_event_source= */ NULL,
- (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, /* userdata= */ NULL);
+ r = manager_start_worker_event(manager);
if (r < 0)
- return log_error_errno(r, "Failed to allocate SIGRTMIN+18 event source, ignoring: %m");
+ return r;
manager->last_usec = now(CLOCK_MONOTONIC);

View File

@ -0,0 +1,262 @@
From d03f5018a7015594b9af864779a3e06d0f407192 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 22 Dec 2024 01:48:37 +0900
Subject: [PATCH] udev-config: split on_ctrl_msg() into small pieces
No functional change, just refactroing and preparation for later
commits.
(cherry picked from commit b358833ee91551d5d70a4fd754187a0259e2c62f)
Resolves: RHEL-75774
---
src/udev/udev-config.c | 78 ++++++++++++++++++++++++++++++++++++++++-
src/udev/udev-config.h | 5 ++-
src/udev/udev-manager.c | 59 ++++---------------------------
src/udev/udev-manager.h | 4 +++
4 files changed, 91 insertions(+), 55 deletions(-)
diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c
index 891cf92535..d511691ab2 100644
--- a/src/udev/udev-config.c
+++ b/src/udev/udev-config.c
@@ -271,7 +271,7 @@ static void manager_merge_config(Manager *manager) {
MERGE_BOOL(blockdev_read_only);
}
-void udev_config_set_default_children_max(UdevConfig *config) {
+static void udev_config_set_default_children_max(UdevConfig *config) {
uint64_t cpu_limit, mem_limit, cpu_count = 1;
int r;
@@ -293,6 +293,30 @@ void udev_config_set_default_children_max(UdevConfig *config) {
log_debug("Set children_max to %u", config->children_max);
}
+void manager_set_children_max(Manager *manager, unsigned n) {
+ assert(manager);
+
+ manager->config_by_control.children_max = n;
+ /* When 0 is specified, determine the maximum based on the system resources. */
+ udev_config_set_default_children_max(&manager->config_by_control);
+ manager->config.children_max = manager->config_by_control.children_max;
+
+ notify_ready(manager);
+}
+
+void manager_set_log_level(Manager *manager, int log_level) {
+ assert(manager);
+ assert(LOG_PRI(log_level) == log_level);
+
+ int old = log_get_max_level();
+
+ log_set_max_level(log_level);
+ manager->config.log_level = manager->config_by_control.log_level = log_level;
+
+ if (log_level != old)
+ manager_kill_workers(manager, /* force = */ false);
+}
+
static void manager_adjust_config(UdevConfig *config) {
assert(config);
@@ -315,6 +339,58 @@ static void manager_adjust_config(UdevConfig *config) {
udev_config_set_default_children_max(config);
}
+static int manager_set_environment_one(Manager *manager, const char *s) {
+ int r;
+
+ assert(manager);
+ assert(s);
+
+ _cleanup_free_ char *key = NULL, *value = NULL;
+ r = split_pair(s, "=", &key, &value);
+ if (r < 0)
+ return r;
+
+ if (isempty(value)) {
+ _cleanup_free_ char *old_key = NULL, *old_value = NULL;
+ old_value = hashmap_remove2(manager->properties, key, (void**) &old_key);
+ return !!old_value;
+ }
+
+ if (streq_ptr(value, hashmap_get(manager->properties, key)))
+ return 0;
+
+ _cleanup_free_ char *old_key = NULL, *old_value = NULL;
+ old_value = hashmap_get2(manager->properties, key, (void**) &old_key);
+
+ r = hashmap_ensure_replace(&manager->properties, &string_hash_ops, key, value);
+ if (r < 0) {
+ assert(!old_key);
+ assert(!old_value);
+ return r;
+ }
+
+ TAKE_PTR(key);
+ TAKE_PTR(value);
+ return 1;
+}
+
+void manager_set_environment(Manager *manager, char * const *v) {
+ bool changed = false;
+ int r;
+
+ assert(manager);
+
+ STRV_FOREACH(s, v) {
+ r = manager_set_environment_one(manager, *s);
+ if (r < 0)
+ log_debug_errno(r, "Failed to update environment '%s', ignoring: %m", *s);
+ changed = changed || r > 0;
+ }
+
+ if (changed)
+ manager_kill_workers(manager, /* force = */ false);
+}
+
int manager_load(Manager *manager, int argc, char *argv[]) {
int r;
diff --git a/src/udev/udev-config.h b/src/udev/udev-config.h
index 1c7a74b106..68bb1ea98c 100644
--- a/src/udev/udev-config.h
+++ b/src/udev/udev-config.h
@@ -26,6 +26,9 @@ typedef struct UdevConfig {
.resolve_name_timing = _RESOLVE_NAME_TIMING_INVALID, \
}
+void manager_set_children_max(Manager *manager, unsigned n);
+void manager_set_log_level(Manager *manager, int log_level);
+void manager_set_environment(Manager *manager, char * const *v);
+
int manager_load(Manager *manager, int argc, char *argv[]);
UdevReloadFlags manager_reload_config(Manager *manager);
-void udev_config_set_default_children_max(UdevConfig *c);
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index d9bd9d6d7b..2c87e8bb9e 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -194,7 +194,7 @@ static int worker_new(Worker **ret, Manager *manager, sd_device_monitor *worker_
return 0;
}
-static void manager_kill_workers(Manager *manager, bool force) {
+void manager_kill_workers(Manager *manager, bool force) {
Worker *worker;
assert(manager);
@@ -233,7 +233,7 @@ static void manager_exit(Manager *manager) {
manager_kill_workers(manager, true);
}
-static void notify_ready(Manager *manager) {
+void notify_ready(Manager *manager) {
int r;
assert(manager);
@@ -844,7 +844,6 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
/* receive the udevd message from userspace */
static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) {
Manager *manager = ASSERT_PTR(userdata);
- int r;
assert(value);
@@ -857,13 +856,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
log_debug("Received udev control message (SET_LOG_LEVEL), setting log_level=%i", value->intval);
- r = log_get_max_level();
- if (r == value->intval)
- break;
-
- log_set_max_level(value->intval);
- manager->config.log_level = manager->config_by_control.log_level = value->intval;
- manager_kill_workers(manager, false);
+ manager_set_log_level(manager, value->intval);
break;
case UDEV_CTRL_STOP_EXEC_QUEUE:
log_debug("Received udev control message (STOP_EXEC_QUEUE)");
@@ -879,8 +872,6 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
manager_reload(manager, /* force = */ true);
break;
case UDEV_CTRL_SET_ENV: {
- _unused_ _cleanup_free_ char *old_val = NULL, *old_key = NULL;
- _cleanup_free_ char *key = NULL, *val = NULL;
const char *eq;
eq = strchr(value->buf, '=');
@@ -889,41 +880,8 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
return 1;
}
- key = strndup(value->buf, eq - value->buf);
- if (!key) {
- log_oom();
- return 1;
- }
-
- old_val = hashmap_remove2(manager->properties, key, (void **) &old_key);
-
- r = hashmap_ensure_allocated(&manager->properties, &string_hash_ops);
- if (r < 0) {
- log_oom();
- return 1;
- }
-
- eq++;
- if (isempty(eq))
- log_debug("Received udev control message (ENV), unsetting '%s'", key);
- else {
- val = strdup(eq);
- if (!val) {
- log_oom();
- return 1;
- }
-
- log_debug("Received udev control message (ENV), setting '%s=%s'", key, val);
-
- r = hashmap_put(manager->properties, key, val);
- if (r < 0) {
- log_oom();
- return 1;
- }
- }
-
- key = val = NULL;
- manager_kill_workers(manager, false);
+ log_debug("Received udev control message(SET_ENV, %s)", value->buf);
+ manager_set_environment(manager, STRV_MAKE(value->buf));
break;
}
case UDEV_CTRL_SET_CHILDREN_MAX:
@@ -933,13 +891,8 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
}
log_debug("Received udev control message (SET_MAX_CHILDREN), setting children_max=%i", value->intval);
- manager->config_by_control.children_max = value->intval;
-
- /* When 0 is specified, determine the maximum based on the system resources. */
- udev_config_set_default_children_max(&manager->config_by_control);
- manager->config.children_max = manager->config_by_control.children_max;
- notify_ready(manager);
+ manager_set_children_max(manager, value->intval);
break;
case UDEV_CTRL_PING:
log_debug("Received udev control message (PING)");
diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h
index 13c7242ea8..05f9a8b709 100644
--- a/src/udev/udev-manager.h
+++ b/src/udev/udev-manager.h
@@ -55,4 +55,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
int manager_init(Manager *manager);
int manager_main(Manager *manager);
+void notify_ready(Manager *manager);
+
+void manager_kill_workers(Manager *manager, bool force);
+
bool devpath_conflict(const char *a, const char *b);

Some files were not shown because too many files have changed in this diff Show More