diff --git a/SOURCES/0228-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch b/SOURCES/0228-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch new file mode 100644 index 0000000000000000000000000000000000000000..8635997098733315117b3f6ad718489ec7ddf9e8 --- /dev/null +++ b/SOURCES/0228-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch @@ -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); + } diff --git a/SOURCES/0229-bootctl-fix-potential-uninitialized-memory-access.patch b/SOURCES/0229-bootctl-fix-potential-uninitialized-memory-access.patch new file mode 100644 index 0000000000000000000000000000000000000000..e24e0a64ec15e57ae722ad1a5556825bab55022c --- /dev/null +++ b/SOURCES/0229-bootctl-fix-potential-uninitialized-memory-access.patch @@ -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"); diff --git a/SOURCES/0230-bootctl-also-shown-whether-stub-loader-partition-dat.patch b/SOURCES/0230-bootctl-also-shown-whether-stub-loader-partition-dat.patch new file mode 100644 index 0000000000000000000000000000000000000000..f997b7c8d37a89dcb7fc8be7dbba225013665a4c --- /dev/null +++ b/SOURCES/0230-bootctl-also-shown-whether-stub-loader-partition-dat.patch @@ -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)) && diff --git a/SOURCES/0231-bootctl-suppress-output-of-empty-partition-info-if-w.patch b/SOURCES/0231-bootctl-suppress-output-of-empty-partition-info-if-w.patch new file mode 100644 index 0000000000000000000000000000000000000000..bfb5df8793e4f4cb72a8e1515f8fcad3ccf17aa8 --- /dev/null +++ b/SOURCES/0231-bootctl-suppress-output-of-empty-partition-info-if-w.patch @@ -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"); + } + diff --git a/SOURCES/0232-bootctl-minor-reordering-of-fields-in-output.patch b/SOURCES/0232-bootctl-minor-reordering-of-fields-in-output.patch new file mode 100644 index 0000000000000000000000000000000000000000..4b7b6f7ec038b69f2ab837092d92ef783227e161 --- /dev/null +++ b/SOURCES/0232-bootctl-minor-reordering-of-fields-in-output.patch @@ -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"); + } + diff --git a/SOURCES/0233-missing_sched-add-CLONE_PIDFD.patch b/SOURCES/0233-missing_sched-add-CLONE_PIDFD.patch new file mode 100644 index 0000000000000000000000000000000000000000..7422c1f657a27300ff263daf53a35ea4256cf8cd --- /dev/null +++ b/SOURCES/0233-missing_sched-add-CLONE_PIDFD.patch @@ -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" + + /** diff --git a/SOURCES/0234-stub-Mention-that-VirtualSize-should-be-SizeOfRawDat.patch b/SOURCES/0234-stub-Mention-that-VirtualSize-should-be-SizeOfRawDat.patch new file mode 100644 index 0000000000000000000000000000000000000000..eefebfa173119044ed382863e0653bfd05514491 --- /dev/null +++ b/SOURCES/0234-stub-Mention-that-VirtualSize-should-be-SizeOfRawDat.patch @@ -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 diff --git a/SOURCES/0235-import-pubring.gpg-add-openSUSE-build-key.patch b/SOURCES/0235-import-pubring.gpg-add-openSUSE-build-key.patch new file mode 100644 index 0000000000000000000000000000000000000000..810b8b35329247f185ada13f15d5834d9fb772ea --- /dev/null +++ b/SOURCES/0235-import-pubring.gpg-add-openSUSE-build-key.patch @@ -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 + diff --git a/SOURCES/0236-import-update-to-current-fedora-keyring.patch b/SOURCES/0236-import-update-to-current-fedora-keyring.patch new file mode 100644 index 0000000000000000000000000000000000000000..265ad2b13b07896f8e28f18cd883b560cfb44f36 --- /dev/null +++ b/SOURCES/0236-import-update-to-current-fedora-keyring.patch @@ -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 + diff --git a/SOURCES/0237-ukify-do-not-fail-if-pefile-complains-about-hardcode.patch b/SOURCES/0237-ukify-do-not-fail-if-pefile-complains-about-hardcode.patch new file mode 100644 index 0000000000000000000000000000000000000000..fafca0d26c198aa7cef52e7a1286d9433b5bb06b --- /dev/null +++ b/SOURCES/0237-ukify-do-not-fail-if-pefile-complains-about-hardcode.patch @@ -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']] diff --git a/SOURCES/0238-tmpfiles-fix-copypasta-in-create_symlink-FIFO-symlin.patch b/SOURCES/0238-tmpfiles-fix-copypasta-in-create_symlink-FIFO-symlin.patch new file mode 100644 index 0000000000000000000000000000000000000000..00516b78742dc65f71326a30586f82111ebc2953 --- /dev/null +++ b/SOURCES/0238-tmpfiles-fix-copypasta-in-create_symlink-FIFO-symlin.patch @@ -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); diff --git a/SOURCES/0239-udev-worker-add-debugging-log-about-success-of-flock.patch b/SOURCES/0239-udev-worker-add-debugging-log-about-success-of-flock.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a72cada72d4b423471dd76d03ac5f453a4994a0 --- /dev/null +++ b/SOURCES/0239-udev-worker-add-debugging-log-about-success-of-flock.patch @@ -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; + diff --git a/SOURCES/0240-udev-watch-mention-that-the-failure-is-ignored.patch b/SOURCES/0240-udev-watch-mention-that-the-failure-is-ignored.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f8ec37da0d8bc0938a2b66557164bbc3e847237 --- /dev/null +++ b/SOURCES/0240-udev-watch-mention-that-the-failure-is-ignored.patch @@ -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; + } diff --git a/SOURCES/0241-udev-watch-do-not-try-to-remove-invalid-watch-handle.patch b/SOURCES/0241-udev-watch-do-not-try-to-remove-invalid-watch-handle.patch new file mode 100644 index 0000000000000000000000000000000000000000..1c6a5742ee50cd4d568986ca9aa60308757f2ed0 --- /dev/null +++ b/SOURCES/0241-udev-watch-do-not-try-to-remove-invalid-watch-handle.patch @@ -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. */ diff --git a/SOURCES/0242-login-Continue-watching-leader-pidfd-after-stop.patch b/SOURCES/0242-login-Continue-watching-leader-pidfd-after-stop.patch new file mode 100644 index 0000000000000000000000000000000000000000..a297845d7ce00cb4b15ed23a26b891323c315f79 --- /dev/null +++ b/SOURCES/0242-login-Continue-watching-leader-pidfd-after-stop.patch @@ -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); diff --git a/SOURCES/0243-login-Queue-session-for-garbage-collection-on-leader.patch b/SOURCES/0243-login-Queue-session-for-garbage-collection-on-leader.patch new file mode 100644 index 0000000000000000000000000000000000000000..1a2b86d1b91199f2e155370ad8eebe02ab3884ac --- /dev/null +++ b/SOURCES/0243-login-Queue-session-for-garbage-collection-on-leader.patch @@ -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; + } + diff --git a/SOURCES/0244-ukify-print-debug-progress-messages-to-stderr.patch b/SOURCES/0244-ukify-print-debug-progress-messages-to-stderr.patch new file mode 100644 index 0000000000000000000000000000000000000000..b19329caa6d982b05ccaeed634132c1620c83359 --- /dev/null +++ b/SOURCES/0244-ukify-print-debug-progress-messages-to-stderr.patch @@ -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 diff --git a/SOURCES/0245-ukify-Calculate-section-size-more-correctly.patch b/SOURCES/0245-ukify-Calculate-section-size-more-correctly.patch new file mode 100644 index 0000000000000000000000000000000000000000..de580c90b8c3a65656920f8f4588132147f9473d --- /dev/null +++ b/SOURCES/0245-ukify-Calculate-section-size-more-correctly.patch @@ -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() + diff --git a/SOURCES/0246-mkosi-Update-to-latest.patch b/SOURCES/0246-mkosi-Update-to-latest.patch new file mode 100644 index 0000000000000000000000000000000000000000..80f3f67ff627994494096316a6e774c708731dde --- /dev/null +++ b/SOURCES/0246-mkosi-Update-to-latest.patch @@ -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 \ diff --git a/SOURCES/0247-core-condition-fix-segfault-when-key-not-found-in-os.patch b/SOURCES/0247-core-condition-fix-segfault-when-key-not-found-in-os.patch new file mode 100644 index 0000000000000000000000000000000000000000..c7a0fcab70d4141324054074ca8eb867e9dcc6d6 --- /dev/null +++ b/SOURCES/0247-core-condition-fix-segfault-when-key-not-found-in-os.patch @@ -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. */ diff --git a/SOURCES/0248-meson-bump-version-to-257.3.patch b/SOURCES/0248-meson-bump-version-to-257.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..06b6c45207ae9555f0e6a87d43217a045f3d0531 --- /dev/null +++ b/SOURCES/0248-meson-bump-version-to-257.3.patch @@ -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 diff --git a/SOURCES/0228-ci-update-workflows-to-run-on-source-git-setup.patch b/SOURCES/0249-ci-update-workflows-to-run-on-source-git-setup.patch similarity index 97% rename from SOURCES/0228-ci-update-workflows-to-run-on-source-git-setup.patch rename to SOURCES/0249-ci-update-workflows-to-run-on-source-git-setup.patch index 7ed59287c53470e9b7ae119e51320c4dac51a50b..0813cdc121157dd8b4e5eb1af532249d39610420 100644 --- a/SOURCES/0228-ci-update-workflows-to-run-on-source-git-setup.patch +++ b/SOURCES/0249-ci-update-workflows-to-run-on-source-git-setup.patch @@ -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 diff --git a/SOURCES/0229-ci-setup-source-git-automation.patch b/SOURCES/0250-ci-setup-source-git-automation.patch similarity index 99% rename from SOURCES/0229-ci-setup-source-git-automation.patch rename to SOURCES/0250-ci-setup-source-git-automation.patch index 0e7c08d3067710246ad6644d0eaadab56161e3fc..4d0f963d6029b3e9d6af65bd31bcef9200630eda 100644 --- a/SOURCES/0229-ci-setup-source-git-automation.patch +++ b/SOURCES/0250-ci-setup-source-git-automation.patch @@ -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 diff --git a/SOURCES/0230-ci-reconfigure-Packit-for-RHEL-10.patch b/SOURCES/0251-ci-reconfigure-Packit-for-RHEL-10.patch similarity index 97% rename from SOURCES/0230-ci-reconfigure-Packit-for-RHEL-10.patch rename to SOURCES/0251-ci-reconfigure-Packit-for-RHEL-10.patch index daf3626777355dd411bd6e2edc839ca603698fe4..2cf7ef12b3cfd40083e62d56811d55ebbd619138 100644 --- a/SOURCES/0230-ci-reconfigure-Packit-for-RHEL-10.patch +++ b/SOURCES/0251-ci-reconfigure-Packit-for-RHEL-10.patch @@ -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 diff --git a/SOURCES/0231-journal-again-create-user-journals-for-users-with-hi.patch b/SOURCES/0252-journal-again-create-user-journals-for-users-with-hi.patch similarity index 97% rename from SOURCES/0231-journal-again-create-user-journals-for-users-with-hi.patch rename to SOURCES/0252-journal-again-create-user-journals-for-users-with-hi.patch index 0927b6d668031a086579c15a4b2a03c6d474b2a7..451fdeeee2e5bc742b185f37254b943c67d6a3c0 100644 --- a/SOURCES/0231-journal-again-create-user-journals-for-users-with-hi.patch +++ b/SOURCES/0252-journal-again-create-user-journals-for-users-with-hi.patch @@ -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 diff --git a/SOURCES/0232-tmpfiles-make-purge-hard-to-mis-use.patch b/SOURCES/0253-tmpfiles-make-purge-hard-to-mis-use.patch similarity index 96% rename from SOURCES/0232-tmpfiles-make-purge-hard-to-mis-use.patch rename to SOURCES/0253-tmpfiles-make-purge-hard-to-mis-use.patch index 205a35bfb2ed548f2704e52b38e675e7210cafeb..04e0e57ce911ecc67e665d7c50c545bfdfddad86 100644 --- a/SOURCES/0232-tmpfiles-make-purge-hard-to-mis-use.patch +++ b/SOURCES/0253-tmpfiles-make-purge-hard-to-mis-use.patch @@ -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[]) { diff --git a/SOURCES/0233-fedora-use-system-auth-in-pam-systemd-user.patch b/SOURCES/0254-fedora-use-system-auth-in-pam-systemd-user.patch similarity index 93% rename from SOURCES/0233-fedora-use-system-auth-in-pam-systemd-user.patch rename to SOURCES/0254-fedora-use-system-auth-in-pam-systemd-user.patch index e12eaa39a6e69969cf13696693370d0d2279a5df..83342e66f7ef966a793cfb7bfe5f2f1d8de08914 100644 --- a/SOURCES/0233-fedora-use-system-auth-in-pam-systemd-user.patch +++ b/SOURCES/0254-fedora-use-system-auth-in-pam-systemd-user.patch @@ -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 diff --git a/SOURCES/0234-net-naming-scheme-start-rhel10-naming-and-include-rh.patch b/SOURCES/0255-net-naming-scheme-start-rhel10-naming-and-include-rh.patch similarity index 99% rename from SOURCES/0234-net-naming-scheme-start-rhel10-naming-and-include-rh.patch rename to SOURCES/0255-net-naming-scheme-start-rhel10-naming-and-include-rh.patch index c651d7f2f4c2f3e54dbb771f52eec22b40104203..1bd881c5bf3117ce516eaecf2506cb04fe7c965e 100644 --- a/SOURCES/0234-net-naming-scheme-start-rhel10-naming-and-include-rh.patch +++ b/SOURCES/0255-net-naming-scheme-start-rhel10-naming-and-include-rh.patch @@ -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 diff --git a/SOURCES/0235-rules-copy-40-redhat.rules-from-RHEL-9.patch b/SOURCES/0256-rules-copy-40-redhat.rules-from-RHEL-9.patch similarity index 98% rename from SOURCES/0235-rules-copy-40-redhat.rules-from-RHEL-9.patch rename to SOURCES/0256-rules-copy-40-redhat.rules-from-RHEL-9.patch index 46aa919fd353a89f8894038d007f991ec0c9024e..230c544596e2a493cf5401e531edffacb4bd665e 100644 --- a/SOURCES/0235-rules-copy-40-redhat.rules-from-RHEL-9.patch +++ b/SOURCES/0256-rules-copy-40-redhat.rules-from-RHEL-9.patch @@ -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 diff --git a/SOURCES/0236-logind-set-RemoveIPC-to-false-by-default.patch b/SOURCES/0257-logind-set-RemoveIPC-to-false-by-default.patch similarity index 96% rename from SOURCES/0236-logind-set-RemoveIPC-to-false-by-default.patch rename to SOURCES/0257-logind-set-RemoveIPC-to-false-by-default.patch index deead0760846e255698bf4d29d2d7c23e2e00cde..c28d9ccdade803ea82991ae2214b11b19850e2c4 100644 --- a/SOURCES/0236-logind-set-RemoveIPC-to-false-by-default.patch +++ b/SOURCES/0257-logind-set-RemoveIPC-to-false-by-default.patch @@ -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 diff --git a/SOURCES/0237-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch b/SOURCES/0258-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch similarity index 95% rename from SOURCES/0237-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch rename to SOURCES/0258-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch index 7ee2ed5b84ab94a128503e9628673b3d9253214c..0c02ddf91da09d3669d7e9b862035cfbfb693ba6 100644 --- a/SOURCES/0237-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch +++ b/SOURCES/0258-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch @@ -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 diff --git a/SOURCES/0238-rc-local-order-after-network-online.target.patch b/SOURCES/0259-rc-local-order-after-network-online.target.patch similarity index 92% rename from SOURCES/0238-rc-local-order-after-network-online.target.patch rename to SOURCES/0259-rc-local-order-after-network-online.target.patch index 02180eaa475e86765ba119db13b63de810bf46b3..2ff12aacb2101beb4e0f1669df3326fc691aa5e3 100644 --- a/SOURCES/0238-rc-local-order-after-network-online.target.patch +++ b/SOURCES/0259-rc-local-order-after-network-online.target.patch @@ -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 diff --git a/SOURCES/0239-random-util-increase-random-seed-size-to-1024.patch b/SOURCES/0260-random-util-increase-random-seed-size-to-1024.patch similarity index 91% rename from SOURCES/0239-random-util-increase-random-seed-size-to-1024.patch rename to SOURCES/0260-random-util-increase-random-seed-size-to-1024.patch index 9b96b84fd05d1377154e920ffb46aed2e5c3aacc..fcb2bcf9d6dbc3d451039c45e5cbd756e711ba07 100644 --- a/SOURCES/0239-random-util-increase-random-seed-size-to-1024.patch +++ b/SOURCES/0260-random-util-increase-random-seed-size-to-1024.patch @@ -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 diff --git a/SOURCES/0240-journal-don-t-enable-systemd-journald-audit.socket-b.patch b/SOURCES/0261-journal-don-t-enable-systemd-journald-audit.socket-b.patch similarity index 92% rename from SOURCES/0240-journal-don-t-enable-systemd-journald-audit.socket-b.patch rename to SOURCES/0261-journal-don-t-enable-systemd-journald-audit.socket-b.patch index 838ed88eefa64a4d9dfc36bd2e3e1fe46c5d4075..719cfc7fc6e8151524061bc93097b4d29f9f9262 100644 --- a/SOURCES/0240-journal-don-t-enable-systemd-journald-audit.socket-b.patch +++ b/SOURCES/0261-journal-don-t-enable-systemd-journald-audit.socket-b.patch @@ -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 diff --git a/SOURCES/0241-journald.conf-don-t-touch-current-audit-settings.patch b/SOURCES/0262-journald.conf-don-t-touch-current-audit-settings.patch similarity index 89% rename from SOURCES/0241-journald.conf-don-t-touch-current-audit-settings.patch rename to SOURCES/0262-journald.conf-don-t-touch-current-audit-settings.patch index 53bc8fa6ac4a5d2321d02949888b2e3e27cd049e..171e0dacaff380a52b9be000bc7950d834463f0f 100644 --- a/SOURCES/0241-journald.conf-don-t-touch-current-audit-settings.patch +++ b/SOURCES/0262-journald.conf-don-t-touch-current-audit-settings.patch @@ -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 diff --git a/SOURCES/0242-rules-add-elevator-kernel-command-line-parameter.patch b/SOURCES/0263-rules-add-elevator-kernel-command-line-parameter.patch similarity index 96% rename from SOURCES/0242-rules-add-elevator-kernel-command-line-parameter.patch rename to SOURCES/0263-rules-add-elevator-kernel-command-line-parameter.patch index 46c821f04c6bdbed552db57bfb5a15f71698c1e8..63e06d29f8b2a5e717ec67a81ce8121a77729bac 100644 --- a/SOURCES/0242-rules-add-elevator-kernel-command-line-parameter.patch +++ b/SOURCES/0263-rules-add-elevator-kernel-command-line-parameter.patch @@ -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 diff --git a/SOURCES/0243-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch b/SOURCES/0264-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch similarity index 97% rename from SOURCES/0243-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch rename to SOURCES/0264-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch index 5522fc7e2084141e16c173d010b6257c8c186740..55ea8737a0a39853c5aeb41ee1db3081d94e6682 100644 --- a/SOURCES/0243-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch +++ b/SOURCES/0264-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch @@ -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 diff --git a/SOURCES/0244-udev-net-setup-link-change-the-default-MACAddressPol.patch b/SOURCES/0265-udev-net-setup-link-change-the-default-MACAddressPol.patch similarity index 96% rename from SOURCES/0244-udev-net-setup-link-change-the-default-MACAddressPol.patch rename to SOURCES/0265-udev-net-setup-link-change-the-default-MACAddressPol.patch index a14f5fa3e4f7873bbd95273462fb0da858780a32..b45b73c3678900e00fbeb13a1b8375d61c1a61f9 100644 --- a/SOURCES/0244-udev-net-setup-link-change-the-default-MACAddressPol.patch +++ b/SOURCES/0265-udev-net-setup-link-change-the-default-MACAddressPol.patch @@ -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 diff --git a/SOURCES/0245-core-decrease-log-level-of-messages-about-use-of-Kil.patch b/SOURCES/0266-core-decrease-log-level-of-messages-about-use-of-Kil.patch similarity index 96% rename from SOURCES/0245-core-decrease-log-level-of-messages-about-use-of-Kil.patch rename to SOURCES/0266-core-decrease-log-level-of-messages-about-use-of-Kil.patch index bb6f3c5b6398f8ff28c6ea220a7365614c61efcf..306920616966c6a439315faeba1ccb0cd581ac27 100644 --- a/SOURCES/0245-core-decrease-log-level-of-messages-about-use-of-Kil.patch +++ b/SOURCES/0266-core-decrease-log-level-of-messages-about-use-of-Kil.patch @@ -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 diff --git a/SOURCES/0246-taint-remove-unmerged-bin.patch b/SOURCES/0267-taint-remove-unmerged-bin.patch similarity index 98% rename from SOURCES/0246-taint-remove-unmerged-bin.patch rename to SOURCES/0267-taint-remove-unmerged-bin.patch index 03ba74b75e3b14ad0d8a82e0bb1158adcc29002e..a5aa26886b3cb94d0e3ae0509fc6cf83298d708b 100644 --- a/SOURCES/0246-taint-remove-unmerged-bin.patch +++ b/SOURCES/0267-taint-remove-unmerged-bin.patch @@ -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 diff --git a/SOURCES/0247-presets-remove-resolved.patch b/SOURCES/0268-presets-remove-resolved.patch similarity index 93% rename from SOURCES/0247-presets-remove-resolved.patch rename to SOURCES/0268-presets-remove-resolved.patch index 99ae707c83da443537b7248e70f7af1e0103cdda..c017a3475d67fe6f16eda607c54a3d897ee46350 100644 --- a/SOURCES/0247-presets-remove-resolved.patch +++ b/SOURCES/0268-presets-remove-resolved.patch @@ -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 diff --git a/SOURCES/0248-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch b/SOURCES/0269-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch similarity index 95% rename from SOURCES/0248-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch rename to SOURCES/0269-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch index 34d3d7401ca1f43928eb334207448aa17604f57f..5415428f492e044f23151b51a2b9e66774be92b8 100644 --- a/SOURCES/0248-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch +++ b/SOURCES/0269-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch @@ -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: diff --git a/SOURCES/0249-taint-remove-unused-variable-usr_sbin.patch b/SOURCES/0270-taint-remove-unused-variable-usr_sbin.patch similarity index 93% rename from SOURCES/0249-taint-remove-unused-variable-usr_sbin.patch rename to SOURCES/0270-taint-remove-unused-variable-usr_sbin.patch index 2bcfd96989d369d1430bccd1493b5aea51c752ba..ae0138cc993a448e3bdeb424028053e32fa3db07 100644 --- a/SOURCES/0249-taint-remove-unused-variable-usr_sbin.patch +++ b/SOURCES/0270-taint-remove-unused-variable-usr_sbin.patch @@ -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` diff --git a/SOURCES/0250-packit-drop-the-libarchive-workaround.patch b/SOURCES/0271-packit-drop-the-libarchive-workaround.patch similarity index 93% rename from SOURCES/0250-packit-drop-the-libarchive-workaround.patch rename to SOURCES/0271-packit-drop-the-libarchive-workaround.patch index d997102bb14c872187b0d0cba3fc54fe002b1aa9..3cb8be9edc32ef45bfa4db0c680151c530a7df90 100644 --- a/SOURCES/0250-packit-drop-the-libarchive-workaround.patch +++ b/SOURCES/0271-packit-drop-the-libarchive-workaround.patch @@ -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 diff --git a/SOURCES/0251-coredump-by-default-process-and-store-core-files-up-.patch b/SOURCES/0272-coredump-by-default-process-and-store-core-files-up-.patch similarity index 92% rename from SOURCES/0251-coredump-by-default-process-and-store-core-files-up-.patch rename to SOURCES/0272-coredump-by-default-process-and-store-core-files-up-.patch index 7c26b2edf89341f601f20ae785b0543c75c23377..3a430e47c02ba9e9c847b810459242a5f22d1997 100644 --- a/SOURCES/0251-coredump-by-default-process-and-store-core-files-up-.patch +++ b/SOURCES/0272-coredump-by-default-process-and-store-core-files-up-.patch @@ -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 diff --git a/SOURCES/0252-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch b/SOURCES/0273-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch similarity index 92% rename from SOURCES/0252-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch rename to SOURCES/0273-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch index 726a41225937e230df46a4e87f558c9ac77bcf44..9bd6dd60e9a9c0929fdf7a0f3e4d8f850a88d8c8 100644 --- a/SOURCES/0252-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch +++ b/SOURCES/0273-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch @@ -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 diff --git a/SOURCES/0253-unit-don-t-add-Requires-for-tmp.mount.patch b/SOURCES/0274-unit-don-t-add-Requires-for-tmp.mount.patch similarity index 96% rename from SOURCES/0253-unit-don-t-add-Requires-for-tmp.mount.patch rename to SOURCES/0274-unit-don-t-add-Requires-for-tmp.mount.patch index 0bb8696f2625beff219184c29ed587ed233c1bcb..2c2f85b004cb656d7e36e6b239b96398707690e5 100644 --- a/SOURCES/0253-unit-don-t-add-Requires-for-tmp.mount.patch +++ b/SOURCES/0274-unit-don-t-add-Requires-for-tmp.mount.patch @@ -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 diff --git a/SOURCES/0254-units-add-Install-section-to-tmp.mount.patch b/SOURCES/0275-units-add-Install-section-to-tmp.mount.patch similarity index 90% rename from SOURCES/0254-units-add-Install-section-to-tmp.mount.patch rename to SOURCES/0275-units-add-Install-section-to-tmp.mount.patch index aea9ce6fd93c76a4a0514e9dd2c93683bcbd003a..8c49dbd24919dc0229974a6bbab4dddd0ae6c62a 100644 --- a/SOURCES/0254-units-add-Install-section-to-tmp.mount.patch +++ b/SOURCES/0275-units-add-Install-section-to-tmp.mount.patch @@ -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 diff --git a/SOURCES/0255-units-don-t-enable-tmp.mount-statically-in-local-fs..patch b/SOURCES/0276-units-don-t-enable-tmp.mount-statically-in-local-fs..patch similarity index 92% rename from SOURCES/0255-units-don-t-enable-tmp.mount-statically-in-local-fs..patch rename to SOURCES/0276-units-don-t-enable-tmp.mount-statically-in-local-fs..patch index 871161f79ea9545b0f80da651f3bd6434ba8f429..ab3d60d0d99ed6e0765a4424479cf53092e6ef4f 100644 --- a/SOURCES/0255-units-don-t-enable-tmp.mount-statically-in-local-fs..patch +++ b/SOURCES/0276-units-don-t-enable-tmp.mount-statically-in-local-fs..patch @@ -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 diff --git a/SOURCES/0256-netif-naming-scheme-add-rhel-9.5-scheme.patch b/SOURCES/0277-netif-naming-scheme-add-rhel-9.5-scheme.patch similarity index 97% rename from SOURCES/0256-netif-naming-scheme-add-rhel-9.5-scheme.patch rename to SOURCES/0277-netif-naming-scheme-add-rhel-9.5-scheme.patch index a2ffe37c06fbf929cab290099b875c0e9d455451..3c8ed93618487a7e098c447e960cd755dd8646d8 100644 --- a/SOURCES/0256-netif-naming-scheme-add-rhel-9.5-scheme.patch +++ b/SOURCES/0277-netif-naming-scheme-add-rhel-9.5-scheme.patch @@ -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 diff --git a/SOURCES/0257-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch b/SOURCES/0278-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch similarity index 97% rename from SOURCES/0257-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch rename to SOURCES/0278-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch index fbc30d5d58c91acfb2b6505bc5822097f306a972..66b54ae9aca6240dd417d2c3745dd307e3930ade 100644 --- a/SOURCES/0257-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch +++ b/SOURCES/0278-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch @@ -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 diff --git a/SOURCES/0258-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch b/SOURCES/0279-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch similarity index 94% rename from SOURCES/0258-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch rename to SOURCES/0279-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch index 1669e23dfe7282595116c71f66f33d592a972565..5bfa7109ceaae945182aede53949f349fa8900ed 100644 --- a/SOURCES/0258-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch +++ b/SOURCES/0279-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch @@ -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 diff --git a/SOURCES/0259-netif-naming-scheme-introduce-rhel-10.0-scheme.patch b/SOURCES/0280-netif-naming-scheme-introduce-rhel-10.0-scheme.patch similarity index 97% rename from SOURCES/0259-netif-naming-scheme-introduce-rhel-10.0-scheme.patch rename to SOURCES/0280-netif-naming-scheme-introduce-rhel-10.0-scheme.patch index 8b4c35db9f2ec2cf4fb11514d2c849d6f06c1719..fbdbe8b935ff14b9ec96e9bb7f9121459d1f4161 100644 --- a/SOURCES/0259-netif-naming-scheme-introduce-rhel-10.0-scheme.patch +++ b/SOURCES/0280-netif-naming-scheme-introduce-rhel-10.0-scheme.patch @@ -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 diff --git a/SOURCES/0260-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch b/SOURCES/0281-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch similarity index 97% rename from SOURCES/0260-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch rename to SOURCES/0281-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch index 356df6e79f9367e8041dcdeaba912c52b60fd8d5..f46057442b9a9617dd5366c0774b2f2fcb5cc37e 100644 --- a/SOURCES/0260-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch +++ b/SOURCES/0281-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch @@ -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 diff --git a/SOURCES/0261-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch b/SOURCES/0282-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch similarity index 91% rename from SOURCES/0261-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch rename to SOURCES/0282-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch index 31583def999e7fcca24ccfe84274d70c683e56b9..727a40827bb9245fb46b3c6128734fa48f7a487a 100644 --- a/SOURCES/0261-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch +++ b/SOURCES/0282-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch @@ -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 diff --git a/SOURCES/0262-ci-fix-Packit.patch b/SOURCES/0283-ci-fix-Packit.patch similarity index 91% rename from SOURCES/0262-ci-fix-Packit.patch rename to SOURCES/0283-ci-fix-Packit.patch index 397132d5ece09a0ae723f60a6a321555babbcd6f..5d5dd62220780b051933cd151ca30c0730d41dd8 100644 --- a/SOURCES/0262-ci-fix-Packit.patch +++ b/SOURCES/0283-ci-fix-Packit.patch @@ -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 diff --git a/SOURCES/0263-ci-drop-testing-farm-test.patch b/SOURCES/0284-ci-drop-testing-farm-test.patch similarity index 90% rename from SOURCES/0263-ci-drop-testing-farm-test.patch rename to SOURCES/0284-ci-drop-testing-farm-test.patch index 3f3fc96ee0ca136400305fe7b77e6c145f64d82c..2c239c8a2b823769a535236d0c3ecdb8140cd041 100644 --- a/SOURCES/0263-ci-drop-testing-farm-test.patch +++ b/SOURCES/0284-ci-drop-testing-farm-test.patch @@ -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 diff --git a/SOURCES/0264-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch b/SOURCES/0285-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch similarity index 99% rename from SOURCES/0264-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch rename to SOURCES/0285-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch index 3be2c821135db55777aa4270bbd0dd956af4713a..a4a4570d21f648f2091c76420ccc659e5436622b 100644 --- a/SOURCES/0264-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch +++ b/SOURCES/0285-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch @@ -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 diff --git a/SOURCES/0265-manager-s-deserialized_subscribed-subscribed_as_strv.patch b/SOURCES/0286-manager-s-deserialized_subscribed-subscribed_as_strv.patch similarity index 98% rename from SOURCES/0265-manager-s-deserialized_subscribed-subscribed_as_strv.patch rename to SOURCES/0286-manager-s-deserialized_subscribed-subscribed_as_strv.patch index 25872eedc4d60617bcad0845a576709401fc7033..68eeb2609d6c7909414c34a6252a50e76d9b1732 100644 --- a/SOURCES/0265-manager-s-deserialized_subscribed-subscribed_as_strv.patch +++ b/SOURCES/0286-manager-s-deserialized_subscribed-subscribed_as_strv.patch @@ -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 diff --git a/SOURCES/0266-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch b/SOURCES/0287-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch similarity index 99% rename from SOURCES/0266-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch rename to SOURCES/0287-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch index b80eb8ef9afb652e0f9613ecb7698778b1ae8582..58d6a8a76f465184cc417d12d9c9b56cdc2eda89 100644 --- a/SOURCES/0266-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch +++ b/SOURCES/0287-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch @@ -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 diff --git a/SOURCES/0267-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch b/SOURCES/0288-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch similarity index 98% rename from SOURCES/0267-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch rename to SOURCES/0288-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch index 113eb6a80fb2fae6c31eb74a812ed290d53fddbf..e7175141cf48cd610f3995a5bbbcb10037e127b6 100644 --- a/SOURCES/0267-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch +++ b/SOURCES/0288-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch @@ -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 diff --git a/SOURCES/0268-shared-bus-util-move-string-set-append-get-funcs-to-.patch b/SOURCES/0289-shared-bus-util-move-string-set-append-get-funcs-to-.patch similarity index 98% rename from SOURCES/0268-shared-bus-util-move-string-set-append-get-funcs-to-.patch rename to SOURCES/0289-shared-bus-util-move-string-set-append-get-funcs-to-.patch index 761bb87f27358ae10b82260b8c62cbbee7db6319..e8d18f0a5feeab75671d287b4302bd64ef03c87b 100644 --- a/SOURCES/0268-shared-bus-util-move-string-set-append-get-funcs-to-.patch +++ b/SOURCES/0289-shared-bus-util-move-string-set-append-get-funcs-to-.patch @@ -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 diff --git a/SOURCES/0269-shared-serialize-make-input-params-const.patch b/SOURCES/0290-shared-serialize-make-input-params-const.patch similarity index 97% rename from SOURCES/0269-shared-serialize-make-input-params-const.patch rename to SOURCES/0290-shared-serialize-make-input-params-const.patch index 4e4096d270fac4477cfe016afd87c70e6ec76ede..f16de3e442b135897f9a5e3b7a765ada7fbafc0e 100644 --- a/SOURCES/0269-shared-serialize-make-input-params-const.patch +++ b/SOURCES/0290-shared-serialize-make-input-params-const.patch @@ -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 diff --git a/SOURCES/0270-shared-serialize-introduce-serialize_id128.patch b/SOURCES/0291-shared-serialize-introduce-serialize_id128.patch similarity index 97% rename from SOURCES/0270-shared-serialize-introduce-serialize_id128.patch rename to SOURCES/0291-shared-serialize-introduce-serialize_id128.patch index 6b7232fbd160960be0029c6c73617183e6ddef30..a598391e63ba9af50824c67901562db90788819e 100644 --- a/SOURCES/0270-shared-serialize-introduce-serialize_id128.patch +++ b/SOURCES/0291-shared-serialize-introduce-serialize_id128.patch @@ -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() diff --git a/SOURCES/0271-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch b/SOURCES/0292-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch similarity index 96% rename from SOURCES/0271-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch rename to SOURCES/0292-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch index f5b1e72e30472ea15a83e0e1f6f72cf6f1f5da0d..a64ad5097d9a2a6cc9270f409a9347239f48f449 100644 --- a/SOURCES/0271-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch +++ b/SOURCES/0292-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch @@ -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 diff --git a/SOURCES/0272-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch b/SOURCES/0293-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch similarity index 94% rename from SOURCES/0272-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch rename to SOURCES/0293-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch index d6aea1e09d339a46080d4e8bf6d918c91994ad7b..0dd548ab46b2a3518ec5a92cced318c4d1a4e531 100644 --- a/SOURCES/0272-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch +++ b/SOURCES/0293-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch @@ -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 diff --git a/SOURCES/0273-core-manager-drop-duplicate-bus-track-deserializatio.patch b/SOURCES/0294-core-manager-drop-duplicate-bus-track-deserializatio.patch similarity index 95% rename from SOURCES/0273-core-manager-drop-duplicate-bus-track-deserializatio.patch rename to SOURCES/0294-core-manager-drop-duplicate-bus-track-deserializatio.patch index dcd055bca8ab84d61dbac544167dc75c8599fbf0..e8a084ac36d20ea38354f765d8fd5a435cafac27 100644 --- a/SOURCES/0273-core-manager-drop-duplicate-bus-track-deserializatio.patch +++ b/SOURCES/0294-core-manager-drop-duplicate-bus-track-deserializatio.patch @@ -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 diff --git a/SOURCES/0274-bus-util-introduce-bus_get_instance_id.patch b/SOURCES/0295-bus-util-introduce-bus_get_instance_id.patch similarity index 96% rename from SOURCES/0274-bus-util-introduce-bus_get_instance_id.patch rename to SOURCES/0295-bus-util-introduce-bus_get_instance_id.patch index 1971c672ee9d2b2b68f6d58f8d5c1b6fee809b75..a0881eae7d596aa26906a49be2655406858355c6 100644 --- a/SOURCES/0274-bus-util-introduce-bus_get_instance_id.patch +++ b/SOURCES/0295-bus-util-introduce-bus_get_instance_id.patch @@ -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() diff --git a/SOURCES/0275-core-serialize-API-bus-id-and-validate-before-deseri.patch b/SOURCES/0296-core-serialize-API-bus-id-and-validate-before-deseri.patch similarity index 99% rename from SOURCES/0275-core-serialize-API-bus-id-and-validate-before-deseri.patch rename to SOURCES/0296-core-serialize-API-bus-id-and-validate-before-deseri.patch index 5ec17174a29185ed47e8335926b426d0c1ac04c9..5c5c5d9ca0636b242668af11ce268b27a99a1b30 100644 --- a/SOURCES/0275-core-serialize-API-bus-id-and-validate-before-deseri.patch +++ b/SOURCES/0296-core-serialize-API-bus-id-and-validate-before-deseri.patch @@ -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 diff --git a/SOURCES/0276-core-manager-restore-bus-track-deserialization-clean.patch b/SOURCES/0297-core-manager-restore-bus-track-deserialization-clean.patch similarity index 94% rename from SOURCES/0276-core-manager-restore-bus-track-deserialization-clean.patch rename to SOURCES/0297-core-manager-restore-bus-track-deserialization-clean.patch index 3bd765518d50573055d522034fab6b293ce9a295..d093c3a690f4da0dcf389bc4f22a09b4ce7f1e62 100644 --- a/SOURCES/0276-core-manager-restore-bus-track-deserialization-clean.patch +++ b/SOURCES/0297-core-manager-restore-bus-track-deserialization-clean.patch @@ -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 diff --git a/SOURCES/0277-shared-bus-util-add-missing-set.h-include.patch b/SOURCES/0298-shared-bus-util-add-missing-set.h-include.patch similarity index 95% rename from SOURCES/0277-shared-bus-util-add-missing-set.h-include.patch rename to SOURCES/0298-shared-bus-util-add-missing-set.h-include.patch index e07a4c077489da18873df3c927f28b6169a26415..2049aa57ad8770a30ad7a43393968e2eff1f4ef7 100644 --- a/SOURCES/0277-shared-bus-util-add-missing-set.h-include.patch +++ b/SOURCES/0298-shared-bus-util-add-missing-set.h-include.patch @@ -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 diff --git a/SOURCES/0278-udevadm-test-add-missing-oom-check.patch b/SOURCES/0299-udevadm-test-add-missing-oom-check.patch similarity index 92% rename from SOURCES/0278-udevadm-test-add-missing-oom-check.patch rename to SOURCES/0299-udevadm-test-add-missing-oom-check.patch index 305054a83cefa14f16b73245ef49c070a41e55c9..8f37cf694b5721a8579cae447709cf5b44793fc5 100644 --- a/SOURCES/0278-udevadm-test-add-missing-oom-check.patch +++ b/SOURCES/0299-udevadm-test-add-missing-oom-check.patch @@ -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 diff --git a/SOURCES/0279-udev-rules-replace-type-func-type-func.patch b/SOURCES/0300-udev-rules-replace-type-func-type-func.patch similarity index 95% rename from SOURCES/0279-udev-rules-replace-type-func-type-func.patch rename to SOURCES/0300-udev-rules-replace-type-func-type-func.patch index ba2c44602877d4f64c0f201c905ec9311a8fa725..5e7db5d38bc1e04982ca59bfef33a72a722c22a3 100644 --- a/SOURCES/0279-udev-rules-replace-type-func-type-func.patch +++ b/SOURCES/0300-udev-rules-replace-type-func-type-func.patch @@ -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()' diff --git a/SOURCES/0280-udev-rules-do-not-change-maximum-log-level-when-runn.patch b/SOURCES/0301-udev-rules-do-not-change-maximum-log-level-when-runn.patch similarity index 96% rename from SOURCES/0280-udev-rules-do-not-change-maximum-log-level-when-runn.patch rename to SOURCES/0301-udev-rules-do-not-change-maximum-log-level-when-runn.patch index aaee03234577a26f53701ac1f5ef92fdef721272..f325d332a0bd79b1d6c58a26f44300821885e500 100644 --- a/SOURCES/0280-udev-rules-do-not-change-maximum-log-level-when-runn.patch +++ b/SOURCES/0301-udev-rules-do-not-change-maximum-log-level-when-runn.patch @@ -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 diff --git a/SOURCES/0281-udevadm-test-introduce-v-verbose-option-to-show-verb.patch b/SOURCES/0302-udevadm-test-introduce-v-verbose-option-to-show-verb.patch similarity index 99% rename from SOURCES/0281-udevadm-test-introduce-v-verbose-option-to-show-verb.patch rename to SOURCES/0302-udevadm-test-introduce-v-verbose-option-to-show-verb.patch index 44c4fecc7fd205503effd69b199174bf3e8bf798..69f02d61d0d946fafde9be8d5f7af220578a6c5b 100644 --- a/SOURCES/0281-udevadm-test-introduce-v-verbose-option-to-show-verb.patch +++ b/SOURCES/0302-udevadm-test-introduce-v-verbose-option-to-show-verb.patch @@ -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 diff --git a/SOURCES/0282-udev-rules-show-original-token-string-in-log_event_e.patch b/SOURCES/0303-udev-rules-show-original-token-string-in-log_event_e.patch similarity index 99% rename from SOURCES/0282-udev-rules-show-original-token-string-in-log_event_e.patch rename to SOURCES/0303-udev-rules-show-original-token-string-in-log_event_e.patch index 3c2572936aa377caa92388bdbf609c2190c825f3..894f58ff2ec085b7f49a7141b6d31d373ea2a67e 100644 --- a/SOURCES/0282-udev-rules-show-original-token-string-in-log_event_e.patch +++ b/SOURCES/0303-udev-rules-show-original-token-string-in-log_event_e.patch @@ -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() diff --git a/SOURCES/0283-udev-rules-logs-result-of-format-substitution.patch b/SOURCES/0304-udev-rules-logs-result-of-format-substitution.patch similarity index 99% rename from SOURCES/0283-udev-rules-logs-result-of-format-substitution.patch rename to SOURCES/0304-udev-rules-logs-result-of-format-substitution.patch index b245fa6b955364bfffdc3cab3d0fa52aea5d13d0..923b7d439ec4aa5733374d8a7d864846587b02b1 100644 --- a/SOURCES/0283-udev-rules-logs-result-of-format-substitution.patch +++ b/SOURCES/0304-udev-rules-logs-result-of-format-substitution.patch @@ -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 diff --git a/SOURCES/0284-udev-rules-add-more-trace-logs-for-string-match.patch b/SOURCES/0305-udev-rules-add-more-trace-logs-for-string-match.patch similarity index 99% rename from SOURCES/0284-udev-rules-add-more-trace-logs-for-string-match.patch rename to SOURCES/0305-udev-rules-add-more-trace-logs-for-string-match.patch index ab9068b6d7980359af5e86ab5bc2ea342e5be039..e3a25e1b83aca9eaa3f2f47e13658a30239298f6 100644 --- a/SOURCES/0284-udev-rules-add-more-trace-logs-for-string-match.patch +++ b/SOURCES/0305-udev-rules-add-more-trace-logs-for-string-match.patch @@ -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 diff --git a/SOURCES/0285-udev-rules-introduce-udev_replace_chars_and_log.patch b/SOURCES/0306-udev-rules-introduce-udev_replace_chars_and_log.patch similarity index 99% rename from SOURCES/0285-udev-rules-introduce-udev_replace_chars_and_log.patch rename to SOURCES/0306-udev-rules-introduce-udev_replace_chars_and_log.patch index 87aef42dab3841786c4315eb8b722a5b3e4bbff0..88b78c4ec088f644b84bcbdaec8ac68523a0512c 100644 --- a/SOURCES/0285-udev-rules-introduce-udev_replace_chars_and_log.patch +++ b/SOURCES/0306-udev-rules-introduce-udev_replace_chars_and_log.patch @@ -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() diff --git a/SOURCES/0286-udev-rules-ignore-whole-command-result-if-it-is-too-.patch b/SOURCES/0307-udev-rules-ignore-whole-command-result-if-it-is-too-.patch similarity index 95% rename from SOURCES/0286-udev-rules-ignore-whole-command-result-if-it-is-too-.patch rename to SOURCES/0307-udev-rules-ignore-whole-command-result-if-it-is-too-.patch index a1278a4d582d3286aa6855fc420b5daa21237132..ea8671cca2b0b4c2aa78eeed980c84b2e6c3a552 100644 --- a/SOURCES/0286-udev-rules-ignore-whole-command-result-if-it-is-too-.patch +++ b/SOURCES/0307-udev-rules-ignore-whole-command-result-if-it-is-too-.patch @@ -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 diff --git a/SOURCES/0287-udev-rules-update-log-messages.patch b/SOURCES/0308-udev-rules-update-log-messages.patch similarity index 99% rename from SOURCES/0287-udev-rules-update-log-messages.patch rename to SOURCES/0308-udev-rules-update-log-messages.patch index 2b7a6c8707f6899e1682566d13d24bb6daf06627..57dec0fbf11945b3685c9262c4efce3db2194334 100644 --- a/SOURCES/0287-udev-rules-update-log-messages.patch +++ b/SOURCES/0308-udev-rules-update-log-messages.patch @@ -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 diff --git a/SOURCES/0288-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch b/SOURCES/0309-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch similarity index 98% rename from SOURCES/0288-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch rename to SOURCES/0309-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch index 442c809cb217c6f14d803b7148eeb25d381aadb0..f5d11673b833b99c78d799b233caec35f671c6e2 100644 --- a/SOURCES/0288-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch +++ b/SOURCES/0309-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch @@ -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 diff --git a/SOURCES/0310-udev-move-enums-to-udev-def.h.patch b/SOURCES/0310-udev-move-enums-to-udev-def.h.patch new file mode 100644 index 0000000000000000000000000000000000000000..e88fd02a662e3c5b41ec566b1c744917672a1831 --- /dev/null +++ b/SOURCES/0310-udev-move-enums-to-udev-def.h.patch @@ -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" diff --git a/SOURCES/0311-udev-move-listen_fds-to-udev-manager.c.patch b/SOURCES/0311-udev-move-listen_fds-to-udev-manager.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..434987d721327f6960fb21d4565371c4c27d7b6c --- /dev/null +++ b/SOURCES/0311-udev-move-listen_fds-to-udev-manager.c.patch @@ -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; diff --git a/SOURCES/0312-udev-several-coding-style-fixes.patch b/SOURCES/0312-udev-several-coding-style-fixes.patch new file mode 100644 index 0000000000000000000000000000000000000000..8708142e46398b3c47b1fda4d4ca879901d0f6d8 --- /dev/null +++ b/SOURCES/0312-udev-several-coding-style-fixes.patch @@ -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) + diff --git a/SOURCES/0313-udev-builtin-make-udev_builtin_add_property-and-frie.patch b/SOURCES/0313-udev-builtin-make-udev_builtin_add_property-and-frie.patch new file mode 100644 index 0000000000000000000000000000000000000000..1ffbb2598650d86ee158d6661bcf2705c8c61e2b --- /dev/null +++ b/SOURCES/0313-udev-builtin-make-udev_builtin_add_property-and-frie.patch @@ -0,0 +1,1259 @@ +From fc5978e7c5913187fba87ae5d71da5de3064f10c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 5 Dec 2024 01:17:40 +0900 +Subject: [PATCH] udev-builtin: make udev_builtin_add_property() and friends + take UdevEvent* + +No functional change, just refactoring. + +(cherry picked from commit 036c75ded366bc2e8ae5ef3bf230f20982633d15) + +Resolves: RHEL-75774 +--- + src/udev/net/link-config.c | 29 +++--- + src/udev/net/link-config.h | 4 +- + src/udev/udev-builtin-blkid.c | 70 +++++++------- + src/udev/udev-builtin-btrfs.c | 4 +- + src/udev/udev-builtin-hwdb.c | 21 ++--- + src/udev/udev-builtin-input_id.c | 58 ++++++------ + src/udev/udev-builtin-net_driver.c | 2 +- + src/udev/udev-builtin-net_id.c | 123 ++++++++++++------------- + src/udev/udev-builtin-net_setup_link.c | 8 +- + src/udev/udev-builtin-path_id.c | 18 ++-- + src/udev/udev-builtin-usb_id.c | 52 +++++------ + src/udev/udev-builtin.c | 26 +++--- + src/udev/udev-builtin.h | 9 +- + 13 files changed, 211 insertions(+), 213 deletions(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index c2bec61347..55eeb9de81 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -1001,18 +1001,16 @@ static int link_apply_rps_cpu_mask(Link *link, EventMode mode) { + return 0; + } + +-static int link_apply_udev_properties(Link *link, EventMode mode) { ++static int link_apply_udev_properties(Link *link, UdevEvent *event) { + LinkConfig *config; +- sd_device *device; + + assert(link); + + config = ASSERT_PTR(link->config); +- device = ASSERT_PTR(link->device); + + /* 1. apply ImportProperty=. */ + STRV_FOREACH(p, config->import_properties) +- (void) udev_builtin_import_property(device, link->device_db_clone, mode, *p); ++ (void) udev_builtin_import_property(event, *p); + + /* 2. apply Property=. */ + STRV_FOREACH(p, config->properties) { +@@ -1027,15 +1025,15 @@ static int link_apply_udev_properties(Link *link, EventMode mode) { + if (!key) + return log_oom(); + +- (void) udev_builtin_add_property(device, mode, key, eq + 1); ++ (void) udev_builtin_add_property(event, key, eq + 1); + } + + /* 3. apply UnsetProperty=. */ + STRV_FOREACH(p, config->unset_properties) +- (void) udev_builtin_add_property(device, mode, *p, NULL); ++ (void) udev_builtin_add_property(event, *p, NULL); + + /* 4. set the default properties. */ +- (void) udev_builtin_add_property(device, mode, "ID_NET_LINK_FILE", config->filename); ++ (void) udev_builtin_add_property(event, "ID_NET_LINK_FILE", config->filename); + + _cleanup_free_ char *joined = NULL; + STRV_FOREACH(d, config->dropins) { +@@ -1049,26 +1047,27 @@ static int link_apply_udev_properties(Link *link, EventMode mode) { + return log_oom(); + } + +- (void) udev_builtin_add_property(device, mode, "ID_NET_LINK_FILE_DROPINS", joined); ++ (void) udev_builtin_add_property(event, "ID_NET_LINK_FILE_DROPINS", joined); + + if (link->new_name) +- (void) udev_builtin_add_property(device, mode, "ID_NET_NAME", link->new_name); ++ (void) udev_builtin_add_property(event, "ID_NET_NAME", link->new_name); + + return 0; + } + +-int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, EventMode mode) { ++int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, UdevEvent *event) { + int r; + + assert(ctx); + assert(rtnl); + assert(link); ++ assert(event); + +- r = link_apply_ethtool_settings(link, &ctx->ethtool_fd, mode); ++ r = link_apply_ethtool_settings(link, &ctx->ethtool_fd, event->event_mode); + if (r < 0) + return r; + +- r = link_apply_rtnl_settings(link, rtnl, mode); ++ r = link_apply_rtnl_settings(link, rtnl, event->event_mode); + if (r < 0) + return r; + +@@ -1080,15 +1079,15 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, Eve + if (r < 0) + return r; + +- r = link_apply_sr_iov_config(link, rtnl, mode); ++ r = link_apply_sr_iov_config(link, rtnl, event->event_mode); + if (r < 0) + return r; + +- r = link_apply_rps_cpu_mask(link, mode); ++ r = link_apply_rps_cpu_mask(link, event->event_mode); + if (r < 0) + return r; + +- return link_apply_udev_properties(link, mode); ++ return link_apply_udev_properties(link, event); + } + + int config_parse_udev_property( +diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h +index 5aaa7c51a0..a60e183e4b 100644 +--- a/src/udev/net/link-config.h ++++ b/src/udev/net/link-config.h +@@ -12,10 +12,10 @@ + #include "list.h" + #include "net-condition.h" + #include "netif-naming-scheme.h" +-#include "udev-event.h" + + typedef struct LinkConfigContext LinkConfigContext; + typedef struct LinkConfig LinkConfig; ++typedef struct UdevEvent UdevEvent; + + typedef enum MACAddressPolicy { + MAC_ADDRESS_POLICY_PERSISTENT, +@@ -107,7 +107,7 @@ 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, EventMode mode); ++int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, UdevEvent *event); + + 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-blkid.c b/src/udev/udev-builtin-blkid.c +index ae9a11f45d..73417338f5 100644 +--- a/src/udev/udev-builtin-blkid.c ++++ b/src/udev/udev-builtin-blkid.c +@@ -34,95 +34,98 @@ + #include "strxcpyx.h" + #include "udev-builtin.h" + +-static void print_property(sd_device *dev, EventMode mode, const char *name, const char *value) { ++static void print_property(UdevEvent *event, const char *name, const char *value) { + char s[256]; + ++ assert(event); ++ assert(name); ++ + s[0] = '\0'; + + if (streq(name, "TYPE")) { +- udev_builtin_add_property(dev, mode, "ID_FS_TYPE", value); ++ udev_builtin_add_property(event, "ID_FS_TYPE", value); + + } else if (streq(name, "USAGE")) { +- udev_builtin_add_property(dev, mode, "ID_FS_USAGE", value); ++ udev_builtin_add_property(event, "ID_FS_USAGE", value); + + } else if (streq(name, "VERSION")) { +- udev_builtin_add_property(dev, mode, "ID_FS_VERSION", value); ++ udev_builtin_add_property(event, "ID_FS_VERSION", value); + + } else if (streq(name, "UUID")) { + blkid_safe_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_UUID", s); ++ udev_builtin_add_property(event, "ID_FS_UUID", s); + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_UUID_ENC", s); ++ udev_builtin_add_property(event, "ID_FS_UUID_ENC", s); + + } else if (streq(name, "UUID_SUB")) { + blkid_safe_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_UUID_SUB", s); ++ udev_builtin_add_property(event, "ID_FS_UUID_SUB", s); + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_UUID_SUB_ENC", s); ++ udev_builtin_add_property(event, "ID_FS_UUID_SUB_ENC", s); + + } else if (streq(name, "LABEL")) { + blkid_safe_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_LABEL", s); ++ udev_builtin_add_property(event, "ID_FS_LABEL", s); + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_LABEL_ENC", s); ++ udev_builtin_add_property(event, "ID_FS_LABEL_ENC", s); + + } else if (STR_IN_SET(name, "FSSIZE", "FSLASTBLOCK", "FSBLOCKSIZE")) { + strscpyl(s, sizeof(s), "ID_FS_", name + 2, NULL); +- udev_builtin_add_property(dev, mode, s, value); ++ udev_builtin_add_property(event, s, value); + + } else if (streq(name, "PTTYPE")) { +- udev_builtin_add_property(dev, mode, "ID_PART_TABLE_TYPE", value); ++ udev_builtin_add_property(event, "ID_PART_TABLE_TYPE", value); + + } else if (streq(name, "PTUUID")) { +- udev_builtin_add_property(dev, mode, "ID_PART_TABLE_UUID", value); ++ udev_builtin_add_property(event, "ID_PART_TABLE_UUID", value); + + } else if (streq(name, "PART_ENTRY_NAME")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_PART_ENTRY_NAME", s); ++ udev_builtin_add_property(event, "ID_PART_ENTRY_NAME", s); + + } else if (streq(name, "PART_ENTRY_TYPE")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_PART_ENTRY_TYPE", s); ++ udev_builtin_add_property(event, "ID_PART_ENTRY_TYPE", s); + + } else if (startswith(name, "PART_ENTRY_")) { + strscpyl(s, sizeof(s), "ID_", name, NULL); +- udev_builtin_add_property(dev, mode, s, value); ++ udev_builtin_add_property(event, s, value); + + } else if (streq(name, "SYSTEM_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_SYSTEM_ID", s); ++ udev_builtin_add_property(event, "ID_FS_SYSTEM_ID", s); + + } else if (streq(name, "PUBLISHER_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_PUBLISHER_ID", s); ++ udev_builtin_add_property(event, "ID_FS_PUBLISHER_ID", s); + + } else if (streq(name, "APPLICATION_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_APPLICATION_ID", s); ++ udev_builtin_add_property(event, "ID_FS_APPLICATION_ID", s); + + } else if (streq(name, "BOOT_SYSTEM_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_BOOT_SYSTEM_ID", s); ++ udev_builtin_add_property(event, "ID_FS_BOOT_SYSTEM_ID", s); + + } else if (streq(name, "VOLUME_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_VOLUME_ID", s); ++ udev_builtin_add_property(event, "ID_FS_VOLUME_ID", s); + + } else if (streq(name, "LOGICAL_VOLUME_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_LOGICAL_VOLUME_ID", s); ++ udev_builtin_add_property(event, "ID_FS_LOGICAL_VOLUME_ID", s); + + } else if (streq(name, "VOLUME_SET_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_VOLUME_SET_ID", s); ++ udev_builtin_add_property(event, "ID_FS_VOLUME_SET_ID", s); + + } else if (streq(name, "DATA_PREPARER_ID")) { + blkid_encode_string(value, s, sizeof(s)); +- udev_builtin_add_property(dev, mode, "ID_FS_DATA_PREPARER_ID", s); ++ udev_builtin_add_property(event, "ID_FS_DATA_PREPARER_ID", s); + } + } + +-static int find_gpt_root(sd_device *dev, blkid_probe pr, EventMode mode) { ++static int find_gpt_root(UdevEvent *event, blkid_probe pr) { + + #if defined(SD_GPT_ROOT_NATIVE) && ENABLE_EFI + +@@ -131,6 +134,7 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, EventMode mode) { + sd_id128_t root_id = SD_ID128_NULL; + int r; + ++ assert(event); + assert(pr); + + /* Iterate through the partitions on this disk, and see if the UEFI ESP or XBOOTLDR partition we +@@ -201,7 +205,7 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, EventMode mode) { + /* We found the ESP/XBOOTLDR on this disk, and also found a root partition, nice! Let's export its + * UUID */ + if (found_esp_or_xbootldr && !sd_id128_is_null(root_id)) +- udev_builtin_add_property(dev, mode, "ID_PART_GPT_AUTO_ROOT_UUID", SD_ID128_TO_UUID_STRING(root_id)); ++ udev_builtin_add_property(event, "ID_PART_GPT_AUTO_ROOT_UUID", SD_ID128_TO_UUID_STRING(root_id)); + #endif + + return 0; +@@ -421,7 +425,7 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { + if (blkid_probe_get_value(pr, i, &name, &data, NULL) < 0) + continue; + +- print_property(dev, event->event_mode, name, data); ++ print_property(event, name, data); + + /* Is this a disk with GPT partition table? */ + if (streq(name, "PTTYPE") && streq(data, "gpt")) +@@ -430,11 +434,11 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { + /* Is this a partition that matches the root partition + * property inherited from the parent? */ + if (root_partition && streq(name, "PART_ENTRY_UUID") && streq(data, root_partition)) +- udev_builtin_add_property(dev, event->event_mode, "ID_PART_GPT_AUTO_ROOT", "1"); ++ udev_builtin_add_property(event, "ID_PART_GPT_AUTO_ROOT", "1"); + } + + if (is_gpt) +- find_gpt_root(dev, pr, event->event_mode); ++ find_gpt_root(event, pr); + + r = read_loopback_backing_inode( + dev, +@@ -445,8 +449,8 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { + if (r < 0) + log_device_debug_errno(dev, r, "Failed to read loopback backing inode, ignoring: %m"); + else if (r > 0) { +- udev_builtin_add_propertyf(dev, event->event_mode, "ID_LOOP_BACKING_DEVICE", DEVNUM_FORMAT_STR, DEVNUM_FORMAT_VAL(backing_devno)); +- udev_builtin_add_propertyf(dev, event->event_mode, "ID_LOOP_BACKING_INODE", "%" PRIu64, (uint64_t) backing_inode); ++ udev_builtin_add_propertyf(event, "ID_LOOP_BACKING_DEVICE", DEVNUM_FORMAT_STR, DEVNUM_FORMAT_VAL(backing_devno)); ++ udev_builtin_add_propertyf(event, "ID_LOOP_BACKING_INODE", "%" PRIu64, (uint64_t) backing_inode); + + if (backing_fname) { + /* In the worst case blkid_encode_string() will blow up to 4x the string +@@ -457,8 +461,8 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { + assert(strlen(backing_fname) < ELEMENTSOF(encoded) / 4); + blkid_encode_string(backing_fname, encoded, ELEMENTSOF(encoded)); + +- udev_builtin_add_property(dev, event->event_mode, "ID_LOOP_BACKING_FILENAME", backing_fname); +- udev_builtin_add_property(dev, event->event_mode, "ID_LOOP_BACKING_FILENAME_ENC", encoded); ++ udev_builtin_add_property(event, "ID_LOOP_BACKING_FILENAME", backing_fname); ++ udev_builtin_add_property(event, "ID_LOOP_BACKING_FILENAME_ENC", encoded); + } + } + +diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c +index fe030d05b9..f7d42c1ed0 100644 +--- a/src/udev/udev-builtin-btrfs.c ++++ b/src/udev/udev-builtin-btrfs.c +@@ -27,7 +27,7 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { + /* Driver not installed? Then we aren't ready. This is useful in initrds that lack + * btrfs.ko. After the host transition (where btrfs.ko will hopefully become + * available) the device can be retriggered and will then be considered ready. */ +- udev_builtin_add_property(dev, event->event_mode, "ID_BTRFS_READY", "0"); ++ udev_builtin_add_property(event, "ID_BTRFS_READY", "0"); + return 0; + } + +@@ -39,7 +39,7 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { + if (r < 0) + return log_device_debug_errno(dev, errno, "Failed to call BTRFS_IOC_DEVICES_READY: %m"); + +- udev_builtin_add_property(dev, event->event_mode, "ID_BTRFS_READY", one_zero(r == 0)); ++ udev_builtin_add_property(event, "ID_BTRFS_READY", one_zero(r == 0)); + return 0; + } + +diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c +index fbee04b4a8..b499d92479 100644 +--- a/src/udev/udev-builtin-hwdb.c ++++ b/src/udev/udev-builtin-hwdb.c +@@ -18,11 +18,10 @@ + static sd_hwdb *hwdb; + + int udev_builtin_hwdb_lookup( +- sd_device *dev, ++ UdevEvent *event, + const char *prefix, + const char *modalias, +- const char *filter, +- EventMode mode) { ++ const char *filter) { + + _cleanup_free_ char *lookup = NULL; + const char *key, *value; +@@ -42,7 +41,7 @@ int udev_builtin_hwdb_lookup( + if (filter && fnmatch(filter, key, FNM_NOESCAPE) != 0) + continue; + +- r = udev_builtin_add_property(dev, mode, key, value); ++ r = udev_builtin_add_property(event, key, value); + if (r < 0) + return r; + n++; +@@ -69,18 +68,18 @@ static const char* modalias_usb(sd_device *dev, char *s, size_t size) { + } + + static int udev_builtin_hwdb_search( +- sd_device *dev, ++ UdevEvent *event, + sd_device *srcdev, + const char *subsystem, + const char *prefix, +- const char *filter, +- EventMode mode) { ++ const char *filter) { + ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + char s[LINE_MAX]; + bool last = false; + int r = 0; + +- assert(dev); ++ assert(event); + + if (!srcdev) + srcdev = dev; +@@ -108,7 +107,7 @@ static int udev_builtin_hwdb_search( + + log_device_debug(dev, "hwdb modalias key: \"%s\"", modalias); + +- r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, mode); ++ r = udev_builtin_hwdb_lookup(event, prefix, modalias, filter); + if (r > 0) + break; + +@@ -166,7 +165,7 @@ static int builtin_hwdb(UdevEvent *event, int argc, char *argv[]) { + + /* query a specific key given as argument */ + if (argv[optind]) { +- r = udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, event->event_mode); ++ r = udev_builtin_hwdb_lookup(event, prefix, argv[optind], filter); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to look up hwdb: %m"); + if (r == 0) +@@ -181,7 +180,7 @@ static int builtin_hwdb(UdevEvent *event, int argc, char *argv[]) { + return log_device_debug_errno(dev, r, "Failed to create sd_device object '%s': %m", device); + } + +- r = udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, event->event_mode); ++ r = udev_builtin_hwdb_search(event, srcdev, subsystem, prefix, filter); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to look up hwdb: %m"); + if (r == 0) +diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c +index c204d656f0..509edee8aa 100644 +--- a/src/udev/udev-builtin-input_id.c ++++ b/src/udev/udev-builtin-input_id.c +@@ -44,12 +44,15 @@ static int abs_size_mm(const struct input_absinfo *absinfo) { + return (absinfo->maximum - absinfo->minimum) / absinfo->resolution; + } + +-static void extract_info(sd_device *dev, EventMode mode) { ++static void extract_info(UdevEvent *event) { + char width[DECIMAL_STR_MAX(int)], height[DECIMAL_STR_MAX(int)]; + struct input_absinfo xabsinfo = {}, yabsinfo = {}; + _cleanup_close_ int fd = -EBADF; + +- fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); ++ assert(event); ++ assert(event->dev); ++ ++ fd = sd_device_open(event->dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (fd < 0) + return; + +@@ -63,8 +66,8 @@ static void extract_info(sd_device *dev, EventMode mode) { + xsprintf(width, "%d", abs_size_mm(&xabsinfo)); + xsprintf(height, "%d", abs_size_mm(&yabsinfo)); + +- udev_builtin_add_property(dev, mode, "ID_INPUT_WIDTH_MM", width); +- udev_builtin_add_property(dev, mode, "ID_INPUT_HEIGHT_MM", height); ++ udev_builtin_add_property(event, "ID_INPUT_WIDTH_MM", width); ++ udev_builtin_add_property(event, "ID_INPUT_HEIGHT_MM", height); + } + + /* +@@ -148,15 +151,15 @@ static struct input_id get_input_id(sd_device *dev) { + + /* pointer devices */ + static bool test_pointers( +- sd_device *dev, ++ UdevEvent *event, + 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, +- EventMode mode) { ++ const unsigned long *bitmask_props) { + ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + size_t num_joystick_axes = 0, num_joystick_buttons = 0; + bool has_abs_coordinates = false, + has_rel_coordinates = false, +@@ -190,7 +193,7 @@ static bool test_pointers( + is_accelerometer = true; + + if (is_accelerometer) { +- udev_builtin_add_property(dev, mode, "ID_INPUT_ACCELEROMETER", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_ACCELEROMETER", "1"); + return true; + } + +@@ -313,30 +316,30 @@ static bool test_pointers( + } + + if (is_pointing_stick) +- udev_builtin_add_property(dev, mode, "ID_INPUT_POINTINGSTICK", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_POINTINGSTICK", "1"); + if (is_mouse || is_abs_mouse) +- udev_builtin_add_property(dev, mode, "ID_INPUT_MOUSE", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_MOUSE", "1"); + if (is_touchpad) +- udev_builtin_add_property(dev, mode, "ID_INPUT_TOUCHPAD", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_TOUCHPAD", "1"); + if (is_touchscreen) +- udev_builtin_add_property(dev, mode, "ID_INPUT_TOUCHSCREEN", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_TOUCHSCREEN", "1"); + if (is_joystick) +- udev_builtin_add_property(dev, mode, "ID_INPUT_JOYSTICK", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_JOYSTICK", "1"); + if (is_tablet) +- udev_builtin_add_property(dev, mode, "ID_INPUT_TABLET", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_TABLET", "1"); + if (is_tablet_pad) +- udev_builtin_add_property(dev, mode, "ID_INPUT_TABLET_PAD", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_TABLET_PAD", "1"); + + return is_tablet || is_mouse || is_abs_mouse || is_touchpad || is_touchscreen || is_joystick || is_pointing_stick; + } + + /* key like devices */ + static bool test_key( +- sd_device *dev, ++ UdevEvent *event, + const unsigned long *bitmask_ev, +- const unsigned long *bitmask_key, +- EventMode mode) { ++ const unsigned long *bitmask_key) { + ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + bool found = false; + + /* do we have any KEY_* capability? */ +@@ -362,12 +365,12 @@ static bool test_key( + } + + if (found) +- udev_builtin_add_property(dev, mode, "ID_INPUT_KEY", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_KEY", "1"); + + /* the first 32 bits are ESC, numbers, and Q to D; if we have all of + * those, consider it a full keyboard; do not test KEY_RESERVED, though */ + if (FLAGS_SET(bitmask_key[0], 0xFFFFFFFE)) { +- udev_builtin_add_property(dev, mode, "ID_INPUT_KEYBOARD", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_KEYBOARD", "1"); + return true; + } + +@@ -404,28 +407,27 @@ static int builtin_input_id(UdevEvent *event, int argc, char *argv[]) { + + /* Use this as a flag that input devices were detected, so that this + * program doesn't need to be called more than once per device */ +- udev_builtin_add_property(dev, event->event_mode, "ID_INPUT", "1"); ++ udev_builtin_add_property(event, "ID_INPUT", "1"); + get_cap_mask(pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), event->event_mode); + get_cap_mask(pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), event->event_mode); + get_cap_mask(pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), event->event_mode); + get_cap_mask(pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), event->event_mode); + get_cap_mask(pdev, "properties", bitmask_props, sizeof(bitmask_props), event->event_mode); +- is_pointer = test_pointers(dev, &id, bitmask_ev, bitmask_abs, ++ is_pointer = test_pointers(event, &id, bitmask_ev, bitmask_abs, + bitmask_key, bitmask_rel, +- bitmask_props, event->event_mode); +- is_key = test_key(dev, bitmask_ev, bitmask_key, event->event_mode); ++ bitmask_props); ++ is_key = test_key(event, bitmask_ev, bitmask_key); + /* Some evdev nodes have only a scrollwheel */ + if (!is_pointer && !is_key && test_bit(EV_REL, bitmask_ev) && + (test_bit(REL_WHEEL, bitmask_rel) || test_bit(REL_HWHEEL, bitmask_rel))) +- udev_builtin_add_property(dev, event->event_mode, "ID_INPUT_KEY", "1"); ++ udev_builtin_add_property(event, "ID_INPUT_KEY", "1"); + if (test_bit(EV_SW, bitmask_ev)) +- udev_builtin_add_property(dev, event->event_mode, "ID_INPUT_SWITCH", "1"); +- ++ udev_builtin_add_property(event, "ID_INPUT_SWITCH", "1"); + } + + if (sd_device_get_sysname(dev, &sysname) >= 0 && + startswith(sysname, "event")) +- extract_info(dev, event->event_mode); ++ extract_info(event); + + return 0; + } +diff --git a/src/udev/udev-builtin-net_driver.c b/src/udev/udev-builtin-net_driver.c +index 90a9e8d22f..5e35b39ee4 100644 +--- a/src/udev/udev-builtin-net_driver.c ++++ b/src/udev/udev-builtin-net_driver.c +@@ -32,7 +32,7 @@ static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv + if (r < 0) + return log_device_warning_errno(dev, r, "Failed to get driver for '%s': %m", sysname); + +- return udev_builtin_add_property(event->dev, event->event_mode, "ID_NET_DRIVER", driver); ++ return udev_builtin_add_property(event, "ID_NET_DRIVER", driver); + } + + const UdevBuiltin udev_builtin_net_driver = { +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 09c04b9a7f..96e792bcde 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -299,12 +299,12 @@ static int pci_get_onboard_index(sd_device *dev, unsigned *ret) { + return 0; + } + +-static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *prefix, const char *suffix, EventMode mode) { ++static int names_pci_onboard(UdevEvent *event, sd_device *pci_dev, const char *prefix, const char *suffix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *port = NULL; + unsigned idx = 0; /* avoid false maybe-uninitialized warning */ + int r; + +- assert(dev); + assert(pci_dev); + assert(prefix); + +@@ -319,7 +319,7 @@ static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *pre + + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%so%u%s%s", prefix, idx, strempty(port), strempty(suffix))) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_ONBOARD", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_ONBOARD", str); + + log_device_debug(dev, "PCI onboard index identifier: index=%u port=%s %s %s", + idx, strna(port), +@@ -328,11 +328,11 @@ static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *pre + return 0; + } + +-static int names_pci_onboard_label(sd_device *dev, sd_device *pci_dev, const char *prefix, EventMode mode) { ++static int names_pci_onboard_label(UdevEvent *event, sd_device *pci_dev, const char *prefix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + const char *label; + int r; + +- assert(dev); + assert(prefix); + + /* retrieve on-board label from firmware */ +@@ -344,7 +344,7 @@ static int names_pci_onboard_label(sd_device *dev, sd_device *pci_dev, const cha + if (snprintf_ok(str, sizeof str, "%s%s", + naming_scheme_has(NAMING_LABEL_NOPREFIX) ? "" : prefix, + label)) +- udev_builtin_add_property(dev, mode, "ID_NET_LABEL_ONBOARD", str); ++ udev_builtin_add_property(event, "ID_NET_LABEL_ONBOARD", str); + + log_device_debug(dev, "Onboard label from PCI device: %s", label); + return 0; +@@ -666,13 +666,13 @@ static int get_pci_slot_specifiers( + return 0; + } + +-static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix, const char *suffix, EventMode mode) { ++static int names_pci_slot(UdevEvent *event, sd_device *pci_dev, const char *prefix, const char *suffix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *domain = NULL, *bus_and_slot = NULL, *func = NULL, *port = NULL; + uint32_t slot = 0; /* avoid false maybe-uninitialized warning */ + char str[ALTIFNAMSIZ]; + int r; + +- assert(dev); + assert(pci_dev); + assert(prefix); + +@@ -687,7 +687,7 @@ static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix + /* compose a name based on the raw kernel's PCI bus, slot numbers */ + if (snprintf_ok(str, sizeof str, "%s%s%s%s%s%s", + prefix, strempty(domain), bus_and_slot, strempty(func), strempty(port), strempty(suffix))) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_PATH", str); + + log_device_debug(dev, "PCI path identifier: domain=%s bus_and_slot=%s func=%s port=%s %s %s", + strna(domain), bus_and_slot, strna(func), strna(port), +@@ -706,7 +706,7 @@ static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix + + if (snprintf_ok(str, sizeof str, "%s%ss%"PRIu32"%s%s%s", + prefix, strempty(domain), slot, strempty(func), strempty(port), strempty(suffix))) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_SLOT", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_SLOT", str); + + log_device_debug(dev, "PCI slot identifier: domain=%s slot=%"PRIu32" func=%s port=%s %s %s", + strna(domain), slot, strna(func), strna(port), +@@ -715,12 +715,12 @@ static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix + return 0; + } + +-static int names_vio(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_vio(UdevEvent *event, const char *prefix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *s = NULL; + unsigned slotid; + int r; + +- assert(dev); + assert(prefix); + + /* get ibmveth/ibmvnic slot-based names. */ +@@ -754,20 +754,20 @@ static int names_vio(sd_device *dev, const char *prefix, EventMode mode) { + + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%sv%u", prefix, slotid)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_SLOT", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_SLOT", str); + log_device_debug(dev, "Vio slot identifier: slotid=%u %s %s", + slotid, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + return 0; + } + +-static int names_platform(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_platform(UdevEvent *event, const char *prefix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *p = NULL; + const char *validchars; + char *vendor, *model_str, *instance_str; + unsigned model, instance; + int r; + +- assert(dev); + assert(prefix); + + /* get ACPI path names for ARM64 platform devices */ +@@ -816,18 +816,18 @@ static int names_platform(sd_device *dev, const char *prefix, EventMode mode) { + + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%sa%s%xi%u", prefix, vendor, model, instance)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_PATH", str); + log_device_debug(dev, "Platform identifier: vendor=%s model=%x instance=%u %s %s", + vendor, model, instance, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + return 0; + } + +-static int names_devicetree(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_devicetree(UdevEvent *event, const char *prefix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_(sd_device_unrefp) sd_device *aliases_dev = NULL, *ofnode_dev = NULL, *devicetree_dev = NULL; + const char *ofnode_path, *ofnode_syspath, *devicetree_syspath; + int r; + +- assert(dev); + assert(prefix); + + if (!naming_scheme_has(NAMING_DEVICETREE_ALIASES)) +@@ -923,7 +923,7 @@ static int names_devicetree(sd_device *dev, const char *prefix, EventMode mode) + + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%sd%u", prefix, i)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_ONBOARD", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_ONBOARD", str); + log_device_debug(dev, "DeviceTree identifier: alias_index=%u %s \"%s\"", + i, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + return 0; +@@ -932,12 +932,11 @@ static int names_devicetree(sd_device *dev, const char *prefix, EventMode mode) + return -ENOENT; + } + +-static int names_pci(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_pci(UdevEvent *event, const char *prefix) { ++ sd_device *parent, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; + _cleanup_free_ char *virtfn_suffix = NULL; +- sd_device *parent; + +- assert(dev); + assert(prefix); + + /* check if our direct parent is a PCI device with no other bus in-between */ +@@ -949,10 +948,10 @@ static int names_pci(sd_device *dev, const char *prefix, EventMode mode) { + get_virtfn_info(parent, &physfn_pcidev, &virtfn_suffix) >= 0) + parent = physfn_pcidev; + else +- (void) names_pci_onboard_label(dev, parent, prefix, mode); ++ (void) names_pci_onboard_label(event, parent, prefix); + +- (void) names_pci_onboard(dev, parent, prefix, virtfn_suffix, mode); +- (void) names_pci_slot(dev, parent, prefix, virtfn_suffix, mode); ++ (void) names_pci_onboard(event, parent, prefix, virtfn_suffix); ++ (void) names_pci_slot(event, parent, prefix, virtfn_suffix); + return 0; + } + +@@ -1015,12 +1014,11 @@ static int get_usb_specifier(sd_device *dev, char **ret) { + return 0; + } + +-static int names_usb(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_usb(UdevEvent *event, const char *prefix) { ++ sd_device *usbdev, *pcidev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *suffix = NULL; +- sd_device *usbdev, *pcidev; + int r; + +- assert(dev); + assert(prefix); + + /* USB device */ +@@ -1036,7 +1034,7 @@ static int names_usb(sd_device *dev, const char *prefix, EventMode mode) { + /* If the USB bus is on PCI bus, then suffix the USB specifier to the name based on the PCI bus. */ + r = sd_device_get_parent_with_subsystem_devtype(usbdev, "pci", NULL, &pcidev); + if (r >= 0) +- return names_pci_slot(dev, pcidev, prefix, suffix, mode); ++ return names_pci_slot(event, pcidev, prefix, suffix); + + if (r != -ENOENT || !naming_scheme_has(NAMING_USB_HOST)) + return log_device_debug_errno(usbdev, r, "Failed to get parent PCI bus: %m"); +@@ -1044,7 +1042,7 @@ static int names_usb(sd_device *dev, const char *prefix, EventMode mode) { + /* Otherwise, e.g. on-chip asics that have USB ports, use the USB specifier as is. */ + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%s%s", prefix, suffix)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_PATH", str); + + return 0; + } +@@ -1079,12 +1077,11 @@ static int get_bcma_specifier(sd_device *dev, char **ret) { + return 0; + } + +-static int names_bcma(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_bcma(UdevEvent *event, const char *prefix) { ++ sd_device *bcmadev, *pcidev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *suffix = NULL; +- sd_device *bcmadev, *pcidev; + int r; + +- assert(dev); + assert(prefix); + + r = sd_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL, &bcmadev); +@@ -1099,16 +1096,15 @@ static int names_bcma(sd_device *dev, const char *prefix, EventMode mode) { + if (r < 0) + return r; + +- return names_pci_slot(dev, pcidev, prefix, suffix, mode); ++ return names_pci_slot(event, pcidev, prefix, suffix); + } + +-static int names_ccw(sd_device *dev, const char *prefix, EventMode mode) { +- sd_device *cdev; ++static int names_ccw(UdevEvent *event, const char *prefix) { ++ sd_device *cdev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + const char *bus_id; + size_t bus_id_start, bus_id_len; + int r; + +- assert(dev); + assert(prefix); + + /* get path names for Linux on System z network devices */ +@@ -1144,17 +1140,17 @@ static int names_ccw(sd_device *dev, const char *prefix, EventMode mode) { + /* Use the CCW bus-ID as network device name */ + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%sc%s", prefix, bus_id)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_PATH", str); + log_device_debug(dev, "CCW identifier: ccw_busid=%s %s \"%s\"", + bus_id, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + return 0; + } + + /* IEEE Organizationally Unique Identifier vendor string */ +-static int ieee_oui(sd_device *dev, const struct hw_addr_data *hw_addr, EventMode mode) { ++static int ieee_oui(UdevEvent *event, const struct hw_addr_data *hw_addr) { + char str[32]; + +- assert(dev); ++ assert(event); + assert(hw_addr); + + if (hw_addr->length != 6) +@@ -1174,16 +1170,16 @@ static int ieee_oui(sd_device *dev, const struct hw_addr_data *hw_addr, EventMod + hw_addr->bytes[4], + hw_addr->bytes[5]); + +- return udev_builtin_hwdb_lookup(dev, NULL, str, NULL, mode); ++ return udev_builtin_hwdb_lookup(event, NULL, str, NULL); + } + +-static int names_mac(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_mac(UdevEvent *event, const char *prefix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + unsigned iftype, assign_type; + struct hw_addr_data hw_addr; + const char *s; + int r; + +- assert(dev); + assert(prefix); + + r = device_get_sysattr_unsigned_filtered(dev, "type", &iftype); +@@ -1221,22 +1217,21 @@ static int names_mac(sd_device *dev, const char *prefix, EventMode mode) { + + char str[ALTIFNAMSIZ]; + xsprintf(str, "%sx%s", prefix, HW_ADDR_TO_STR_FULL(&hw_addr, HW_ADDR_TO_STRING_NO_COLON)); +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_MAC", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_MAC", str); + log_device_debug(dev, "MAC address identifier: hw_addr=%s %s %s", + HW_ADDR_TO_STR(&hw_addr), + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + +- (void) ieee_oui(dev, &hw_addr, mode); ++ (void) ieee_oui(event, &hw_addr); + return 0; + } + +-static int names_netdevsim(sd_device *dev, const char *prefix, EventMode mode) { +- sd_device *netdevsimdev; ++static int names_netdevsim(UdevEvent *event, const char *prefix) { ++ sd_device *netdevsimdev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + const char *sysnum, *phys_port_name; + unsigned addr; + int r; + +- assert(dev); + assert(prefix); + + /* get netdevsim path names */ +@@ -1265,19 +1260,19 @@ static int names_netdevsim(sd_device *dev, const char *prefix, EventMode mode) { + + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%si%un%s", prefix, addr, phys_port_name)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_PATH", str); + log_device_debug(dev, "Netdevsim identifier: address=%u, port_name=%s %s %s", + addr, phys_port_name, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + return 0; + } + +-static int names_xen(sd_device *dev, const char *prefix, EventMode mode) { ++static int names_xen(UdevEvent *event, const char *prefix) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + _cleanup_free_ char *vif = NULL; + const char *p; + unsigned id; + int r; + +- assert(dev); + assert(prefix); + + /* get xen vif "slot" based names. */ +@@ -1305,7 +1300,7 @@ static int names_xen(sd_device *dev, const char *prefix, EventMode mode) { + + char str[ALTIFNAMSIZ]; + if (snprintf_ok(str, sizeof str, "%sX%u", prefix, id)) +- udev_builtin_add_property(dev, mode, "ID_NET_NAME_SLOT", str); ++ udev_builtin_add_property(event, "ID_NET_NAME_SLOT", str); + log_device_debug(dev, "Xen identifier: id=%u %s %s", + id, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); + return 0; +@@ -1383,18 +1378,18 @@ static int builtin_net_id(UdevEvent *event, int argc, char *argv[]) { + return 0; + } + +- udev_builtin_add_property(dev, event->event_mode, "ID_NET_NAMING_SCHEME", naming_scheme()->name); +- +- (void) names_mac(dev, prefix, event->event_mode); +- (void) names_devicetree(dev, prefix, event->event_mode); +- (void) names_ccw(dev, prefix, event->event_mode); +- (void) names_vio(dev, prefix, event->event_mode); +- (void) names_platform(dev, prefix, event->event_mode); +- (void) names_netdevsim(dev, prefix, event->event_mode); +- (void) names_xen(dev, prefix, event->event_mode); +- (void) names_pci(dev, prefix, event->event_mode); +- (void) names_usb(dev, prefix, event->event_mode); +- (void) names_bcma(dev, prefix, event->event_mode); ++ udev_builtin_add_property(event, "ID_NET_NAMING_SCHEME", naming_scheme()->name); ++ ++ (void) names_mac(event, prefix); ++ (void) names_devicetree(event, prefix); ++ (void) names_ccw(event, prefix); ++ (void) names_vio(event, prefix); ++ (void) names_platform(event, prefix); ++ (void) names_netdevsim(event, prefix); ++ (void) names_xen(event, prefix); ++ (void) names_pci(event, prefix); ++ (void) names_usb(event, prefix); ++ (void) names_bcma(event, prefix); + + return 0; + } +diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c +index 8cfcaa932f..4500a69c68 100644 +--- a/src/udev/udev-builtin-net_setup_link.c ++++ b/src/udev/udev-builtin-net_setup_link.c +@@ -30,13 +30,13 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv) { + device_action_to_string(action)); + + /* Import previously assigned .link file name. */ +- (void) udev_builtin_import_property(dev, event->dev_db_clone, event->event_mode, "ID_NET_LINK_FILE"); +- (void) udev_builtin_import_property(dev, event->dev_db_clone, event->event_mode, "ID_NET_LINK_FILE_DROPINS"); ++ (void) udev_builtin_import_property(event, "ID_NET_LINK_FILE"); ++ (void) udev_builtin_import_property(event, "ID_NET_LINK_FILE_DROPINS"); + + /* Set ID_NET_NAME= with the current interface name. */ + const char *value; + if (sd_device_get_sysname(dev, &value) >= 0) +- (void) udev_builtin_add_property(dev, event->event_mode, "ID_NET_NAME", value); ++ (void) udev_builtin_add_property(event, "ID_NET_NAME", value); + + return 0; + } +@@ -59,7 +59,7 @@ 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->event_mode); ++ r = link_apply_config(ctx, &event->rtnl, link, event); + if (r == -ENODEV) + log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring."); + else if (r < 0) +diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c +index 8ba5f2e358..d6ea471482 100644 +--- a/src/udev/udev-builtin-path_id.c ++++ b/src/udev/udev-builtin-path_id.c +@@ -639,10 +639,10 @@ static int find_real_nvme_parent(sd_device *dev, sd_device **ret) { + return 0; + } + +-static void add_id_with_usb_revision(sd_device *dev, EventMode mode, char *path) { ++static void add_id_with_usb_revision(UdevEvent *event, char *path) { + char *p; + +- assert(dev); ++ assert(event); + assert(path); + + /* When the path contains the USB revision, let's adds ID_PATH_WITH_USB_REVISION property and +@@ -656,13 +656,13 @@ static void add_id_with_usb_revision(sd_device *dev, EventMode mode, char *path) + if (p[1] != '-') + return; + +- (void) udev_builtin_add_property(dev, mode, "ID_PATH_WITH_USB_REVISION", path); ++ (void) udev_builtin_add_property(event, "ID_PATH_WITH_USB_REVISION", path); + + /* Drop the USB revision specifier for backward compatibility. */ + memmove(p - 1, p + 1, strlen(p + 1) + 1); + } + +-static void add_id_tag(sd_device *dev, EventMode mode, const char *path) { ++static void add_id_tag(UdevEvent *event, const char *path) { + char tag[UDEV_NAME_SIZE]; + size_t i = 0; + +@@ -690,7 +690,7 @@ static void add_id_tag(sd_device *dev, EventMode mode, const char *path) { + i--; + tag[i] = '\0'; + +- (void) udev_builtin_add_property(dev, mode, "ID_PATH_TAG", tag); ++ (void) udev_builtin_add_property(event, "ID_PATH_TAG", tag); + } + + static int builtin_path_id(UdevEvent *event, int argc, char *argv[]) { +@@ -848,11 +848,11 @@ static int builtin_path_id(UdevEvent *event, int argc, char *argv[]) { + if (device_in_subsystem(dev, "block") && !supported_transport) + return -ENOENT; + +- add_id_with_usb_revision(dev, event->event_mode, path); ++ add_id_with_usb_revision(event, path); + +- (void) udev_builtin_add_property(dev, event->event_mode, "ID_PATH", path); ++ (void) udev_builtin_add_property(event, "ID_PATH", path); + +- add_id_tag(dev, event->event_mode, path); ++ add_id_tag(event, path); + + /* + * Compatible link generation for ATA devices +@@ -860,7 +860,7 @@ static int builtin_path_id(UdevEvent *event, int argc, char *argv[]) { + * ID_PATH_ATA_COMPAT + */ + if (compat_path) +- (void) udev_builtin_add_property(dev, event->event_mode, "ID_PATH_ATA_COMPAT", compat_path); ++ (void) udev_builtin_add_property(event, "ID_PATH_ATA_COMPAT", compat_path); + + return 0; + } +diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c +index 9abdec3591..7148c80194 100644 +--- a/src/udev/udev-builtin-usb_id.c ++++ b/src/udev/udev-builtin-usb_id.c +@@ -413,55 +413,55 @@ fallback: + if (sd_device_get_property_value(dev, "ID_BUS", NULL) >= 0) + log_device_debug(dev, "ID_BUS property is already set, setting only properties prefixed with \"ID_USB_\"."); + else { +- udev_builtin_add_property(dev, event->event_mode, "ID_BUS", "usb"); ++ udev_builtin_add_property(event, "ID_BUS", "usb"); + +- udev_builtin_add_property(dev, event->event_mode, "ID_MODEL", model_str); +- udev_builtin_add_property(dev, event->event_mode, "ID_MODEL_ENC", model_str_enc); +- udev_builtin_add_property(dev, event->event_mode, "ID_MODEL_ID", product_id); ++ udev_builtin_add_property(event, "ID_MODEL", model_str); ++ udev_builtin_add_property(event, "ID_MODEL_ENC", model_str_enc); ++ udev_builtin_add_property(event, "ID_MODEL_ID", product_id); + +- udev_builtin_add_property(dev, event->event_mode, "ID_SERIAL", serial); ++ udev_builtin_add_property(event, "ID_SERIAL", serial); + if (!isempty(serial_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_SERIAL_SHORT", serial_str); ++ udev_builtin_add_property(event, "ID_SERIAL_SHORT", serial_str); + +- udev_builtin_add_property(dev, event->event_mode, "ID_VENDOR", vendor_str); +- udev_builtin_add_property(dev, event->event_mode, "ID_VENDOR_ENC", vendor_str_enc); +- udev_builtin_add_property(dev, event->event_mode, "ID_VENDOR_ID", vendor_id); ++ udev_builtin_add_property(event, "ID_VENDOR", vendor_str); ++ udev_builtin_add_property(event, "ID_VENDOR_ENC", vendor_str_enc); ++ udev_builtin_add_property(event, "ID_VENDOR_ID", vendor_id); + +- udev_builtin_add_property(dev, event->event_mode, "ID_REVISION", revision_str); ++ udev_builtin_add_property(event, "ID_REVISION", revision_str); + + if (!isempty(type_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_TYPE", type_str); ++ udev_builtin_add_property(event, "ID_TYPE", type_str); + + if (!isempty(instance_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_INSTANCE", instance_str); ++ udev_builtin_add_property(event, "ID_INSTANCE", instance_str); + } + + /* Also export the same values in the above by prefixing ID_USB_. */ +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_MODEL", model_str); +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_MODEL_ENC", model_str_enc); +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_MODEL_ID", product_id); +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_SERIAL", serial); ++ udev_builtin_add_property(event, "ID_USB_MODEL", model_str); ++ udev_builtin_add_property(event, "ID_USB_MODEL_ENC", model_str_enc); ++ udev_builtin_add_property(event, "ID_USB_MODEL_ID", product_id); ++ udev_builtin_add_property(event, "ID_USB_SERIAL", serial); + if (!isempty(serial_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_SERIAL_SHORT", serial_str); ++ udev_builtin_add_property(event, "ID_USB_SERIAL_SHORT", serial_str); + +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_VENDOR", vendor_str); +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_VENDOR_ENC", vendor_str_enc); +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_VENDOR_ID", vendor_id); ++ udev_builtin_add_property(event, "ID_USB_VENDOR", vendor_str); ++ udev_builtin_add_property(event, "ID_USB_VENDOR_ENC", vendor_str_enc); ++ udev_builtin_add_property(event, "ID_USB_VENDOR_ID", vendor_id); + +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_REVISION", revision_str); ++ udev_builtin_add_property(event, "ID_USB_REVISION", revision_str); + + if (!isempty(type_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_TYPE", type_str); ++ udev_builtin_add_property(event, "ID_USB_TYPE", type_str); + + if (!isempty(instance_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_INSTANCE", instance_str); ++ udev_builtin_add_property(event, "ID_USB_INSTANCE", instance_str); + + if (!isempty(packed_if_str)) +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_INTERFACES", packed_if_str); ++ udev_builtin_add_property(event, "ID_USB_INTERFACES", packed_if_str); + if (ifnum) +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_INTERFACE_NUM", ifnum); ++ udev_builtin_add_property(event, "ID_USB_INTERFACE_NUM", ifnum); + if (driver) +- udev_builtin_add_property(dev, event->event_mode, "ID_USB_DRIVER", driver); ++ udev_builtin_add_property(event, "ID_USB_DRIVER", driver); + return 0; + } + +diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c +index 69401aa2e0..2118c2f3df 100644 +--- a/src/udev/udev-builtin.c ++++ b/src/udev/udev-builtin.c +@@ -120,10 +120,10 @@ int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *comma + return builtins[cmd]->cmd(event, strv_length(argv), argv); + } + +-int udev_builtin_add_property(sd_device *dev, EventMode mode, const char *key, const char *val) { ++int udev_builtin_add_property(UdevEvent *event, const char *key, const char *val) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + int r; + +- assert(dev); + assert(key); + + r = device_add_property(dev, key, val); +@@ -131,18 +131,18 @@ int udev_builtin_add_property(sd_device *dev, EventMode mode, const char *key, c + return log_device_debug_errno(dev, r, "Failed to add property '%s%s%s'", + key, val ? "=" : "", strempty(val)); + +- if (mode == EVENT_UDEVADM_TEST_BUILTIN) ++ if (event->event_mode == EVENT_UDEVADM_TEST_BUILTIN) + printf("%s=%s\n", key, strempty(val)); + + return 0; + } + +-int udev_builtin_add_propertyf(sd_device *dev, EventMode mode, const char *key, const char *valf, ...) { ++int udev_builtin_add_propertyf(UdevEvent *event, const char *key, const char *valf, ...) { + _cleanup_free_ char *val = NULL; + va_list ap; + int r; + +- assert(dev); ++ assert(event); + assert(key); + assert(valf); + +@@ -152,26 +152,26 @@ int udev_builtin_add_propertyf(sd_device *dev, EventMode mode, const char *key, + if (r < 0) + return log_oom_debug(); + +- return udev_builtin_add_property(dev, mode, key, val); ++ return udev_builtin_add_property(event, key, val); + } + +-int udev_builtin_import_property(sd_device *dev, sd_device *src, EventMode mode, const char *key) { ++int udev_builtin_import_property(UdevEvent *event, const char *key) { + const char *val; + int r; + +- assert(dev); +- assert(key); ++ assert(event); ++ assert(event->dev); + +- if (!src) ++ if (!event->dev_db_clone) + return 0; + +- r = sd_device_get_property_value(src, key, &val); ++ r = sd_device_get_property_value(event->dev_db_clone, key, &val); + if (r == -ENOENT) + return 0; + if (r < 0) +- return log_device_debug_errno(src, r, "Failed to get property \"%s\", ignoring: %m", key); ++ return log_device_debug_errno(event->dev_db_clone, r, "Failed to get property \"%s\", ignoring: %m", key); + +- r = udev_builtin_add_property(dev, mode, key, val); ++ r = udev_builtin_add_property(event, key, val); + if (r < 0) + return r; + +diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h +index 2433dfa4d4..8c2016e5f0 100644 +--- a/src/udev/udev-builtin.h ++++ b/src/udev/udev-builtin.h +@@ -60,8 +60,7 @@ 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); +-int udev_builtin_add_property(sd_device *dev, EventMode mode, const char *key, const char *val); +-int udev_builtin_add_propertyf(sd_device *dev, EventMode mode, const char *key, const char *valf, ...) _printf_(4, 5); +-int udev_builtin_import_property(sd_device *dev, sd_device *src, EventMode mode, const char *key); +-int udev_builtin_hwdb_lookup(sd_device *dev, const char *prefix, const char *modalias, +- const char *filter, EventMode mode); ++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); ++int udev_builtin_hwdb_lookup(UdevEvent *event, const char *prefix, const char *modalias, const char *filter); diff --git a/SOURCES/0314-udev-introduce-reference-counter-for-UdevEvent.patch b/SOURCES/0314-udev-introduce-reference-counter-for-UdevEvent.patch new file mode 100644 index 0000000000000000000000000000000000000000..3d6a76b4cce2258152d73c2c7b8367304477d753 --- /dev/null +++ b/SOURCES/0314-udev-introduce-reference-counter-for-UdevEvent.patch @@ -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; diff --git a/SOURCES/0315-udev-net-make-Link-object-take-reference-to-UdevEven.patch b/SOURCES/0315-udev-net-make-Link-object-take-reference-to-UdevEven.patch new file mode 100644 index 0000000000000000000000000000000000000000..6899e284f7b54b76212782bb1f86146a00910990 --- /dev/null +++ b/SOURCES/0315-udev-net-make-Link-object-take-reference-to-UdevEven.patch @@ -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; + } + diff --git a/SOURCES/0316-udev-move-parsers-for-config-file-kerenel-command-li.patch b/SOURCES/0316-udev-move-parsers-for-config-file-kerenel-command-li.patch new file mode 100644 index 0000000000000000000000000000000000000000..a4976a5a65157ffacea0fb05566df095d03ea92e --- /dev/null +++ b/SOURCES/0316-udev-move-parsers-for-config-file-kerenel-command-li.patch @@ -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; diff --git a/SOURCES/0317-udev-config-introduce-UdevConfig.patch b/SOURCES/0317-udev-config-introduce-UdevConfig.patch new file mode 100644 index 0000000000000000000000000000000000000000..b931b8fa235defd46edc1321d0bb5dd335194f5a --- /dev/null +++ b/SOURCES/0317-udev-config-introduce-UdevConfig.patch @@ -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 */ diff --git a/SOURCES/0318-udev-reload-.rules-files-and-builtins-only-when-nece.patch b/SOURCES/0318-udev-reload-.rules-files-and-builtins-only-when-nece.patch new file mode 100644 index 0000000000000000000000000000000000000000..31effe3fa97ab251c286888f29a7fd092f6dd27c --- /dev/null +++ b/SOURCES/0318-udev-reload-.rules-files-and-builtins-only-when-nece.patch @@ -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"); diff --git a/SOURCES/0319-udev-also-reload-udev.conf-when-explicitly-requested.patch b/SOURCES/0319-udev-also-reload-udev.conf-when-explicitly-requested.patch new file mode 100644 index 0000000000000000000000000000000000000000..946f84e2ff908b4eb72e53e91e899adf4169094d --- /dev/null +++ b/SOURCES/0319-udev-also-reload-udev.conf-when-explicitly-requested.patch @@ -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); diff --git a/SOURCES/0320-TEST-17-use-udevadm-control-reload-or-systemctl-relo.patch b/SOURCES/0320-TEST-17-use-udevadm-control-reload-or-systemctl-relo.patch new file mode 100644 index 0000000000000000000000000000000000000000..34e429e9d6f203cf6393ab4a7a8f1eb94992503a --- /dev/null +++ b/SOURCES/0320-TEST-17-use-udevadm-control-reload-or-systemctl-relo.patch @@ -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') diff --git a/SOURCES/0321-udevd-add-missing-header-for-glibc-2.34.patch b/SOURCES/0321-udevd-add-missing-header-for-glibc-2.34.patch new file mode 100644 index 0000000000000000000000000000000000000000..89331976dc7b2b52caae815bffe34ab288638fb0 --- /dev/null +++ b/SOURCES/0321-udevd-add-missing-header-for-glibc-2.34.patch @@ -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" diff --git a/SOURCES/0322-meson-sort-source-files.patch b/SOURCES/0322-meson-sort-source-files.patch new file mode 100644 index 0000000000000000000000000000000000000000..99c76e9bcfb16d7096298c4f87b5c72682432d4d --- /dev/null +++ b/SOURCES/0322-meson-sort-source-files.patch @@ -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 diff --git a/SOURCES/0323-sd-json-introduce-json_dispatch_log_level.patch b/SOURCES/0323-sd-json-introduce-json_dispatch_log_level.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1df18eb86e8e09f7a4e7a379688461bee8db8bb --- /dev/null +++ b/SOURCES/0323-sd-json-introduce-json_dispatch_log_level.patch @@ -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); + diff --git a/SOURCES/0324-varlink-invert-uid-check-to-reduce-call-of-getuid.patch b/SOURCES/0324-varlink-invert-uid-check-to-reduce-call-of-getuid.patch new file mode 100644 index 0000000000000000000000000000000000000000..0e44a088eb8f66486761b04f3e3e38c4ffacd7f3 --- /dev/null +++ b/SOURCES/0324-varlink-invert-uid-check-to-reduce-call-of-getuid.patch @@ -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); diff --git a/SOURCES/0325-string-util-modernize-split_pair.patch b/SOURCES/0325-string-util-modernize-split_pair.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b28cc47d3ac6137d981f5b72b3d92d41fcc57f8 --- /dev/null +++ b/SOURCES/0325-string-util-modernize-split_pair.patch @@ -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, "="); + } diff --git a/SOURCES/0326-udev-split-manager_init-and-manager_main-into-small-.patch b/SOURCES/0326-udev-split-manager_init-and-manager_main-into-small-.patch new file mode 100644 index 0000000000000000000000000000000000000000..388a6ad13f15545598a2bddcc62d267a6e874f05 --- /dev/null +++ b/SOURCES/0326-udev-split-manager_init-and-manager_main-into-small-.patch @@ -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); + diff --git a/SOURCES/0327-udev-config-split-on_ctrl_msg-into-small-pieces.patch b/SOURCES/0327-udev-config-split-on_ctrl_msg-into-small-pieces.patch new file mode 100644 index 0000000000000000000000000000000000000000..642910a83ff45ea6f0b67ab1e39b24b8438c2e3a --- /dev/null +++ b/SOURCES/0327-udev-config-split-on_ctrl_msg-into-small-pieces.patch @@ -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); diff --git a/SOURCES/0328-udev-introduce-udev_property_name_is_valid-and-frien.patch b/SOURCES/0328-udev-introduce-udev_property_name_is_valid-and-frien.patch new file mode 100644 index 0000000000000000000000000000000000000000..37ecd1fa4ff9555e6c1343925636496daa39792a --- /dev/null +++ b/SOURCES/0328-udev-introduce-udev_property_name_is_valid-and-frien.patch @@ -0,0 +1,68 @@ +From 1ffd9f7e201e155e3301445a9db00dffabe1827a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 4 Jan 2025 21:07:41 +0900 +Subject: [PATCH] udev: introduce udev_property_name_is_valid() and friends + +(cherry picked from commit 4c547d216aad4a61d58a6962d0256da3c6ae6a71) + +Resolves: RHEL-75774 +--- + src/udev/net/link-config.c | 7 ++----- + src/udev/udev-def.h | 8 ++++++++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 7d4e334503..5a4b7261bb 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -15,7 +15,6 @@ + #include "creds-util.h" + #include "device-private.h" + #include "device-util.h" +-#include "env-util.h" + #include "escape.h" + #include "ethtool-util.h" + #include "fd-util.h" +@@ -1111,8 +1110,7 @@ int config_parse_udev_property( + continue; + } + +- /* The restriction for udev property is not clear. Let's apply the one for environment variable here. */ +- if (!env_assignment_is_valid(resolved)) { ++ if (!udev_property_assignment_is_valid(resolved)) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid udev property, ignoring assignment: %s", word); + continue; +@@ -1181,8 +1179,7 @@ int config_parse_udev_property_name( + continue; + } + +- /* The restriction for udev property is not clear. Let's apply the one for environment variable here. */ +- if (!env_name_is_valid(resolved)) { ++ if (!udev_property_name_is_valid(resolved)) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid udev property name, ignoring assignment: %s", resolved); + continue; +diff --git a/src/udev/udev-def.h b/src/udev/udev-def.h +index 9d9fc78247..ed231764bc 100644 +--- a/src/udev/udev-def.h ++++ b/src/udev/udev-def.h +@@ -3,6 +3,8 @@ + + #include <errno.h> + ++#include "env-util.h" ++ + #define UDEV_NAME_SIZE 512 + #define UDEV_PATH_SIZE 1024 + #define UDEV_LINE_SIZE 16384 +@@ -78,3 +80,9 @@ typedef enum UdevReloadFlags { + UDEV_RELOAD_KILL_WORKERS = 1u << (_UDEV_BUILTIN_MAX + 0), + UDEV_RELOAD_RULES = 1u << (_UDEV_BUILTIN_MAX + 1), + } UdevReloadFlags; ++ ++/* udev properties are conceptually close to environment variables. Let's validate names, values, and ++ * assignments in the same way. */ ++#define udev_property_name_is_valid(x) env_name_is_valid(x) ++#define udev_property_value_is_valid(x) env_value_is_valid(x) ++#define udev_property_assignment_is_valid(x) env_assignment_is_valid(x) diff --git a/SOURCES/0329-udev-ctrl-refuse-ENV-control-message-with-invalid-en.patch b/SOURCES/0329-udev-ctrl-refuse-ENV-control-message-with-invalid-en.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b64be179cd716043efb8057c404fe5216480b71 --- /dev/null +++ b/SOURCES/0329-udev-ctrl-refuse-ENV-control-message-with-invalid-en.patch @@ -0,0 +1,47 @@ +From 618742f92e739fc800d066b17bccd1e44cfc6981 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 22 Dec 2024 06:34:33 +0900 +Subject: [PATCH] udev-ctrl: refuse ENV control message with invalid + environment assignment + +Previously, udevd accepts an arbitrary pair of key and value. +Let's make the environment variable assignment more strict for safety. + +Note, we already refuse environment variables with the same way in +net/link-config.c. + +(cherry picked from commit bbb0dbe6b1fad7c8d8250f5dff334a2de8766559) + +Resolves: RHEL-75774 +--- + src/udev/udev-manager.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c +index 2c87e8bb9e..83b0a90ccf 100644 +--- a/src/udev/udev-manager.c ++++ b/src/udev/udev-manager.c +@@ -871,19 +871,15 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl + log_debug("Received udev control message (RELOAD)"); + manager_reload(manager, /* force = */ true); + break; +- case UDEV_CTRL_SET_ENV: { +- const char *eq; +- +- eq = strchr(value->buf, '='); +- if (!eq) { +- log_error("Invalid key format '%s'", value->buf); +- return 1; ++ case UDEV_CTRL_SET_ENV: ++ if (!udev_property_assignment_is_valid(value->buf)) { ++ log_debug("Received invalid udev control message(SET_ENV, %s), ignoring.", value->buf); ++ break; + } + + 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: + if (value->intval < 0) { + log_debug("Received invalid udev control message (SET_MAX_CHILDREN, %i), ignoring.", value->intval); diff --git a/SOURCES/0330-varlink-add-comments-for-io.systemd.service-interfac.patch b/SOURCES/0330-varlink-add-comments-for-io.systemd.service-interfac.patch new file mode 100644 index 0000000000000000000000000000000000000000..7499d4a730641075272684873077aa79e4f988e1 --- /dev/null +++ b/SOURCES/0330-varlink-add-comments-for-io.systemd.service-interfac.patch @@ -0,0 +1,35 @@ +From b0559cceb8b4dd37db4b8dd5e7870fcc784fe8d0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 4 Jan 2025 21:51:09 +0900 +Subject: [PATCH] varlink: add comments for io.systemd.service interface + +(cherry picked from commit 8252b74f2dda823ac8d4ff9e9b49f9c981136375) + +Resolves: RHEL-75774 +--- + src/shared/varlink-io.systemd.service.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/shared/varlink-io.systemd.service.c b/src/shared/varlink-io.systemd.service.c +index 06e32f9bf6..f34d5cfead 100644 +--- a/src/shared/varlink-io.systemd.service.c ++++ b/src/shared/varlink-io.systemd.service.c +@@ -11,13 +11,18 @@ static SD_VARLINK_DEFINE_METHOD(Reload); + + static SD_VARLINK_DEFINE_METHOD( + SetLogLevel, ++ SD_VARLINK_FIELD_COMMENT("The maximum log level."), + SD_VARLINK_DEFINE_INPUT(level, SD_VARLINK_INT, 0)); + + SD_VARLINK_DEFINE_INTERFACE( + io_systemd_service, + "io.systemd.service", ++ SD_VARLINK_INTERFACE_COMMENT("An interface to control basic properties of systemd services."), ++ SD_VARLINK_SYMBOL_COMMENT("Checks if the service is running."), + &vl_method_Ping, ++ SD_VARLINK_SYMBOL_COMMENT("Reloads configurations."), + &vl_method_Reload, ++ SD_VARLINK_SYMBOL_COMMENT("Sets the maximum log level."), + &vl_method_SetLogLevel); + + int varlink_method_ping(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { diff --git a/SOURCES/0331-sd-varlink-introduce-sd_varlink_get_current_method.patch b/SOURCES/0331-sd-varlink-introduce-sd_varlink_get_current_method.patch new file mode 100644 index 0000000000000000000000000000000000000000..82a183127a4ffb88064aa0212708e5ae703b12cf --- /dev/null +++ b/SOURCES/0331-sd-varlink-introduce-sd_varlink_get_current_method.patch @@ -0,0 +1,69 @@ +From d0199162ba3426385535ff7bcef1955c8fc54e9b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 4 Jan 2025 21:18:42 +0900 +Subject: [PATCH] sd-varlink: introduce sd_varlink_get_current_method() + +(cherry picked from commit ffe292330337b4c78932cde808463752196f531f) + +Resolves: RHEL-75774 +--- + src/libsystemd/libsystemd.sym | 5 +++++ + src/libsystemd/sd-varlink/sd-varlink.c | 19 +++++++++++++++++++ + src/systemd/sd-varlink.h | 1 + + 3 files changed, 25 insertions(+) + +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index a76dc7e4ae..4dbe4e3c76 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -1059,3 +1059,8 @@ global: + sd_device_monitor_get_timeout; + sd_device_monitor_receive; + } LIBSYSTEMD_256; ++ ++LIBSYSTEMD_258 { ++global: ++ sd_varlink_get_current_method; ++} LIBSYSTEMD_257; +diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c +index 7038cba5db..5f3b17199d 100644 +--- a/src/libsystemd/sd-varlink/sd-varlink.c ++++ b/src/libsystemd/sd-varlink/sd-varlink.c +@@ -1542,6 +1542,25 @@ _public_ int sd_varlink_dispatch_again(sd_varlink *v) { + return 0; + } + ++_public_ int sd_varlink_get_current_method(sd_varlink *v, const char **ret) { ++ assert_return(v, -EINVAL); ++ ++ if (!v->current) ++ return -ENODATA; ++ ++ sd_json_variant *p = sd_json_variant_by_key(v->current, "method"); ++ if (!p) ++ return -ENODATA; ++ ++ const char *s = sd_json_variant_string(p); ++ if (!s) ++ return -ENODATA; ++ ++ if (ret) ++ *ret = s; ++ return 0; ++} ++ + _public_ int sd_varlink_get_current_parameters(sd_varlink *v, sd_json_variant **ret) { + sd_json_variant *p; + +diff --git a/src/systemd/sd-varlink.h b/src/systemd/sd-varlink.h +index 17cf8b7386..9401d417b2 100644 +--- a/src/systemd/sd-varlink.h ++++ b/src/systemd/sd-varlink.h +@@ -176,6 +176,7 @@ int sd_varlink_notifyb(sd_varlink *v, ...); + int sd_varlink_dispatch_again(sd_varlink *v); + + /* Get the currently processed incoming message */ ++int sd_varlink_get_current_method(sd_varlink *v, const char **ret); + int sd_varlink_get_current_parameters(sd_varlink *v, sd_json_variant **ret); + + /* Parsing incoming data via json_dispatch() and generate a nice error on parse errors */ diff --git a/SOURCES/0332-TEST-17-UDEV-wait-for-udevd-being-restarted-after-ex.patch b/SOURCES/0332-TEST-17-UDEV-wait-for-udevd-being-restarted-after-ex.patch new file mode 100644 index 0000000000000000000000000000000000000000..12887b0285426b7d1bf139ee030abbab021e1268 --- /dev/null +++ b/SOURCES/0332-TEST-17-UDEV-wait-for-udevd-being-restarted-after-ex.patch @@ -0,0 +1,35 @@ +From c7ac125cac1a0efcbd5f7e63433d8652887c0714 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 7 Jan 2025 20:23:02 +0900 +Subject: [PATCH] TEST-17-UDEV: wait for udevd being restarted after exit + control command + +Also wait for created devices being processed before running tests. + +(cherry picked from commit d5c4c4d45c6075f5a1dde024d7a4717b71f369a2) + +Resolves: RHEL-75774 +--- + test/units/TEST-17-UDEV.10.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/test/units/TEST-17-UDEV.10.sh b/test/units/TEST-17-UDEV.10.sh +index 6820e76679..be342b3468 100755 +--- a/test/units/TEST-17-UDEV.10.sh ++++ b/test/units/TEST-17-UDEV.10.sh +@@ -28,9 +28,15 @@ blk="$(mktemp)" + dd if=/dev/zero of="$blk" bs=1M count=1 + loopdev="$(losetup --show -f "$blk")" + ++# Wait for devices created in the above being processed. ++udevadm settle --timeout 30 ++ + udevadm -h + ++INVOCATION_ID=$(systemctl show --property InvocationID --value systemd-udevd.service) + udevadm control -e ++# Wait for systemd-udevd.service being restarted. ++timeout 30 bash -ec "while [[ \"\$(systemctl show --property InvocationID --value systemd-udevd.service)\" == \"$INVOCATION_ID\" ]]; do sleep .5; done" + udevadm control -l emerg + udevadm control -l alert + udevadm control -l crit diff --git a/SOURCES/0333-udev-make-worker-event-source-take-file-descriptor.patch b/SOURCES/0333-udev-make-worker-event-source-take-file-descriptor.patch new file mode 100644 index 0000000000000000000000000000000000000000..d24922a9ec0c21a97e1162abdad43701e06785b8 --- /dev/null +++ b/SOURCES/0333-udev-make-worker-event-source-take-file-descriptor.patch @@ -0,0 +1,102 @@ +From d5f7f864605262d432c7dfeb09d785f7c38463a4 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 22 Dec 2024 00:14:52 +0900 +Subject: [PATCH] udev: make worker event source take file descriptor + +No functional change, just refactoring. + +(cherry picked from commit 77eb6f73053a71ddd7e9156a409b138eb87c4cd6) + +Resolves: RHEL-75774 +--- + src/udev/udev-manager.c | 27 +++++++++++++++++++++------ + src/udev/udev-manager.h | 2 +- + 2 files changed, 22 insertions(+), 7 deletions(-) + +diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c +index 83b0a90ccf..1768da5a38 100644 +--- a/src/udev/udev-manager.c ++++ b/src/udev/udev-manager.c +@@ -144,7 +144,7 @@ Manager* manager_free(Manager *manager) { + event_queue_cleanup(manager, EVENT_UNDEF); + + safe_close(manager->inotify_fd); +- safe_close_pair(manager->worker_watch); ++ safe_close(manager->worker_notify_fd); + + sd_device_monitor_unref(manager->monitor); + udev_ctrl_unref(manager->ctrl); +@@ -406,7 +406,7 @@ static int worker_spawn(Manager *manager, Event *event) { + .monitor = TAKE_PTR(worker_monitor), + .properties = TAKE_PTR(manager->properties), + .rules = TAKE_PTR(manager->rules), +- .pipe_fd = TAKE_FD(manager->worker_watch[WRITE_END]), ++ .pipe_fd = TAKE_FD(manager->worker_notify_fd), + .inotify_fd = TAKE_FD(manager->inotify_fd), + .config = manager->config, + }; +@@ -1122,7 +1122,7 @@ Manager* manager_new(void) { + + *manager = (Manager) { + .inotify_fd = -EBADF, +- .worker_watch = EBADF_PAIR, ++ .worker_notify_fd = -EBADF, + .config_by_udev_conf = UDEV_CONFIG_INIT, + .config_by_command = UDEV_CONFIG_INIT, + .config_by_kernel = UDEV_CONFIG_INIT, +@@ -1320,24 +1320,39 @@ static int manager_start_inotify(Manager *manager) { + } + + static int manager_start_worker_event(Manager *manager) { ++ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; ++ _cleanup_close_pair_ int pair[2] = EBADF_PAIR; + 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); ++ r = socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, pair); + if (r < 0) + return log_error_errno(errno, "Failed to create socketpair for communicating with workers: %m"); + +- r = setsockopt_int(manager->worker_watch[READ_END], SOL_SOCKET, SO_PASSCRED, true); ++ r = setsockopt_int(pair[READ_END], SOL_SOCKET, SO_PASSCRED, true); + if (r < 0) + return log_error_errno(r, "Failed to enable SO_PASSCRED: %m"); + +- r = sd_event_add_io(manager->event, NULL, manager->worker_watch[READ_END], EPOLLIN, on_worker, manager); ++ r = sd_event_add_io(manager->event, &s, pair[READ_END], EPOLLIN, on_worker, manager); + if (r < 0) + return log_error_errno(r, "Failed to create worker event source: %m"); + ++ (void) sd_event_source_set_description(s, "manager-worker-event"); ++ ++ r = sd_event_source_set_io_fd_own(s, true); ++ if (r < 0) ++ return log_error_errno(r, "Failed to make worker event source own file descriptor: %m"); ++ ++ TAKE_FD(pair[READ_END]); ++ ++ r = sd_event_source_set_floating(s, true); ++ if (r < 0) ++ return log_error_errno(r, "Failed to make worker event source floating: %m"); ++ ++ manager->worker_notify_fd = TAKE_FD(pair[WRITE_END]); + return 0; + } + +diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h +index 05f9a8b709..2690d59bf3 100644 +--- a/src/udev/udev-manager.h ++++ b/src/udev/udev-manager.h +@@ -28,7 +28,7 @@ typedef struct Manager { + + sd_device_monitor *monitor; + UdevCtrl *ctrl; +- int worker_watch[2]; ++ int worker_notify_fd; + + /* used by udev-watch */ + int inotify_fd; diff --git a/SOURCES/0334-udev-dump-split-out-dump_event-from-udevadm-test.c.patch b/SOURCES/0334-udev-dump-split-out-dump_event-from-udevadm-test.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..0079b6d7d42ab0ddab66ce10ddca73318947a6b9 --- /dev/null +++ b/SOURCES/0334-udev-dump-split-out-dump_event-from-udevadm-test.c.patch @@ -0,0 +1,269 @@ +From 2583cd4e5b2f06b9d0dcf5faa4d2e2245560448f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 11 Jan 2025 15:56:27 +0900 +Subject: [PATCH] udev-dump: split out dump_event() from udevadm-test.c + +(cherry picked from commit 91d9f8f834354a0d541a94e65e389309e32cba9d) + +Resolves: RHEL-75774 +--- + src/udev/meson.build | 1 + + src/udev/udev-dump.c | 96 +++++++++++++++++++++++++++++++++++++++++ + src/udev/udev-dump.h | 8 ++++ + src/udev/udevadm-test.c | 94 +--------------------------------------- + 4 files changed, 107 insertions(+), 92 deletions(-) + create mode 100644 src/udev/udev-dump.c + create mode 100644 src/udev/udev-dump.h + +diff --git a/src/udev/meson.build b/src/udev/meson.build +index 54e12a45e4..171bbd2b70 100644 +--- a/src/udev/meson.build ++++ b/src/udev/meson.build +@@ -31,6 +31,7 @@ libudevd_core_sources = files( + 'udev-builtin.c', + 'udev-config.c', + 'udev-ctrl.c', ++ 'udev-dump.c', + 'udev-event.c', + 'udev-format.c', + 'udev-manager.c', +diff --git a/src/udev/udev-dump.c b/src/udev/udev-dump.c +new file mode 100644 +index 0000000000..5900eef8af +--- /dev/null ++++ b/src/udev/udev-dump.c +@@ -0,0 +1,96 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include "ansi-color.h" ++#include "device-private.h" ++#include "device-util.h" ++#include "format-util.h" ++#include "fs-util.h" ++#include "udev-builtin.h" ++#include "udev-dump.h" ++#include "udev-event.h" ++#include "user-util.h" ++ ++void dump_event(UdevEvent *event, FILE *f) { ++ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); ++ ++ if (!f) ++ f = stdout; ++ ++ fprintf(f, "%sProperties:%s\n", ansi_highlight(), ansi_normal()); ++ FOREACH_DEVICE_PROPERTY(dev, key, value) ++ fprintf(f, " %s=%s\n", key, value); ++ ++ if (sd_device_get_tag_first(dev)) { ++ fprintf(f, "%sTags:%s\n", ansi_highlight(), ansi_normal()); ++ FOREACH_DEVICE_TAG(dev, tag) ++ fprintf(f, " %s\n", tag); ++ } ++ ++ if (sd_device_get_devnum(dev, NULL) >= 0) { ++ ++ if (sd_device_get_devlink_first(dev)) { ++ int prio; ++ device_get_devlink_priority(dev, &prio); ++ fprintf(f, "%sDevice node symlinks:%s (priority=%i)\n", ansi_highlight(), ansi_normal(), prio); ++ FOREACH_DEVICE_DEVLINK(dev, devlink) ++ fprintf(f, " %s\n", devlink); ++ } ++ ++ fprintf(f, "%sInotify watch:%s\n %s\n", ansi_highlight(), ansi_normal(), enabled_disabled(event->inotify_watch)); ++ ++ uid_t uid = event->uid; ++ if (!uid_is_valid(uid)) ++ (void) device_get_devnode_uid(dev, &uid); ++ if (uid_is_valid(uid)) { ++ _cleanup_free_ char *user = uid_to_name(uid); ++ fprintf(f, "%sDevice node owner:%s\n %s (uid="UID_FMT")\n", ansi_highlight(), ansi_normal(), strna(user), uid); ++ } ++ ++ gid_t gid = event->gid; ++ if (!gid_is_valid(uid)) ++ (void) device_get_devnode_gid(dev, &gid); ++ if (gid_is_valid(gid)) { ++ _cleanup_free_ char *group = gid_to_name(gid); ++ fprintf(f, "%sDevice node group:%s\n %s (gid="GID_FMT")\n", ansi_highlight(), ansi_normal(), strna(group), gid); ++ } ++ ++ mode_t mode = event->mode; ++ if (mode == MODE_INVALID) ++ (void) device_get_devnode_mode(dev, &mode); ++ if (mode != MODE_INVALID) ++ fprintf(f, "%sDevice node permission:%s\n %04o\n", ansi_highlight(), ansi_normal(), mode); ++ ++ if (!ordered_hashmap_isempty(event->seclabel_list)) { ++ const char *name, *label; ++ fprintf(f, "%sDevice node security label:%s\n", ansi_highlight(), ansi_normal()); ++ ORDERED_HASHMAP_FOREACH_KEY(label, name, event->seclabel_list) ++ fprintf(f, " %s : %s\n", name, label); ++ } ++ } ++ ++ if (sd_device_get_ifindex(dev, NULL) >= 0) { ++ if (!isempty(event->name)) ++ fprintf(f, "%sNetwork interface name:%s\n %s\n", ansi_highlight(), ansi_normal(), event->name); ++ ++ if (!strv_isempty(event->altnames)) { ++ bool space = true; ++ fprintf(f, "%sAlternative interface names:%s", ansi_highlight(), ansi_normal()); ++ fputstrv(f, event->altnames, "\n ", &space); ++ fputs("\n", f); ++ } ++ } ++ ++ if (!ordered_hashmap_isempty(event->run_list)) { ++ void *val; ++ const char *command; ++ fprintf(f, "%sQueued commands:%s\n", ansi_highlight(), ansi_normal()); ++ ORDERED_HASHMAP_FOREACH_KEY(val, command, event->run_list) { ++ UdevBuiltinCommand builtin_cmd = PTR_TO_UDEV_BUILTIN_CMD(val); ++ ++ if (builtin_cmd != _UDEV_BUILTIN_INVALID) ++ fprintf(f, " RUN{builtin} : %s\n", command); ++ else ++ fprintf(f, " RUN{program} : %s\n", command); ++ } ++ } ++} +diff --git a/src/udev/udev-dump.h b/src/udev/udev-dump.h +new file mode 100644 +index 0000000000..6e3f1368ce +--- /dev/null ++++ b/src/udev/udev-dump.h +@@ -0,0 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++#pragma once ++ ++#include <stdio.h> ++ ++typedef struct UdevEvent UdevEvent; ++ ++void dump_event(UdevEvent *event, FILE *f); +diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c +index 09d1150dd7..5ceb6a5f28 100644 +--- a/src/udev/udevadm-test.c ++++ b/src/udev/udevadm-test.c +@@ -3,33 +3,19 @@ + * Copyright © 2003-2004 Greg Kroah-Hartman <greg@kroah.com> + */ + +-#include <errno.h> + #include <getopt.h> + #include <signal.h> +-#include <stddef.h> + #include <stdio.h> +-#include <stdlib.h> +-#include <sys/signalfd.h> +-#include <unistd.h> + + #include "sd-device.h" + +-#include "ansi-color.h" + #include "device-private.h" +-#include "device-util.h" +-#include "format-util.h" +-#include "path-util.h" +-#include "string-util.h" +-#include "strv.h" +-#include "strxcpyx.h" +-#include "terminal-util.h" + #include "udev-builtin.h" ++#include "udev-dump.h" + #include "udev-event.h" +-#include "udev-format.h" + #include "udev-rules.h" + #include "udevadm-util.h" + #include "udevadm.h" +-#include "user-util.h" + + static sd_device_action_t arg_action = SD_DEVICE_ADD; + static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; +@@ -153,83 +139,7 @@ int test_main(int argc, char *argv[], void *userdata) { + puts("Processing udev rules done."); + + puts(""); +- printf("%sProperties:%s\n", ansi_highlight(), ansi_normal()); +- FOREACH_DEVICE_PROPERTY(dev, key, value) +- printf(" %s=%s\n", key, value); +- +- if (sd_device_get_tag_first(dev)) { +- printf("%sTags:%s\n", ansi_highlight(), ansi_normal()); +- FOREACH_DEVICE_TAG(dev, tag) +- printf(" %s\n", tag); +- } +- +- if (sd_device_get_devnum(dev, NULL) >= 0) { +- +- if (sd_device_get_devlink_first(dev)) { +- int prio; +- device_get_devlink_priority(dev, &prio); +- printf("%sDevice node symlinks:%s (priority=%i)\n", ansi_highlight(), ansi_normal(), prio); +- FOREACH_DEVICE_DEVLINK(dev, devlink) +- printf(" %s\n", devlink); +- } +- +- printf("%sInotify watch:%s\n %s\n", ansi_highlight(), ansi_normal(), enabled_disabled(event->inotify_watch)); +- +- uid_t uid = event->uid; +- if (!uid_is_valid(uid)) +- (void) device_get_devnode_uid(dev, &uid); +- if (uid_is_valid(uid)) { +- _cleanup_free_ char *user = uid_to_name(uid); +- printf("%sDevice node owner:%s\n %s (uid="UID_FMT")\n", ansi_highlight(), ansi_normal(), strna(user), uid); +- } +- +- gid_t gid = event->gid; +- if (!gid_is_valid(gid)) +- (void) device_get_devnode_gid(dev, &gid); +- if (gid_is_valid(gid)) { +- _cleanup_free_ char *group = gid_to_name(gid); +- printf("%sDevice node group:%s\n %s (gid="GID_FMT")\n", ansi_highlight(), ansi_normal(), strna(group), gid); +- } +- +- mode_t mode = event->mode; +- if (mode == MODE_INVALID) +- (void) device_get_devnode_mode(dev, &mode); +- if (mode != MODE_INVALID) +- printf("%sDevice node permission:%s\n %04o\n", ansi_highlight(), ansi_normal(), mode); +- +- if (!ordered_hashmap_isempty(event->seclabel_list)) { +- const char *name, *label; +- printf("%sDevice node security label:%s\n", ansi_highlight(), ansi_normal()); +- ORDERED_HASHMAP_FOREACH_KEY(label, name, event->seclabel_list) +- printf(" %s : %s\n", name, label); +- } +- } +- +- if (sd_device_get_ifindex(dev, NULL) >= 0) { +- if (!isempty(event->name)) +- printf("%sNetwork interface name:%s\n %s\n", ansi_highlight(), ansi_normal(), event->name); +- +- if (!strv_isempty(event->altnames)) { +- bool space = true; +- printf("%sAlternative interface names:%s", ansi_highlight(), ansi_normal()); +- fputstrv(stdout, event->altnames, "\n ", &space); +- puts(""); +- } +- } +- +- if (!ordered_hashmap_isempty(event->run_list)) { +- void *val; +- const char *command; +- printf("%sQueued commands:%s\n", ansi_highlight(), ansi_normal()); +- ORDERED_HASHMAP_FOREACH_KEY(val, command, event->run_list) { +- UdevBuiltinCommand builtin_cmd = PTR_TO_UDEV_BUILTIN_CMD(val); +- +- if (builtin_cmd != _UDEV_BUILTIN_INVALID) +- printf(" RUN{builtin} : %s\n", command); +- else +- printf(" RUN{program} : %s\n", command); +- } +- } ++ dump_event(event, NULL); + + r = 0; + out: diff --git a/SOURCES/0335-udev-rules-introduce-OPTIONS-dump-token.patch b/SOURCES/0335-udev-rules-introduce-OPTIONS-dump-token.patch new file mode 100644 index 0000000000000000000000000000000000000000..e3b0f7a15385f50687677670852dd629e049648b --- /dev/null +++ b/SOURCES/0335-udev-rules-introduce-OPTIONS-dump-token.patch @@ -0,0 +1,107 @@ +From 3c4bb5e072ce6fa02976bd43d038c1b5b4c392c3 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 11 Jan 2025 17:00:17 +0900 +Subject: [PATCH] udev-rules: introduce OPTIONS="dump" token + +Should be useful for debugging. + +(cherry picked from commit b4ffb776696bdd3a7345f73956ce7551f6b449ff) + +Resolves: RHEL-75774 +--- + man/udev.xml | 9 +++++++++ + src/udev/udev-rules.c | 33 ++++++++++++++++++++++++++++++++- + 2 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/man/udev.xml b/man/udev.xml +index e6c0e23ed4..27ebdfc114 100644 +--- a/man/udev.xml ++++ b/man/udev.xml +@@ -720,6 +720,15 @@ SUBSYSTEM=="net", OPTIONS="log_level=debug"</programlisting></para> + <xi:include href="version-info.xml" xpointer="v248"/> + </listitem> + </varlistentry> ++ <varlistentry> ++ <term><option>dump</option></term> ++ <listitem> ++ <para>Dump the status of the event currently processing. It may be useful for debugging ++ udev rules by inserting this option.</para> ++ ++ <xi:include href="version-info.xml" xpointer="v258"/> ++ </listitem> ++ </varlistentry> + </variablelist> + </listitem> + </varlistentry> +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index 041c642aa9..d94fc6fdbd 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -18,6 +18,7 @@ + #include "fs-util.h" + #include "glob-util.h" + #include "list.h" ++#include "memstream-util.h" + #include "mkdir.h" + #include "netif-naming-scheme.h" + #include "nulstr-util.h" +@@ -32,6 +33,7 @@ + #include "sysctl-util.h" + #include "syslog-util.h" + #include "udev-builtin.h" ++#include "udev-dump.h" + #include "udev-event.h" + #include "udev-format.h" + #include "udev-node.h" +@@ -117,6 +119,7 @@ typedef enum { + #define _TK_A_MIN _TK_M_MAX + + /* lvalues which take one of assign operators */ ++ TK_A_OPTIONS_DUMP, /* no argument */ + TK_A_OPTIONS_STRING_ESCAPE_NONE, /* no argument */ + TK_A_OPTIONS_STRING_ESCAPE_REPLACE, /* no argument */ + TK_A_OPTIONS_DB_PERSIST, /* no argument */ +@@ -991,7 +994,9 @@ static int parse_token( + if (op == OP_ADD) + op = OP_ASSIGN; + +- if (streq(value, "string_escape=none")) ++ if (streq(value, "dump")) ++ r = rule_line_add_token(rule_line, TK_A_OPTIONS_DUMP, op, NULL, NULL, /* is_case_insensitive = */ false, token_str); ++ else if (streq(value, "string_escape=none")) + r = rule_line_add_token(rule_line, TK_A_OPTIONS_STRING_ESCAPE_NONE, op, NULL, NULL, /* is_case_insensitive = */ false, token_str); + else if (streq(value, "string_escape=replace")) + r = rule_line_add_token(rule_line, TK_A_OPTIONS_STRING_ESCAPE_REPLACE, op, NULL, NULL, /* is_case_insensitive = */ false, token_str); +@@ -2551,6 +2556,32 @@ static int udev_rule_apply_token_to_event( + case TK_M_RESULT: + return token_match_string(event, token, event->program_result, /* log_result = */ true); + ++ case TK_A_OPTIONS_DUMP: { ++ log_event_info(event, token, "Dumping current state:"); ++ ++ if (event->event_mode == EVENT_UDEV_WORKER) { ++ _cleanup_(memstream_done) MemStream m = {}; ++ FILE *f = memstream_init(&m); ++ if (!f) ++ return log_oom(); ++ ++ dump_event(event, f); ++ ++ _cleanup_free_ char *buf = NULL; ++ r = memstream_finalize(&m, &buf, NULL); ++ if (r < 0) ++ log_event_warning_errno(event, token, r, "Failed to finalize memory stream, ignoring: %m"); ++ else ++ log_info("%s", buf); ++ } else { ++ puts("============================"); ++ dump_event(event, NULL); ++ puts("============================"); ++ } ++ ++ log_event_info(event, token, "DONE"); ++ return true; ++ } + case TK_A_OPTIONS_STRING_ESCAPE_NONE: + event->esc = ESCAPE_NONE; + return log_event_done(event, token); diff --git a/SOURCES/0336-udev-control-move-setting-of-log-level-to-manager_ad.patch b/SOURCES/0336-udev-control-move-setting-of-log-level-to-manager_ad.patch new file mode 100644 index 0000000000000000000000000000000000000000..ed5deaa14d6bb543d9cef54c749637ef4d323161 --- /dev/null +++ b/SOURCES/0336-udev-control-move-setting-of-log-level-to-manager_ad.patch @@ -0,0 +1,44 @@ +From 31fd7f6077e1400450b57c4a1357d476e79b76d8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 21 Jan 2025 04:03:05 +0900 +Subject: [PATCH] udev-control: move setting of log level to + manager_adjust_config() + +No functional change, just refactoring. + +(cherry picked from commit b5a10b2127207c6ddb64ed05d01bc211ccef2981) + +Resolves: RHEL-75774 +--- + src/udev/udev-config.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c +index d511691ab2..86a99a5381 100644 +--- a/src/udev/udev-config.c ++++ b/src/udev/udev-config.c +@@ -320,6 +320,8 @@ void manager_set_log_level(Manager *manager, int log_level) { + static void manager_adjust_config(UdevConfig *config) { + assert(config); + ++ log_set_max_level(config->log_level); ++ + if (config->timeout_usec < MIN_WORKER_TIMEOUT_USEC) { + log_debug("Timeout (%s) for processing event is too small, using the default: %s", + FORMAT_TIMESPAN(config->timeout_usec, 1), +@@ -411,7 +413,6 @@ int manager_load(Manager *manager, int argc, char *argv[]) { + if (arg_debug) + log_set_target(LOG_TARGET_CONSOLE); + +- log_set_max_level(manager->config.log_level); + manager_adjust_config(&manager->config); + return 1; + } +@@ -424,7 +425,6 @@ UdevReloadFlags manager_reload_config(Manager *manager) { + 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) diff --git a/SOURCES/0337-udev-config-allow-to-enable-trace-logging-through-ke.patch b/SOURCES/0337-udev-config-allow-to-enable-trace-logging-through-ke.patch new file mode 100644 index 0000000000000000000000000000000000000000..433cda0cd2787424cb55d25c840b62ccd18a91cd --- /dev/null +++ b/SOURCES/0337-udev-config-allow-to-enable-trace-logging-through-ke.patch @@ -0,0 +1,158 @@ +From 72d1239a7505c29375bd78e1ff6126305505b533 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 12 Jan 2025 01:35:48 +0900 +Subject: [PATCH] udev-config: allow to enable trace logging through kernel + command line + +This adds udev.trace[=BOOL] kernel command line option to control trace +logging. + +(cherry picked from commit 695c592a034d98be9c10840c9c89b44013b330a2) + +Resolves: RHEL-75774 +--- + man/kernel-command-line.xml | 2 ++ + man/systemd-udevd.service.xml | 10 +++++++++ + src/udev/udev-config.c | 41 ++++++++++++++++++++++++++++++----- + src/udev/udev-config.h | 1 + + src/udev/udev-worker.c | 1 + + 5 files changed, 49 insertions(+), 6 deletions(-) + +diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml +index baa7122204..0a4c8cf11b 100644 +--- a/man/kernel-command-line.xml ++++ b/man/kernel-command-line.xml +@@ -306,6 +306,8 @@ + <varlistentry> + <term><varname>udev.log_level=</varname></term> + <term><varname>rd.udev.log_level=</varname></term> ++ <term><varname>udev.trace=</varname></term> ++ <term><varname>rd.udev.trace=</varname></term> + <term><varname>udev.children_max=</varname></term> + <term><varname>rd.udev.children_max=</varname></term> + <term><varname>udev.exec_delay=</varname></term> +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index c781765e1c..2a825a52a2 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -165,6 +165,16 @@ + <xi:include href="version-info.xml" xpointer="v247"/> + </listitem> + </varlistentry> ++ <varlistentry> ++ <term><varname>udev.trace[=<replaceable>BOOL</replaceable>]</varname></term> ++ <term><varname>rd.udev.trace[=<replaceable>BOOL</replaceable>]</varname></term> ++ <listitem> ++ <para>Enable/disable trace logging. When enabled, <varname>udev.log_level=</varname> will be ++ ignored, and <literal>debug</literal> level is assumed.</para> ++ ++ <xi:include href="version-info.xml" xpointer="v258"/> ++ </listitem> ++ </varlistentry> + <varlistentry> + <term><varname>udev.children_max=</varname></term> + <term><varname>rd.udev.children_max=</varname></term> +diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c +index 86a99a5381..9c806baec2 100644 +--- a/src/udev/udev-config.c ++++ b/src/udev/udev-config.c +@@ -112,6 +112,20 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + + return 0; + ++ } else if (proc_cmdline_key_streq(key, "udev.trace")) { ++ ++ if (!value) ++ config->trace = true; ++ else { ++ r = parse_boolean(value); ++ if (r < 0) ++ log_warning_errno(r, "Failed to parse udev.trace argument, ignoring: %s", value); ++ else ++ config->trace = r; ++ } ++ ++ return 0; ++ + } else { + if (startswith(key, "udev.")) + log_warning("Unknown udev kernel command line option \"%s\", ignoring.", key); +@@ -257,13 +271,24 @@ static int parse_argv(int argc, char *argv[], UdevConfig *config) { + manager->config_by_command.name || \ + manager->config_by_udev_conf.name; + ++static void manager_merge_config_log_level(Manager *manager) { ++ assert(manager); ++ ++ MERGE_BOOL(trace); ++ ++ if (manager->config.trace) ++ manager->config.log_level = LOG_DEBUG; ++ else ++ MERGE_NON_NEGATIVE(log_level, log_get_max_level()); ++} ++ + 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()); ++ manager_merge_config_log_level(manager); + 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); +@@ -310,11 +335,14 @@ void manager_set_log_level(Manager *manager, int 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; ++ manager->config_by_control.log_level = log_level; ++ manager_merge_config_log_level(manager); + +- if (log_level != old) +- manager_kill_workers(manager, /* force = */ false); ++ if (manager->config.log_level == old) ++ return; ++ ++ log_set_max_level(manager->config.log_level); ++ manager_kill_workers(manager, /* force = */ false); + } + + static void manager_adjust_config(UdevConfig *config) { +@@ -434,7 +462,8 @@ UdevReloadFlags manager_reload_config(Manager *manager) { + 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) ++ manager->config.blockdev_read_only != old.blockdev_read_only || ++ manager->config.trace != old.trace) + return UDEV_RELOAD_KILL_WORKERS; + + return 0; +diff --git a/src/udev/udev-config.h b/src/udev/udev-config.h +index 68bb1ea98c..9e8a48dae2 100644 +--- a/src/udev/udev-config.h ++++ b/src/udev/udev-config.h +@@ -18,6 +18,7 @@ typedef struct UdevConfig { + usec_t timeout_usec; + int timeout_signal; + bool blockdev_read_only; ++ bool trace; + } UdevConfig; + + #define UDEV_CONFIG_INIT \ +diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c +index fc9072e5fd..b26bf3b980 100644 +--- a/src/udev/udev-worker.c ++++ b/src/udev/udev-worker.c +@@ -183,6 +183,7 @@ static int worker_process_device(UdevWorker *worker, sd_device *dev) { + udev_event = udev_event_new(dev, worker, EVENT_UDEV_WORKER); + if (!udev_event) + return -ENOMEM; ++ udev_event->trace = worker->config.trace; + + /* If this is a block device and the device is locked currently via the BSD advisory locks, + * someone else is using it exclusively. We don't run our udev rules now to not interfere. diff --git a/SOURCES/0338-udev-dump-voidify-one-function-call.patch b/SOURCES/0338-udev-dump-voidify-one-function-call.patch new file mode 100644 index 0000000000000000000000000000000000000000..af11eb5b6549d934b7de0ec47403e778a6aa989d --- /dev/null +++ b/SOURCES/0338-udev-dump-voidify-one-function-call.patch @@ -0,0 +1,29 @@ +From cde8350ec4085cada729256d3be46e25a6a55aa5 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 23 Jan 2025 01:48:04 +0900 +Subject: [PATCH] udev-dump: voidify one function call + +Fixes CID#1590377. + +(cherry picked from commit f3cbd4da121bd4df8483376fce71663d7bf38937) + +Resolves: RHEL-75774 +--- + src/udev/udev-dump.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/udev/udev-dump.c b/src/udev/udev-dump.c +index 5900eef8af..26e65979eb 100644 +--- a/src/udev/udev-dump.c ++++ b/src/udev/udev-dump.c +@@ -29,8 +29,8 @@ void dump_event(UdevEvent *event, FILE *f) { + if (sd_device_get_devnum(dev, NULL) >= 0) { + + if (sd_device_get_devlink_first(dev)) { +- int prio; +- device_get_devlink_priority(dev, &prio); ++ int prio = 0; ++ (void) device_get_devlink_priority(dev, &prio); + fprintf(f, "%sDevice node symlinks:%s (priority=%i)\n", ansi_highlight(), ansi_normal(), prio); + FOREACH_DEVICE_DEVLINK(dev, devlink) + fprintf(f, " %s\n", devlink); diff --git a/SOURCES/0339-udev-dump-also-show-written-sysfs-attributes-and-sys.patch b/SOURCES/0339-udev-dump-also-show-written-sysfs-attributes-and-sys.patch new file mode 100644 index 0000000000000000000000000000000000000000..8bc15d1088fb8314a79246a341beb02b3ad18a1c --- /dev/null +++ b/SOURCES/0339-udev-dump-also-show-written-sysfs-attributes-and-sys.patch @@ -0,0 +1,159 @@ +From c95b80ea2e851cc0eecba15c452f83683beae56d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 11 Jan 2025 16:38:02 +0900 +Subject: [PATCH] udev-dump: also show written sysfs attributes and sysctl + entries + +This should be useful to know what is changed by processing an event. + +(cherry picked from commit 9ddcccfad7c09e7f69527e0b25781925149ad046) + +Resolves: RHEL-75774 +--- + src/udev/udev-dump.c | 34 ++++++++++++++++++++++++++++++++++ + src/udev/udev-dump.h | 2 ++ + src/udev/udev-event.c | 2 ++ + src/udev/udev-event.h | 2 ++ + src/udev/udev-rules.c | 28 ++++++++++++++++++++++++---- + 5 files changed, 64 insertions(+), 4 deletions(-) + +diff --git a/src/udev/udev-dump.c b/src/udev/udev-dump.c +index 26e65979eb..918c966c4e 100644 +--- a/src/udev/udev-dump.c ++++ b/src/udev/udev-dump.c +@@ -10,12 +10,46 @@ + #include "udev-event.h" + #include "user-util.h" + ++static void event_cache_written_value(Hashmap **values, const char *attr, const char *value) { ++ assert(values); ++ ++ _unused_ _cleanup_free_ void *key = NULL; ++ free(hashmap_remove2(*values, attr, &key)); ++ ++ if (hashmap_put_strdup_full(values, &path_hash_ops_free_free, attr, value) < 0) ++ log_oom_debug(); ++} ++ ++void event_cache_written_sysattr(UdevEvent *event, const char *attr, const char *value) { ++ event_cache_written_value(&event->written_sysattrs, attr, value); ++} ++ ++void event_cache_written_sysctl(UdevEvent *event, const char *attr, const char *value) { ++ event_cache_written_value(&event->written_sysctls, attr, value); ++} ++ + void dump_event(UdevEvent *event, FILE *f) { + sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + + if (!f) + f = stdout; + ++ if (!hashmap_isempty(event->written_sysattrs)) { ++ const char *key, *value; ++ ++ fprintf(f, "%sWritten sysfs attributes:%s\n", ansi_highlight(), ansi_normal()); ++ HASHMAP_FOREACH_KEY(value, key, event->written_sysattrs) ++ fprintf(f, " %s : %s\n", key, value); ++ } ++ ++ if (!hashmap_isempty(event->written_sysctls)) { ++ const char *key, *value; ++ ++ fprintf(f, "%sWritten sysctl entries:%s\n", ansi_highlight(), ansi_normal()); ++ HASHMAP_FOREACH_KEY(value, key, event->written_sysctls) ++ fprintf(f, " %s : %s\n", key, value); ++ } ++ + fprintf(f, "%sProperties:%s\n", ansi_highlight(), ansi_normal()); + FOREACH_DEVICE_PROPERTY(dev, key, value) + fprintf(f, " %s=%s\n", key, value); +diff --git a/src/udev/udev-dump.h b/src/udev/udev-dump.h +index 6e3f1368ce..514f8267a7 100644 +--- a/src/udev/udev-dump.h ++++ b/src/udev/udev-dump.h +@@ -5,4 +5,6 @@ + + typedef struct UdevEvent UdevEvent; + ++void event_cache_written_sysattr(UdevEvent *event, const char *attr, const char *value); ++void event_cache_written_sysctl(UdevEvent *event, const char *attr, const char *value); + void dump_event(UdevEvent *event, FILE *f); +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index e3661f5bf8..fc4c9f9fd1 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -54,6 +54,8 @@ static UdevEvent* udev_event_free(UdevEvent *event) { + sd_netlink_unref(event->rtnl); + ordered_hashmap_free_free_key(event->run_list); + ordered_hashmap_free_free_free(event->seclabel_list); ++ hashmap_free(event->written_sysattrs); ++ hashmap_free(event->written_sysctls); + free(event->program_result); + free(event->name); + strv_free(event->altnames); +diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h +index 11e2c700e6..d18fb0978b 100644 +--- a/src/udev/udev-event.h ++++ b/src/udev/udev-event.h +@@ -36,6 +36,8 @@ typedef struct UdevEvent { + gid_t gid; + OrderedHashmap *seclabel_list; + OrderedHashmap *run_list; ++ Hashmap *written_sysattrs; ++ Hashmap *written_sysctls; + usec_t birth_usec; + unsigned builtin_run; + unsigned builtin_ret; +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index d94fc6fdbd..dfe521378f 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -2949,11 +2949,19 @@ static int udev_rule_apply_token_to_event( + WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE); + if (r < 0) + log_event_error_errno(event, token, r, "Failed to write \"%s\" to sysfs attribute \"%s\", ignoring: %m", value, buf); +- else ++ else { ++ event_cache_written_sysattr(event, buf, value); + log_event_done(event, token); +- } else ++ } ++ } else { + log_event_debug(event, token, "Running in test mode, skipping writing \"%s\" to sysfs attribute \"%s\".", value, buf); + ++ r = verify_regular_at(AT_FDCWD, buf, /* follow = */ false); ++ if (r < 0 && !ERRNO_IS_NEG_PRIVILEGE(r)) ++ log_event_error_errno(event, token, r, "Failed to verify sysfs attribute \"%s\" is a regular file: %m", buf); ++ else ++ event_cache_written_sysattr(event, buf, value); ++ } + return true; + } + case TK_A_SYSCTL: { +@@ -2972,11 +2980,23 @@ static int udev_rule_apply_token_to_event( + r = sysctl_write(buf, value); + if (r < 0) + log_event_error_errno(event, token, r, "Failed to write \"%s\" to sysctl entry \"%s\", ignoring: %m", value, buf); +- else ++ else { ++ event_cache_written_sysctl(event, buf, value); + log_event_done(event, token); +- } else ++ } ++ } else { + log_event_debug(event, token, "Running in test mode, skipping writing \"%s\" to sysctl entry \"%s\".", value, buf); + ++ _cleanup_free_ char *path = path_join("/proc/sys/", buf); ++ if (!path) ++ return log_oom(); ++ ++ r = verify_regular_at(AT_FDCWD, path, /* follow = */ true); ++ if (r < 0 && !ERRNO_IS_NEG_PRIVILEGE(r)) ++ log_event_error_errno(event, token, r, "Failed to verify sysctl entry \"%s\" is a regular file: %m", buf); ++ else ++ event_cache_written_sysctl(event, buf, value); ++ } + return true; + } + case TK_A_RUN_BUILTIN: diff --git a/SOURCES/0340-udevadm-test-allow-to-specify-extra-directories-to-l.patch b/SOURCES/0340-udevadm-test-allow-to-specify-extra-directories-to-l.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a1cb0b113f8eb15ca4a484efd03b6e40de0e320 --- /dev/null +++ b/SOURCES/0340-udevadm-test-allow-to-specify-extra-directories-to-l.patch @@ -0,0 +1,255 @@ +From 5921b074c97620053b63d37adcb665b17ace5238 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 11 Jan 2025 17:54:43 +0900 +Subject: [PATCH] udevadm-test: allow to specify extra directories to load udev + rules files + +This adds -D/--extra-rules-dir=DIR switch for 'udevadm test' command. +When specified, udev rules files in the specified directory will be also +loaded. This may be useful for debugging udev rules by copying some udev +rules files to a temporary directory. + +(cherry picked from commit c1b7db56e583dbe98e9c605df45a7f7b09c9751f) + +Resolves: RHEL-75774 +--- + man/udevadm.xml | 15 ++++++++++++++ + shell-completion/bash/udevadm | 5 ++++- + shell-completion/zsh/_udevadm | 1 + + src/udev/test-udev-rule-runner.c | 2 +- + src/udev/udev-manager.c | 4 ++-- + src/udev/udev-rules.c | 16 ++++++++++++--- + src/udev/udev-rules.h | 2 +- + src/udev/udevadm-test.c | 34 +++++++++++++++++++++++++------- + 8 files changed, 64 insertions(+), 15 deletions(-) + +diff --git a/man/udevadm.xml b/man/udevadm.xml +index caa41bd204..79907b30c3 100644 +--- a/man/udevadm.xml ++++ b/man/udevadm.xml +@@ -869,6 +869,21 @@ + <xi:include href="version-info.xml" xpointer="v209"/> + </listitem> + </varlistentry> ++ <varlistentry> ++ <term><option>-D <replaceable>DIR</replaceable></option></term> ++ <term><option>--extra-rules-dir=<replaceable>DIR</replaceable></option></term> ++ <listitem> ++ <para>Also load udev rules files from the specified directory. This option can be specified ++ multiple times. It may be useful for debugging udev rules by copying some udev rules files to a ++ temporary directory, editing them, and specifying the directory with this option. Files found in ++ the specified directories have a higher priority than rules files in the default ++ <filename>udev/rules.d</filename> directories used by <command>systemd-udevd</command>. See ++ <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry> for more ++ details about the search paths.</para> ++ ++ <xi:include href="version-info.xml" xpointer="v258"/> ++ </listitem> ++ </varlistentry> + <varlistentry> + <term><option>-v</option></term> + <term><option>--verbose</option></term> +diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm +index af3a0b9058..76ed04bb7a 100644 +--- a/shell-completion/bash/udevadm ++++ b/shell-completion/bash/udevadm +@@ -70,7 +70,7 @@ _udevadm() { + [MONITOR_STANDALONE]='-k --kernel -u --udev -p --property' + [MONITOR_ARG]='-s --subsystem-match -t --tag-match' + [TEST_STANDALONE]='-v --verbose' +- [TEST_ARG]='-a --action -N --resolve-names' ++ [TEST_ARG]='-a --action -N --resolve-names -D --extra-rules-dir' + [TEST_BUILTIN]='-a --action' + [VERIFY]='-N --resolve-names --root --no-summary --no-style' + [WAIT]='-t --timeout --initialized=no --removed --settle' +@@ -225,6 +225,9 @@ _udevadm() { + -N|--resolve-names) + comps='early late never' + ;; ++ -D|--extra-rules-dir) ++ comps='' ++ compopt -o dirnames + esac + elif [[ $cur = -* ]]; then + comps="${OPTS[COMMON]} ${OPTS[TEST_ARG]} ${OPTS[TEST_STANDALONE]}" +diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm +index 5c3d3c93ef..792b3e479d 100644 +--- a/shell-completion/zsh/_udevadm ++++ b/shell-completion/zsh/_udevadm +@@ -87,6 +87,7 @@ _udevadm_test(){ + '(-)'{-V,--version}'[Show package version]' \ + '--action=[The action string.]:actions:(add change remove move online offline bind unbind)' \ + '--subsystem=[The subsystem string.]' \ ++ '(-D --extra-rules-dir=)'{-D,--extra-rules-dir=}'[Also load rules from the directory.]' \ + '(-v --verbose)'{-v,--verbose}'[Show verbose logs.]' \ + '*::devpath:_files -P /sys/ -W /sys' + } +diff --git a/src/udev/test-udev-rule-runner.c b/src/udev/test-udev-rule-runner.c +index 9a04abf590..9ad446aa2d 100644 +--- a/src/udev/test-udev-rule-runner.c ++++ b/src/udev/test-udev-rule-runner.c +@@ -136,7 +136,7 @@ static int run(int argc, char *argv[]) { + usleep_safe(us); + } + +- assert_se(udev_rules_load(&rules, RESOLVE_NAME_EARLY) == 0); ++ assert_se(udev_rules_load(&rules, RESOLVE_NAME_EARLY, /* extra = */ NULL) == 0); + + const char *syspath = strjoina("/sys", devpath); + r = device_new_from_synthetic_event(&dev, syspath, action); +diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c +index 1768da5a38..2c71698bf6 100644 +--- a/src/udev/udev-manager.c ++++ b/src/udev/udev-manager.c +@@ -281,7 +281,7 @@ static void manager_reload(Manager *manager, bool force) { + udev_builtin_reload(flags); + + if (FLAGS_SET(flags, UDEV_RELOAD_RULES)) { +- r = udev_rules_load(&rules, manager->config.resolve_name_timing); ++ r = udev_rules_load(&rules, manager->config.resolve_name_timing, /* extra = */ NULL); + if (r < 0) + log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m"); + else +@@ -1433,7 +1433,7 @@ int manager_main(Manager *manager) { + + udev_builtin_init(); + +- r = udev_rules_load(&manager->rules, manager->config.resolve_name_timing); ++ r = udev_rules_load(&manager->rules, manager->config.resolve_name_timing, /* extra = */ NULL); + if (r < 0) + return log_error_errno(r, "Failed to read udev rules: %m"); + +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index dfe521378f..ec4660968c 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -1778,16 +1778,26 @@ UdevRules* udev_rules_new(ResolveNameTiming resolve_name_timing) { + return rules; + } + +-int udev_rules_load(UdevRules **ret_rules, ResolveNameTiming resolve_name_timing) { ++int udev_rules_load(UdevRules **ret_rules, ResolveNameTiming resolve_name_timing, char * const *extra) { + _cleanup_(udev_rules_freep) UdevRules *rules = NULL; +- _cleanup_strv_free_ char **files = NULL; ++ _cleanup_strv_free_ char **files = NULL, **directories = NULL; + int r; + + rules = udev_rules_new(resolve_name_timing); + if (!rules) + return -ENOMEM; + +- r = conf_files_list_strv(&files, ".rules", NULL, 0, RULES_DIRS); ++ if (!strv_isempty(extra)) { ++ directories = strv_copy(extra); ++ if (!directories) ++ return -ENOMEM; ++ } ++ ++ r = strv_extend_strv(&directories, CONF_PATHS_STRV("udev/rules.d"), /* filter_duplicates = */ false); ++ if (r < 0) ++ return r; ++ ++ r = conf_files_list_strv(&files, ".rules", NULL, 0, (const char* const*) directories); + if (r < 0) + return log_debug_errno(r, "Failed to enumerate rules files: %m"); + +diff --git a/src/udev/udev-rules.h b/src/udev/udev-rules.h +index 67d7e5b178..62dac5ba73 100644 +--- a/src/udev/udev-rules.h ++++ b/src/udev/udev-rules.h +@@ -14,7 +14,7 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos, bool * + int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_checks, UdevRuleFile **ret); + 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); ++int udev_rules_load(UdevRules **ret_rules, ResolveNameTiming resolve_name_timing, char * const *extra); + 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) +diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c +index 5ceb6a5f28..c3f56d2d81 100644 +--- a/src/udev/udevadm-test.c ++++ b/src/udev/udevadm-test.c +@@ -10,6 +10,9 @@ + #include "sd-device.h" + + #include "device-private.h" ++#include "parse-argument.h" ++#include "static-destruct.h" ++#include "strv.h" + #include "udev-builtin.h" + #include "udev-dump.h" + #include "udev-event.h" +@@ -20,8 +23,11 @@ + static sd_device_action_t arg_action = SD_DEVICE_ADD; + static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; + static const char *arg_syspath = NULL; ++static char **arg_extra_rules_dir = NULL; + static bool arg_verbose = false; + ++STATIC_DESTRUCTOR_REGISTER(arg_extra_rules_dir, strv_freep); ++ + static int help(void) { + + printf("%s test [OPTIONS] DEVPATH\n\n" +@@ -30,6 +36,7 @@ static int help(void) { + " -V --version Show package version\n" + " -a --action=ACTION|help Set action string\n" + " -N --resolve-names=early|late|never When to resolve names\n" ++ " -D --extra-rules-dir=DIR Also load rules from the directory\n" + " -v --verbose Show verbose logs\n", + program_invocation_short_name); + +@@ -38,17 +45,18 @@ static int help(void) { + + static int parse_argv(int argc, char *argv[]) { + static const struct option options[] = { +- { "action", required_argument, NULL, 'a' }, +- { "resolve-names", required_argument, NULL, 'N' }, +- { "verbose", no_argument, NULL, 'v' }, +- { "version", no_argument, NULL, 'V' }, +- { "help", no_argument, NULL, 'h' }, ++ { "action", required_argument, NULL, 'a' }, ++ { "resolve-names", required_argument, NULL, 'N' }, ++ { "extra-rules-dir", required_argument, NULL, 'D' }, ++ { "verbose", no_argument, NULL, 'v' }, ++ { "version", no_argument, NULL, 'V' }, ++ { "help", no_argument, NULL, 'h' }, + {} + }; + + int r, c; + +- while ((c = getopt_long(argc, argv, "a:N:vVh", options, NULL)) >= 0) ++ while ((c = getopt_long(argc, argv, "a:N:D:vVh", options, NULL)) >= 0) + switch (c) { + case 'a': + r = parse_device_action(optarg, &arg_action); +@@ -63,6 +71,18 @@ static int parse_argv(int argc, char *argv[]) { + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "--resolve-names= must be early, late or never"); + break; ++ case 'D': { ++ _cleanup_free_ char *p = NULL; ++ ++ r = parse_path_argument(optarg, /* suppress_root = */ false, &p); ++ if (r < 0) ++ return r; ++ ++ r = strv_consume(&arg_extra_rules_dir, TAKE_PTR(p)); ++ if (r < 0) ++ return log_oom(); ++ break; ++ } + case 'v': + arg_verbose = true; + break; +@@ -108,7 +128,7 @@ int test_main(int argc, char *argv[], void *userdata) { + puts("Loading builtins done."); + + puts("\nLoading udev rules files..."); +- r = udev_rules_load(&rules, arg_resolve_name_timing); ++ r = udev_rules_load(&rules, arg_resolve_name_timing, arg_extra_rules_dir); + if (r < 0) { + log_error_errno(r, "Failed to read udev rules: %m"); + goto out; diff --git a/SOURCES/0341-shell-completion-udevadm-add-net_driver.patch b/SOURCES/0341-shell-completion-udevadm-add-net_driver.patch new file mode 100644 index 0000000000000000000000000000000000000000..df549aed1d04303bc942ab9a0cf28ec2acb7e184 --- /dev/null +++ b/SOURCES/0341-shell-completion-udevadm-add-net_driver.patch @@ -0,0 +1,41 @@ +From 631e0ca15fd5073199653c6591a65575b9978e0d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 7 Jan 2025 17:39:12 +0900 +Subject: [PATCH] shell-completion/udevadm: add net_driver + +Follow-up for 2b5b25f123ceb89b3ff45b2380db1c8a88b046d9. + +(cherry picked from commit c3d526d765ee41905661c034c348c915a2f49625) + +Resolves: RHEL-75774 +--- + shell-completion/bash/udevadm | 2 +- + shell-completion/zsh/_udevadm | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm +index 76ed04bb7a..496eac5fd7 100644 +--- a/shell-completion/bash/udevadm ++++ b/shell-completion/bash/udevadm +@@ -78,7 +78,7 @@ _udevadm() { + ) + + local verbs=(info trigger settle control monitor test-builtin test verify wait lock) +- local builtins=(blkid btrfs hwdb input_id keyboard kmod net_id net_setup_link path_id usb_id uaccess) ++ local builtins=(blkid btrfs hwdb input_id keyboard kmod net_driver net_id net_setup_link path_id uaccess usb_id) + + for ((i=0; i < COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" "${verbs[@]}"; then +diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm +index 792b3e479d..63db11cea9 100644 +--- a/shell-completion/zsh/_udevadm ++++ b/shell-completion/zsh/_udevadm +@@ -99,7 +99,7 @@ _udevadm_test-builtin(){ + '(- *)'{-h,--help}'[Print help]' \ + '(- *)'{-V,--version}'[Print version of the program]' \ + '--action=[The action string.]:actions:(add change remove move online offline bind unbind)' \ +- '*::builtins:(blkid btrfs hwdb input_id net_id net_setup_link kmod path_id usb_id uaccess)' ++ '*::builtins:(blkid btrfs hwdb input_id net_driver net_id net_setup_link kmod path_id uaccess usb_id)' + elif (( CURRENT == 3 )); then + _arguments \ + '--action=[The action string.]:actions:(add change remove move online offline bind unbind)' \ diff --git a/SOURCES/0342-udev-sort-builtins.patch b/SOURCES/0342-udev-sort-builtins.patch new file mode 100644 index 0000000000000000000000000000000000000000..ffa1fcc5f206d07291609c4a75de12fd4369a370 --- /dev/null +++ b/SOURCES/0342-udev-sort-builtins.patch @@ -0,0 +1,76 @@ +From 2cfdc83a3c0eb749448d63d072fb00f42d63084c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 7 Jan 2025 17:41:41 +0900 +Subject: [PATCH] udev: sort builtins + +Then, 'udevadm test-builtin --help' lists builtins alphabetically. + +(cherry picked from commit 86a08e70a83330bc003432cf0d00ff5341acf0a0) + +Resolves: RHEL-75774 +--- + src/udev/udev-builtin.c | 2 +- + src/udev/udev-builtin.h | 2 +- + src/udev/udev-def.h | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c +index 3d22ddf945..fc6ecc095b 100644 +--- a/src/udev/udev-builtin.c ++++ b/src/udev/udev-builtin.c +@@ -26,10 +26,10 @@ static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = { + [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id, + [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link, + [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id, +- [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id, + #if HAVE_ACL + [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess, + #endif ++ [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id, + }; + + void udev_builtin_init(void) { +diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h +index 3b5f3bd120..83cf103ab5 100644 +--- a/src/udev/udev-builtin.h ++++ b/src/udev/udev-builtin.h +@@ -47,10 +47,10 @@ extern const UdevBuiltin udev_builtin_net_driver; + extern const UdevBuiltin udev_builtin_net_id; + extern const UdevBuiltin udev_builtin_net_setup_link; + extern const UdevBuiltin udev_builtin_path_id; +-extern const UdevBuiltin udev_builtin_usb_id; + #if HAVE_ACL + extern const UdevBuiltin udev_builtin_uaccess; + #endif ++extern const UdevBuiltin udev_builtin_usb_id; + + void udev_builtin_init(void); + void udev_builtin_exit(void); +diff --git a/src/udev/udev-def.h b/src/udev/udev-def.h +index ed231764bc..c157c487cf 100644 +--- a/src/udev/udev-def.h ++++ b/src/udev/udev-def.h +@@ -50,10 +50,10 @@ typedef enum UdevBuiltinCommand { + 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_USB_ID, + _UDEV_BUILTIN_MAX, + _UDEV_BUILTIN_INVALID = -EINVAL, + } UdevBuiltinCommand; +@@ -73,10 +73,10 @@ typedef enum UdevReloadFlags { + 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_BUILTIN_USB_ID = 1u << UDEV_BUILTIN_USB_ID, + UDEV_RELOAD_KILL_WORKERS = 1u << (_UDEV_BUILTIN_MAX + 0), + UDEV_RELOAD_RULES = 1u << (_UDEV_BUILTIN_MAX + 1), + } UdevReloadFlags; diff --git a/SOURCES/0343-udev-rules-log-the-first-line-number-when-continued.patch b/SOURCES/0343-udev-rules-log-the-first-line-number-when-continued.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8e9ead1c40c438f72756db0da3568c1356f62cc --- /dev/null +++ b/SOURCES/0343-udev-rules-log-the-first-line-number-when-continued.patch @@ -0,0 +1,64 @@ +From 962169813b50b3497574e21bed4692046f23affe Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 11 Jan 2025 03:45:38 +0900 +Subject: [PATCH] udev-rules: log the first line number when continued + +(cherry picked from commit 8e0f023548fae141acc6e3fb2a2ae4de4a284960) + +Resolves: RHEL-75774 +--- + src/udev/udev-rules.c | 12 ++++++++---- + test/units/TEST-17-UDEV.11.sh | 2 +- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index ec4660968c..4d9fbd39a5 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -1631,10 +1631,8 @@ static void udev_check_rule_line(UdevRuleLine *line) { + + int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_checks, UdevRuleFile **ret) { + _cleanup_(udev_rule_file_freep) UdevRuleFile *rule_file = NULL; +- _cleanup_free_ char *continuation = NULL, *name = NULL; ++ _cleanup_free_ char *name = NULL; + _cleanup_fclose_ FILE *f = NULL; +- bool ignore_line = false; +- unsigned line_nr = 0; + struct stat st; + int r; + +@@ -1685,6 +1683,9 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_che + + LIST_APPEND(rule_files, rules->rule_files, rule_file); + ++ _cleanup_free_ char *continuation = NULL; ++ unsigned line_nr = 0, current_line_nr = 0; ++ bool ignore_line = false; + for (;;) { + _cleanup_free_ char *buf = NULL; + size_t len; +@@ -1696,7 +1697,10 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_che + if (r == 0) + break; + +- line_nr++; ++ current_line_nr++; ++ if (!continuation) ++ line_nr = current_line_nr; ++ + line = skip_leading_chars(buf, NULL); + + /* Lines beginning with '#' are ignored regardless of line continuation. */ +diff --git a/test/units/TEST-17-UDEV.11.sh b/test/units/TEST-17-UDEV.11.sh +index 8413d3c189..c0d87b7151 100755 +--- a/test/units/TEST-17-UDEV.11.sh ++++ b/test/units/TEST-17-UDEV.11.sh +@@ -174,7 +174,7 @@ assert_0 "${rules}" + printf 'RUN+="/bin/true"%8176s\\\n #\n' ' ' ' ' >"${rules}" + echo >>"${rules}" + cat >"${exp}" <<EOF +-${rules}:5 Line is too long, ignored. ++${rules}:1 Line is too long, ignored. + ${rules}: udev rules check failed. + EOF + assert_1 "${rules}" diff --git a/SOURCES/0344-chase-introduce-flags-that-verify-that-chased-inode-.patch b/SOURCES/0344-chase-introduce-flags-that-verify-that-chased-inode-.patch new file mode 100644 index 0000000000000000000000000000000000000000..70973dc200f6bfc9759be799eb2b21b900a89442 --- /dev/null +++ b/SOURCES/0344-chase-introduce-flags-that-verify-that-chased-inode-.patch @@ -0,0 +1,96 @@ +From a5486de446d4312b9bebdcb3ab8d6325187930f6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering <lennart@poettering.net> +Date: Mon, 13 Jan 2025 13:12:23 +0100 +Subject: [PATCH] chase: introduce flags that verify that chased inode is + regular file or dir + +This also implies the new CHASE_MUST_BE_DIRECTORY flag in case the +specified path ends in a slash. This makes the rules stricter, it means +we'll be closer to how this is handled in kernel: if a path ends in a +slash it can never refer to a non-directory. + +(cherry picked from commit 90b9f7a07e6f57825f416f6ce2db0a9f2086754b) + +Resolves: RHEL-75774 +--- + src/basic/chase.c | 20 +++++++++++++++++--- + src/basic/chase.h | 2 ++ + src/shared/machine-id-setup.c | 2 +- + 3 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/basic/chase.c b/src/basic/chase.c +index 8eac356665..e5a6fb1587 100644 +--- a/src/basic/chase.c ++++ b/src/basic/chase.c +@@ -89,6 +89,7 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int + int r; + + assert(!FLAGS_SET(flags, CHASE_PREFIX_ROOT)); ++ assert(!FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY|CHASE_MUST_BE_REGULAR)); + assert(!FLAGS_SET(flags, CHASE_STEP|CHASE_EXTRACT_FILENAME)); + assert(!FLAGS_SET(flags, CHASE_TRAIL_SLASH|CHASE_EXTRACT_FILENAME)); + assert(!FLAGS_SET(flags, CHASE_MKDIR_0755) || (flags & (CHASE_NONEXISTENT | CHASE_PARENT)) != 0); +@@ -244,8 +245,15 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int + if (root_fd < 0) + return -errno; + +- if (FLAGS_SET(flags, CHASE_TRAIL_SLASH)) +- append_trail_slash = ENDSWITH_SET(buffer, "/", "/."); ++ if (ENDSWITH_SET(buffer, "/", "/.")) { ++ flags |= CHASE_MUST_BE_DIRECTORY; ++ if (FLAGS_SET(flags, CHASE_TRAIL_SLASH)) ++ append_trail_slash = true; ++ } else if (dot_or_dot_dot(buffer) || endswith(buffer, "/..")) ++ flags |= CHASE_MUST_BE_DIRECTORY; ++ ++ if (FLAGS_SET(flags, CHASE_PARENT)) ++ flags |= CHASE_MUST_BE_DIRECTORY; + + for (todo = buffer;;) { + _cleanup_free_ char *first = NULL; +@@ -477,12 +485,18 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int + close_and_replace(fd, child); + } + +- if (FLAGS_SET(flags, CHASE_PARENT)) { ++ if (FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY)) { + r = stat_verify_directory(&st); + if (r < 0) + return r; + } + ++ if (FLAGS_SET(flags, CHASE_MUST_BE_REGULAR)) { ++ r = stat_verify_regular(&st); ++ if (r < 0) ++ return r; ++ } ++ + if (ret_path) { + if (FLAGS_SET(flags, CHASE_EXTRACT_FILENAME) && done) { + _cleanup_free_ char *f = NULL; +diff --git a/src/basic/chase.h b/src/basic/chase.h +index cfc714b9f7..2d708b4bae 100644 +--- a/src/basic/chase.h ++++ b/src/basic/chase.h +@@ -33,6 +33,8 @@ typedef enum ChaseFlags { + * when internally call chase(), hence CHASE_MKDIR_0755 can be + * safely set without CHASE_NONEXISTENT and CHASE_PARENT. */ + CHASE_EXTRACT_FILENAME = 1 << 12, /* Only return the last component of the resolved path */ ++ CHASE_MUST_BE_DIRECTORY = 1 << 13, /* Fail if returned inode fd is not a dir */ ++ CHASE_MUST_BE_REGULAR = 1 << 14, /* Fail if returned inode fd is not a regular file */ + } ChaseFlags; + + bool unsafe_transition(const struct stat *a, const struct stat *b); +diff --git a/src/shared/machine-id-setup.c b/src/shared/machine-id-setup.c +index f5e1b9ee72..4e355d8144 100644 +--- a/src/shared/machine-id-setup.c ++++ b/src/shared/machine-id-setup.c +@@ -74,7 +74,7 @@ static int acquire_machine_id(const char *root, bool machine_id_from_firmware, s + } + + /* Then, try reading the D-Bus machine ID, unless it is a symlink */ +- fd = chase_and_open("/var/lib/dbus/machine-id", root, CHASE_PREFIX_ROOT | CHASE_NOFOLLOW, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL); ++ fd = chase_and_open("/var/lib/dbus/machine-id", root, CHASE_PREFIX_ROOT|CHASE_NOFOLLOW|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL); + if (fd >= 0 && id128_read_fd(fd, ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, ret) >= 0) { + log_info("Initializing machine ID from D-Bus machine ID."); + return 0; diff --git a/SOURCES/0345-udevadm-verify-chase-specified-paths.patch b/SOURCES/0345-udevadm-verify-chase-specified-paths.patch new file mode 100644 index 0000000000000000000000000000000000000000..42303f44f02180c5a07477c30adf3b836af3193c --- /dev/null +++ b/SOURCES/0345-udevadm-verify-chase-specified-paths.patch @@ -0,0 +1,541 @@ +From 109617461d161e7a0e1a167a4cef92830628f671 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 9 Jan 2025 10:27:11 +0900 +Subject: [PATCH] udevadm-verify: chase specified paths + +Also, when a filename is specified, also search udev rules file in +udev/rules.d directories. + +This also refuses non-existing files, and file neither nor a regular +nor a directory, e.g. /dev/null. + +(cherry picked from commit 7cb4508c5af465ab1be1b103e6c2b613eb58e63c) + +Resolves: RHEL-75774 +--- + man/udevadm.xml | 28 +++++---- + src/udev/udevadm-util.c | 109 ++++++++++++++++++++++++++++++++++ + src/udev/udevadm-util.h | 1 + + src/udev/udevadm-verify.c | 85 ++++++-------------------- + test/units/TEST-17-UDEV.11.sh | 79 ++++++++++++------------ + 5 files changed, 182 insertions(+), 120 deletions(-) + +diff --git a/man/udevadm.xml b/man/udevadm.xml +index 79907b30c3..eed84d27cc 100644 +--- a/man/udevadm.xml ++++ b/man/udevadm.xml +@@ -935,9 +935,15 @@ + + <para>Verify syntactic, semantic, and stylistic correctness of udev rules files.</para> + +- <para>Positional arguments could be used to specify one or more files to check. +- If no files are specified, the udev rules are read from the files located in +- the same udev/rules.d directories that are processed by the udev daemon.</para> ++ <para>Positional arguments can be used to specify one or more files to check. Each argument must be an ++ absolute path to a udev rules file or a directory that contains rules files, or a file name of udev ++ rules file (e.g. <filename>99-systemd.rules</filename>). If a file name is specified, the file will be ++ searched in the <filename>udev/rules.d</filename> directories that are processed by ++ <command>systemd-udevd</command>, and searched in the current working directory if not found. If no ++ files are specified, the udev rules are read from the files located in the same ++ <filename>udev/rules.d</filename> directories that are processed by <command>systemd-udevd</command>. ++ See <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry> for more ++ details about the search paths.</para> + + <para>The exit status is <constant>0</constant> if all specified udev + rules files are syntactically, semantically, and stylistically correct, +@@ -961,8 +967,11 @@ + <varlistentry> + <term><option>--root=<replaceable>PATH</replaceable></option></term> + <listitem> +- <para>When looking for udev rules files located in udev/rules.d directories, +- operate on files underneath the specified root path <replaceable>PATH</replaceable>.</para> ++ <para>When looking for udev rules files located in the <filename>udev/rules.d</filename> ++ directories, operate on files underneath the specified root path <replaceable>PATH</replaceable>. ++ When a file name is specified, and it is not found in the <filename>udev/rules.d</filename> ++ directories, the file will be searched in the specified root path ++ <replaceable>PATH</replaceable>, rather than the current working directory.</para> + + <xi:include href="version-info.xml" xpointer="v254"/> + </listitem> +@@ -1192,12 +1201,9 @@ + <refsect1> + <title>See Also</title> + <para><simplelist type="inline"> +- <member><citerefentry> +- <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum> +- </citerefentry></member> +- <member><citerefentry> +- <refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum> +- </citerefentry></member> ++ <member><citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> ++ <member><citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> ++ <member><citerefentry><refentrytitle>udev.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> + </simplelist></para> + </refsect1> + </refentry> +diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c +index 2447edad19..4aa5e6b6d7 100644 +--- a/src/udev/udevadm-util.c ++++ b/src/udev/udevadm-util.c +@@ -5,6 +5,9 @@ + #include "alloc-util.h" + #include "bus-error.h" + #include "bus-util.h" ++#include "chase.h" ++#include "conf-files.h" ++#include "constants.h" + #include "device-private.h" + #include "path-util.h" + #include "udevadm-util.h" +@@ -122,3 +125,109 @@ int parse_device_action(const char *str, sd_device_action_t *action) { + *action = a; + return 1; + } ++ ++static int search_rules_file_in_conf_dirs(const char *s, const char *root, char ***files) { ++ _cleanup_free_ char *filename = NULL; ++ int r; ++ ++ assert(s); ++ ++ if (!endswith(s, ".rules")) ++ filename = strjoin(s, ".rules"); ++ else ++ filename = strdup(s); ++ if (!filename) ++ return log_oom(); ++ ++ if (!filename_is_valid(filename)) ++ return 0; ++ ++ STRV_FOREACH(p, CONF_PATHS_STRV("udev/rules.d")) { ++ _cleanup_free_ char *path = NULL, *resolved = NULL; ++ ++ path = path_join(*p, filename); ++ if (!path) ++ return log_oom(); ++ ++ r = chase(path, root, CHASE_PREFIX_ROOT | CHASE_MUST_BE_REGULAR, &resolved, /* ret_fd = */ NULL); ++ if (r == -ENOENT) ++ continue; ++ if (r < 0) ++ return log_error_errno(r, "Failed to chase \"%s\": %m", path); ++ ++ r = strv_consume(files, TAKE_PTR(resolved)); ++ if (r < 0) ++ return log_oom(); ++ ++ return 1; /* found */ ++ } ++ ++ return 0; ++} ++ ++static int search_rules_file(const char *s, const char *root, char ***files) { ++ int r; ++ ++ assert(s); ++ assert(files); ++ ++ /* If the input is a file name (e.g. 99-systemd.rules), then try to find it in udev/rules.d directories. */ ++ r = search_rules_file_in_conf_dirs(s, root, files); ++ if (r != 0) ++ return r; ++ ++ /* If not found, or if it is a path, then chase it. */ ++ struct stat st; ++ _cleanup_free_ char *resolved = NULL; ++ r = chase_and_stat(s, root, CHASE_PREFIX_ROOT, &resolved, &st); ++ if (r < 0) ++ return log_error_errno(r, "Failed to chase \"%s\": %m", s); ++ ++ r = stat_verify_regular(&st); ++ if (r == -EISDIR) { ++ _cleanup_strv_free_ char **files_in_dir = NULL; ++ ++ r = conf_files_list_strv(&files_in_dir, ".rules", root, 0, (const char* const*) STRV_MAKE_CONST(s)); ++ if (r < 0) ++ return log_error_errno(r, "Failed to enumerate rules files in '%s': %m", resolved); ++ ++ r = strv_extend_strv_consume(files, TAKE_PTR(files_in_dir), /* filter_duplicates = */ false); ++ if (r < 0) ++ return log_oom(); ++ ++ return 0; ++ } ++ if (r < 0) ++ return log_error_errno(r, "'%s' is neither a regular file nor a directory: %m", resolved); ++ ++ r = strv_consume(files, TAKE_PTR(resolved)); ++ if (r < 0) ++ return log_oom(); ++ ++ return 0; ++} ++ ++int search_rules_files(char * const *a, const char *root, char ***ret) { ++ _cleanup_strv_free_ char **files = NULL; ++ int r; ++ ++ assert(ret); ++ ++ if (strv_isempty(a)) { ++ r = conf_files_list_strv(&files, ".rules", root, 0, (const char* const*) CONF_PATHS_STRV("udev/rules.d")); ++ if (r < 0) ++ return log_error_errno(r, "Failed to enumerate rules files: %m"); ++ ++ if (root && strv_isempty(files)) ++ return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "No rules files found in %s.", root); ++ ++ } else ++ STRV_FOREACH(s, a) { ++ r = search_rules_file(*s, root, &files); ++ if (r < 0) ++ return r; ++ } ++ ++ *ret = TAKE_PTR(files); ++ return 0; ++} +diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h +index 7fb4556413..9a396a1faa 100644 +--- a/src/udev/udevadm-util.h ++++ b/src/udev/udevadm-util.h +@@ -6,3 +6,4 @@ + int find_device(const char *id, const char *prefix, sd_device **ret); + int find_device_with_action(const char *id, sd_device_action_t action, sd_device **ret); + int parse_device_action(const char *str, sd_device_action_t *action); ++int search_rules_files(char * const *a, const char *root, char ***ret); +diff --git a/src/udev/udevadm-verify.c b/src/udev/udevadm-verify.c +index 32202508f3..fb8cdee4f2 100644 +--- a/src/udev/udevadm-verify.c ++++ b/src/udev/udevadm-verify.c +@@ -7,16 +7,15 @@ + #include <stdlib.h> + #include <unistd.h> + +-#include "conf-files.h" +-#include "constants.h" ++#include "errno-util.h" + #include "log.h" + #include "parse-argument.h" + #include "pretty-print.h" +-#include "stat-util.h" + #include "static-destruct.h" + #include "strv.h" + #include "udev-rules.h" + #include "udevadm.h" ++#include "udevadm-util.h" + + static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; + static char *arg_root = NULL; +@@ -109,10 +108,6 @@ static int parse_argv(int argc, char *argv[]) { + assert_not_reached(); + } + +- if (arg_root && optind < argc) +- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), +- "Combination of --root= and FILEs is not supported."); +- + return 1; + } + +@@ -139,57 +134,20 @@ static int verify_rules_file(UdevRules *rules, const char *fname) { + return 0; + } + +-static int verify_rules_filelist(UdevRules *rules, char **files, size_t *fail_count, size_t *success_count, bool walk_dirs); +- +-static int verify_rules_dir(UdevRules *rules, const char *dir, size_t *fail_count, size_t *success_count) { +- int r; +- _cleanup_strv_free_ char **files = NULL; +- +- assert(rules); +- assert(dir); +- assert(fail_count); +- assert(success_count); +- +- r = conf_files_list(&files, ".rules", NULL, 0, dir); +- if (r < 0) +- return log_error_errno(r, "Failed to enumerate rules files: %m"); +- +- return verify_rules_filelist(rules, files, fail_count, success_count, /* walk_dirs */ false); +-} +- +-static int verify_rules_filelist(UdevRules *rules, char **files, size_t *fail_count, size_t *success_count, bool walk_dirs) { +- int r, rv = 0; +- +- assert(rules); +- assert(files); +- assert(fail_count); +- assert(success_count); +- +- STRV_FOREACH(fp, files) { +- if (walk_dirs && is_dir(*fp, /* follow = */ true) > 0) +- r = verify_rules_dir(rules, *fp, fail_count, success_count); +- else { +- r = verify_rules_file(rules, *fp); +- if (r < 0) +- ++(*fail_count); +- else +- ++(*success_count); +- } +- if (r < 0 && rv >= 0) +- rv = r; +- } +- +- return rv; +-} +- + static int verify_rules(UdevRules *rules, char **files) { + size_t fail_count = 0, success_count = 0; +- int r; ++ int r, ret = 0; + + assert(rules); +- assert(files); + +- r = verify_rules_filelist(rules, files, &fail_count, &success_count, /* walk_dirs */ true); ++ STRV_FOREACH(fp, files) { ++ r = verify_rules_file(rules, *fp); ++ if (r < 0) ++ ++fail_count; ++ else ++ ++success_count; ++ RET_GATHER(ret, r); ++ } + + if (arg_summary) + printf("\n%s%zu udev rules files have been checked.%s\n" +@@ -203,7 +161,7 @@ static int verify_rules(UdevRules *rules, char **files) { + fail_count, + fail_count > 0 ? ansi_normal() : ""); + +- return r; ++ return ret; + } + + int verify_main(int argc, char *argv[], void *userdata) { +@@ -218,19 +176,10 @@ int verify_main(int argc, char *argv[], void *userdata) { + if (!rules) + return -ENOMEM; + +- if (optind == argc) { +- const char* const* rules_dirs = STRV_MAKE_CONST(CONF_PATHS("udev/rules.d")); +- _cleanup_strv_free_ char **files = NULL; +- +- r = conf_files_list_strv(&files, ".rules", arg_root, 0, rules_dirs); +- if (r < 0) +- return log_error_errno(r, "Failed to enumerate rules files: %m"); +- if (arg_root && strv_isempty(files)) +- return log_error_errno(SYNTHETIC_ERRNO(ENOENT), +- "No rules files found in %s.", arg_root); +- +- return verify_rules(rules, files); +- } ++ _cleanup_strv_free_ char **files = NULL; ++ r = search_rules_files(strv_skip(argv, optind), arg_root, &files); ++ if (r < 0) ++ return r; + +- return verify_rules(rules, strv_skip(argv, optind)); ++ return verify_rules(rules, files); + } +diff --git a/test/units/TEST-17-UDEV.11.sh b/test/units/TEST-17-UDEV.11.sh +index c0d87b7151..ac99a80b0f 100755 +--- a/test/units/TEST-17-UDEV.11.sh ++++ b/test/units/TEST-17-UDEV.11.sh +@@ -8,6 +8,8 @@ set -o pipefail + # shellcheck source=test/units/util.sh + . "$(dirname "$0")"/util.sh + ++PATH=/var/build:$PATH ++ + # shellcheck disable=SC2317 + cleanup() { + cd / +@@ -101,7 +103,6 @@ assert_0 -h + assert_0 --help + assert_0 -V + assert_0 --version +-assert_0 /dev/null + + # unrecognized option '--unknown' + assert_1 --unknown +@@ -116,13 +117,9 @@ assert_1 --resolve-names=now + # Failed to parse rules file ./nosuchfile: No such file or directory + assert_1 ./nosuchfile + # Failed to parse rules file ./nosuchfile: No such file or directory +-cat >"${exo}" <<EOF +- +-3 udev rules files have been checked. +- Success: 2 +- Fail: 1 +-EOF +-assert_1 /dev/null ./nosuchfile /dev/null ++assert_1 ./nosuchfile /dev/null ++# '/dev/null' is neither a regular file nor a directory: File descriptor in bad state ++assert_1 /dev/null + + rules_dir='etc/udev/rules.d' + mkdir -p "${rules_dir}" +@@ -148,8 +145,6 @@ assert_0 --root="${workdir}" --no-summary + cp "${workdir}/default_output_1_success" "${exo}" + assert_0 "${rules_dir}" + +-# Combination of --root= and FILEs is not supported. +-assert_1 --root="${workdir}" /dev/null + # No rules files found in nosuchdir + assert_1 --root=nosuchdir + +@@ -161,7 +156,7 @@ assert_0 "${rules}" + + # Failed to parse rules file ${rules}: No buffer space available + printf '%16384s\n' ' ' >"${rules}" +-echo "Failed to parse rules file ${rules}: No buffer space available" >"${exp}" ++echo "Failed to parse rules file $(pwd)/${rules}: No buffer space available" >"${exp}" + assert_1 "${rules}" + + { +@@ -174,17 +169,17 @@ assert_0 "${rules}" + printf 'RUN+="/bin/true"%8176s\\\n #\n' ' ' ' ' >"${rules}" + echo >>"${rules}" + cat >"${exp}" <<EOF +-${rules}:1 Line is too long, ignored. +-${rules}: udev rules check failed. ++$(pwd)/${rules}:1 Line is too long, ignored. ++$(pwd)/${rules}: udev rules check failed. + EOF + assert_1 "${rules}" + + printf '\\\n' >"${rules}" + cat >"${exp}" <<EOF +-${rules}:1 Unexpected EOF after line continuation, line ignored. +-${rules}: udev rules check failed. ++$(pwd)/${rules}:1 Unexpected EOF after line continuation, line ignored. ++$(pwd)/${rules}: udev rules check failed. + EOF +-assert_1 "${rules}" ++assert_1 --root="${workdir}" "${rules}" + + test_syntax_error() { + local rule msg +@@ -194,8 +189,8 @@ test_syntax_error() { + + printf '%s\n' "${rule}" >"${rules}" + cat >"${exp}" <<EOF +-${rules}:1 ${msg} +-${rules}: udev rules check failed. ++$(pwd)/${rules}:1 ${msg} ++$(pwd)/${rules}: udev rules check failed. + EOF + assert_1 "${rules}" + } +@@ -208,8 +203,8 @@ test_style_error() { + + printf '%s\n' "${rule}" >"${rules}" + cat >"${exp}" <<EOF +-${rules}:1 ${msg} +-${rules}: udev rules have style issues. ++$(pwd)/${rules}:1 ${msg} ++$(pwd)/${rules}: udev rules have style issues. + EOF + assert_0_impl --no-style "${rules}" + assert_1_impl "${rules}" +@@ -365,9 +360,9 @@ assert_0 "${rules}" + + echo 'GOTO="a"' >"${rules}" + cat >"${exp}" <<EOF +-${rules}:1 GOTO="a" has no matching label, ignoring. +-${rules}:1 The line has no effect any more, dropping. +-${rules}: udev rules check failed. ++$(pwd)/${rules}:1 GOTO="a" has no matching label, ignoring. ++$(pwd)/${rules}:1 The line has no effect any more, dropping. ++$(pwd)/${rules}: udev rules check failed. + EOF + assert_1 "${rules}" + +@@ -383,8 +378,8 @@ LABEL="b" + LABEL="b" + EOF + cat >"${exp}" <<EOF +-${rules}:3 style: LABEL="b" is unused. +-${rules}: udev rules have style issues. ++$(pwd)/${rules}:3 style: LABEL="b" is unused. ++$(pwd)/${rules}: udev rules have style issues. + EOF + assert_0_impl --no-style "${rules}" + assert_1_impl "${rules}" +@@ -394,11 +389,11 @@ GOTO="a" + LABEL="a", LABEL="b" + EOF + cat >"${exp}" <<EOF +-${rules}:2 Contains multiple LABEL keys, ignoring LABEL="a". +-${rules}:1 GOTO="a" has no matching label, ignoring. +-${rules}:1 The line has no effect any more, dropping. +-${rules}:2 style: LABEL="b" is unused. +-${rules}: udev rules check failed. ++$(pwd)/${rules}:2 Contains multiple LABEL keys, ignoring LABEL="a". ++$(pwd)/${rules}:1 GOTO="a" has no matching label, ignoring. ++$(pwd)/${rules}:1 The line has no effect any more, dropping. ++$(pwd)/${rules}:2 style: LABEL="b" is unused. ++$(pwd)/${rules}: udev rules check failed. + EOF + assert_1 "${rules}" + +@@ -406,9 +401,9 @@ cat >"${rules}" <<'EOF' + KERNEL!="", KERNEL=="?*", KERNEL=="", NAME="a" + EOF + cat >"${exp}" <<EOF +-${rules}:1 duplicate expressions. +-${rules}:1 conflicting match expressions, the line has no effect. +-${rules}: udev rules check failed. ++$(pwd)/${rules}:1 duplicate expressions. ++$(pwd)/${rules}:1 conflicting match expressions, the line has no effect. ++$(pwd)/${rules}: udev rules check failed. + EOF + assert_1 "${rules}" + +@@ -416,9 +411,9 @@ cat >"${rules}" <<'EOF' + ACTION=="a"NAME="b" + EOF + cat >"${exp}" <<EOF +-${rules}:1 style: a comma between tokens is expected. +-${rules}:1 style: whitespace between tokens is expected. +-${rules}: udev rules have style issues. ++$(pwd)/${rules}:1 style: a comma between tokens is expected. ++$(pwd)/${rules}:1 style: whitespace between tokens is expected. ++$(pwd)/${rules}: udev rules have style issues. + EOF + assert_0_impl --no-style "${rules}" + assert_1_impl "${rules}" +@@ -428,22 +423,24 @@ cat >"${rules}" <<'EOF' + ACTION=="a" ,NAME="b" + EOF + cat >"${exp}" <<EOF +-${rules}:1 style: stray whitespace before comma. +-${rules}:1 style: whitespace after comma is expected. +-${rules}: udev rules have style issues. ++$(pwd)/${rules}:1 style: stray whitespace before comma. ++$(pwd)/${rules}:1 style: whitespace after comma is expected. ++$(pwd)/${rules}: udev rules have style issues. + EOF + assert_0_impl --no-style "${rules}" + assert_1_impl "${rules}" + next_test_number + + # udevadm verify --root +-sed "s|sample-[0-9]*.rules|${workdir}/${rules_dir}/&|" sample-*.exp >"${workdir}/${exp}" ++#sed "s|sample-[0-9]*.rules|${workdir}/${rules_dir}/&|" sample-*.exp >"${workdir}/${exp}" ++cat sample-*.exp >"${workdir}/${exp}" + cd - + assert_1 --root="${workdir}" + cd - + + # udevadm verify path/ +-sed "s|sample-[0-9]*.rules|${workdir}/${rules_dir}/&|" sample-*.exp >"${workdir}/${exp}" ++#sed "s|sample-[0-9]*.rules|${workdir}/${rules_dir}/&|" sample-*.exp >"${workdir}/${exp}" ++cat sample-*.exp >"${workdir}/${exp}" + cd - + assert_1 "${rules_dir}" + cd - diff --git a/SOURCES/0346-bash-completion-udevadm-verify-suggest-found-udev-ru.patch b/SOURCES/0346-bash-completion-udevadm-verify-suggest-found-udev-ru.patch new file mode 100644 index 0000000000000000000000000000000000000000..66065b5c3fc39d27036df7629fe013d1d58379d8 --- /dev/null +++ b/SOURCES/0346-bash-completion-udevadm-verify-suggest-found-udev-ru.patch @@ -0,0 +1,103 @@ +From 6aa9e8d394dc04f3432a74e837cd21a3e860a43c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 9 Jan 2025 19:25:49 +0900 +Subject: [PATCH] bash-completion/udevadm-verify: suggest found udev rules + files + +This also fixes the issue that no suggestion is provided after a standalone +option is specified. + +(cherry picked from commit bbe1ba5e87a74fa0b56d88a7266040e534c527b0) + +Resolves: RHEL-75774 +--- + shell-completion/bash/udevadm | 50 ++++++++++++++++++++++++++++------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm +index 496eac5fd7..54d024c1b8 100644 +--- a/shell-completion/bash/udevadm ++++ b/shell-completion/bash/udevadm +@@ -46,6 +46,35 @@ __get_all_devices() { + __get_all_device_units + } + ++__get_root() { ++ local i ++ ++ for ((i=0; i < COMP_CWORD; i++)); do ++ if [[ "${COMP_WORDS[i]}" = --root=* ]]; then ++ echo "${COMP_WORDS[i]#--root=}" ++ break ++ fi ++ if (( i > 0 )) && [[ "${COMP_WORDS[i-1]}" == "--root" ]]; then ++ echo "${COMP_WORDS[i]}" ++ break ++ fi ++ done ++} ++ ++__get_udev_rules_files() { ++ local root=$( __get_root ) ++ ++ ls "$root"/usr/lib/udev/rules.d/*.rules \ ++ "$root"/usr/local/lib/udev/rules.d/*.rules \ ++ "$root"/run/udev/rules.d/*.rules \ ++ "$root"/etc/udev/rules.d/*.rules 2>/dev/null ++} ++ ++__get_udev_rules_names() { ++ local -a rules=( $( __get_udev_rules_files ) ) ++ printf '%s\n' "${rules[@]##*/}" ++} ++ + _udevadm() { + local i verb comps builtin + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} +@@ -72,7 +101,8 @@ _udevadm() { + [TEST_STANDALONE]='-v --verbose' + [TEST_ARG]='-a --action -N --resolve-names -D --extra-rules-dir' + [TEST_BUILTIN]='-a --action' +- [VERIFY]='-N --resolve-names --root --no-summary --no-style' ++ [VERIFY_STANDALONE]='--no-summary --no-style' ++ [VERIFY_ARG]='-N --resolve-names --root' + [WAIT]='-t --timeout --initialized=no --removed --settle' + [LOCK]='-t --timeout -d --device -b --backing -p --print' + ) +@@ -266,27 +296,27 @@ _udevadm() { + ;; + + 'verify') +- if __contains_word "$prev" ${OPTS[VERIFY]}; then ++ if __contains_word "$prev" ${OPTS[VERIFY_ARG]}; then + case $prev in + -N|--resolve-names) + comps='early never' + ;; + --root) +- comps=$(compgen -A directory -- "$cur" ) ++ comps='' + compopt -o dirnames + ;; + *) + comps='' + ;; + esac +- COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) +- return 0 +- fi +- +- if [[ $cur = -* ]]; then +- comps="${OPTS[COMMON]} ${OPTS[VERIFY]}" ++ elif [[ $cur = -* ]]; then ++ comps="${OPTS[COMMON]} ${OPTS[VERIFY_ARG]} ${OPTS[VERIFY_STANDALONE]}" ++ elif [[ $cur = */* ]]; then ++ comps=$( __get_udev_rules_files ) ++ compopt -o dirnames + else +- comps=$( compgen -A file -- "$cur" ) ++ comps=$( __get_udev_rules_names ) ++ compopt -o default + fi + ;; + diff --git a/SOURCES/0347-udevadm-introduce-cat-command.patch b/SOURCES/0347-udevadm-introduce-cat-command.patch new file mode 100644 index 0000000000000000000000000000000000000000..0a42516e629f0c338d680585decb3b9388950483 --- /dev/null +++ b/SOURCES/0347-udevadm-introduce-cat-command.patch @@ -0,0 +1,359 @@ +From 29959da4228413ad35faf9656c8304ebfd0c482d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 7 Jan 2025 16:58:37 +0900 +Subject: [PATCH] udevadm: introduce cat command + +This introduces 'udevadm cat' command, that shows udev rules files or +udev.conf, which may be useful for debugging. + +Closes #35818. + +(cherry picked from commit 7f2175eabbea882d02e9df0e9fcb8e2f03a121da) + +Resolves: RHEL-75774 +--- + man/udevadm.xml | 64 ++++++++++++++++++++ + shell-completion/bash/udevadm | 28 ++++++++- + shell-completion/zsh/_udevadm | 11 ++++ + src/udev/meson.build | 1 + + src/udev/udevadm-cat.c | 110 ++++++++++++++++++++++++++++++++++ + src/udev/udevadm.c | 2 + + src/udev/udevadm.h | 1 + + test/units/TEST-17-UDEV.10.sh | 9 +++ + 8 files changed, 225 insertions(+), 1 deletion(-) + create mode 100644 src/udev/udevadm-cat.c + +diff --git a/man/udevadm.xml b/man/udevadm.xml +index eed84d27cc..9cbbdc254d 100644 +--- a/man/udevadm.xml ++++ b/man/udevadm.xml +@@ -53,6 +53,11 @@ + <arg choice="opt" rep="repeat">options</arg> + <arg choice="opt" rep="repeat"><replaceable>file</replaceable></arg> + </cmdsynopsis> ++ <cmdsynopsis> ++ <command>udevadm cat</command> ++ <arg choice="opt" rep="repeat">options</arg> ++ <arg choice="opt" rep="repeat"><replaceable>file</replaceable></arg> ++ </cmdsynopsis> + <cmdsynopsis> + <command>udevadm wait <optional>options</optional> <replaceable>device|syspath</replaceable></command> + </cmdsynopsis> +@@ -1000,6 +1005,65 @@ + </variablelist> + </refsect2> + ++ <refsect2> ++ <title>udevadm cat ++ <optional><replaceable>options</replaceable></optional> ++ <optional><replaceable>file</replaceable></optional> ++ … ++ </title> ++ ++ <para>Show udev rules files or udev.conf.</para> ++ ++ <para>Positional arguments can be used to specify one or more files to show. Each argument must be an ++ absolute path to a udev rules file or a directory that contains rules files, or a file name of udev ++ rules file (e.g. <filename>99-systemd.rules</filename>). If a file name is specified, the file will be ++ searched in the <filename>udev/rules.d</filename> directories that are processed by ++ <command>systemd-udevd</command>, and searched in the current working directory if not found. If no ++ files are specified, the udev rules are read from the files located in the same ++ <filename>udev/rules.d</filename> directories that are processed by <command>systemd-udevd</command>. ++ See <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry> for more ++ details about the search paths.</para> ++ ++ <variablelist> ++ <varlistentry> ++ <term><option>--root=<replaceable>PATH</replaceable></option></term> ++ <listitem> ++ <para>When looking for udev rules files located in the <filename>udev/rules.d</filename> ++ directories, operate on files underneath the specified root path <replaceable>PATH</replaceable>. ++ When a file name is specified, and it is not found in the <filename>udev/rules.d</filename> ++ directories, the file will be searched in the specified root path ++ <replaceable>PATH</replaceable>, rather than the current working directory.</para> ++ ++ <xi:include href="version-info.xml" xpointer="v258"/> ++ </listitem> ++ </varlistentry> ++ ++ <varlistentry> ++ <term><option>--tldr</option></term> ++ <listitem> ++ <para>Only print the "interesting" parts of the configuration files, skipping comments and empty ++ lines and section headers followed only by comments and empty lines.</para> ++ ++ <xi:include href="version-info.xml" xpointer="v258"/> ++ </listitem> ++ </varlistentry> ++ ++ <varlistentry> ++ <term><option>--config</option></term> ++ <listitem> ++ <para>Shows ++ <citerefentry><refentrytitle>udev.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> ++ files, rather than udev rules files. When specified, no udev rules file cannot be specified. ++ </para> ++ ++ <xi:include href="version-info.xml" xpointer="v258"/> ++ </listitem> ++ </varlistentry> ++ ++ <xi:include href="standard-options.xml" xpointer="help" /> ++ </variablelist> ++ </refsect2> ++ + <refsect2> + <title>udevadm wait + <optional><replaceable>options</replaceable></optional> +diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm +index 54d024c1b8..010d4cff8a 100644 +--- a/shell-completion/bash/udevadm ++++ b/shell-completion/bash/udevadm +@@ -103,11 +103,13 @@ _udevadm() { + [TEST_BUILTIN]='-a --action' + [VERIFY_STANDALONE]='--no-summary --no-style' + [VERIFY_ARG]='-N --resolve-names --root' ++ [CAT_STANDALONE]='--tldr --config' ++ [CAT_ARG]='--root' + [WAIT]='-t --timeout --initialized=no --removed --settle' + [LOCK]='-t --timeout -d --device -b --backing -p --print' + ) + +- local verbs=(info trigger settle control monitor test-builtin test verify wait lock) ++ local verbs=(info trigger settle control monitor test-builtin test verify cat wait lock) + local builtins=(blkid btrfs hwdb input_id keyboard kmod net_driver net_id net_setup_link path_id uaccess usb_id) + + for ((i=0; i < COMP_CWORD; i++)); do +@@ -320,6 +322,30 @@ _udevadm() { + fi + ;; + ++ 'cat') ++ if __contains_word "$prev" ${OPTS[CAT_ARG]}; then ++ case $prev in ++ --root) ++ comps='' ++ compopt -o dirnames ++ ;; ++ *) ++ comps='' ++ ;; ++ esac ++ elif [[ $cur = -* ]]; then ++ comps="${OPTS[COMMON]} ${OPTS[CAT_ARG]} ${OPTS[CAT_STANDALONE]}" ++ elif __contains_word "--config" ${COMP_WORDS[*]}; then ++ comps="${OPTS[COMMON]} ${OPTS[CAT_ARG]} ${OPTS[CAT_STANDALONE]}" ++ elif [[ $cur = */* ]]; then ++ comps=$( __get_udev_rules_files ) ++ compopt -o dirnames ++ else ++ comps=$( __get_udev_rules_names ) ++ compopt -o default ++ fi ++ ;; ++ + 'wait') + if __contains_word "$prev" ${OPTS[WAIT]}; then + case $prev in +diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm +index 63db11cea9..c9b43e231d 100644 +--- a/shell-completion/zsh/_udevadm ++++ b/shell-completion/zsh/_udevadm +@@ -124,6 +124,17 @@ _udevadm_verify(){ + '*::files:_files' + } + ++(( $+functions[_udevadm_cat] )) || ++_udevadm_cat(){ ++ _arguments \ ++ '(- *)'{-h,--help}'[Show help]' \ ++ '(- *)'{-V,--version}'[Show package version]' \ ++ '--root=[Operate on catalog hierarchy under specified directory]:directories:_directories' \ ++ --tldr'[Skip comments and empty lines.]' \ ++ --config'[Show udev.conf.]' \ ++ '*::files:_files' ++} ++ + (( $+functions[_udevadm_wait] )) || + _udevadm_wait(){ + _arguments \ +diff --git a/src/udev/meson.build b/src/udev/meson.build +index 171bbd2b70..62cd8014d2 100644 +--- a/src/udev/meson.build ++++ b/src/udev/meson.build +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: LGPL-2.1-or-later + + udevadm_sources = files( ++ 'udevadm-cat.c', + 'udevadm-control.c', + 'udevadm-hwdb.c', + 'udevadm-info.c', +diff --git a/src/udev/udevadm-cat.c b/src/udev/udevadm-cat.c +new file mode 100644 +index 0000000000..2d7e86994d +--- /dev/null ++++ b/src/udev/udevadm-cat.c +@@ -0,0 +1,110 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include <getopt.h> ++ ++#include "log.h" ++#include "parse-argument.h" ++#include "pretty-print.h" ++#include "static-destruct.h" ++#include "strv.h" ++#include "udevadm.h" ++#include "udevadm-util.h" ++ ++static char *arg_root = NULL; ++static CatFlags arg_cat_flags = 0; ++static bool arg_config = false; ++ ++STATIC_DESTRUCTOR_REGISTER(arg_root, freep); ++ ++static int help(void) { ++ _cleanup_free_ char *link = NULL; ++ int r; ++ ++ r = terminal_urlify_man("udevadm", "8", &link); ++ if (r < 0) ++ return log_oom(); ++ ++ printf("%s cat [OPTIONS] [FILE...]\n" ++ "\n%sShow udev rules files.%s\n\n" ++ " -h --help Show this help\n" ++ " -V --version Show package version\n" ++ " --root=PATH Operate on an alternate filesystem root\n" ++ " --tldr Skip comments and empty lines\n" ++ " --config Show udev.conf rather than udev rules files\n" ++ "\nSee the %s for details.\n", ++ program_invocation_short_name, ++ ansi_highlight(), ++ ansi_normal(), ++ link); ++ ++ return 0; ++} ++ ++static int parse_argv(int argc, char *argv[]) { ++ enum { ++ ARG_ROOT = 0x100, ++ ARG_TLDR, ++ ARG_CONFIG, ++ }; ++ static const struct option options[] = { ++ { "help", no_argument, NULL, 'h' }, ++ { "version", no_argument, NULL, 'V' }, ++ { "root", required_argument, NULL, ARG_ROOT }, ++ { "tldr", no_argument, NULL, ARG_TLDR }, ++ { "config", no_argument, NULL, ARG_CONFIG }, ++ {} ++ }; ++ ++ int r, c; ++ ++ assert(argc >= 0); ++ assert(argv); ++ ++ while ((c = getopt_long(argc, argv, "hVN:", options, NULL)) >= 0) ++ switch (c) { ++ case 'h': ++ return help(); ++ case 'V': ++ return print_version(); ++ case ARG_ROOT: ++ r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root); ++ if (r < 0) ++ return r; ++ break; ++ case ARG_TLDR: ++ arg_cat_flags = CAT_TLDR; ++ break; ++ case ARG_CONFIG: ++ arg_config = true; ++ break; ++ case '?': ++ return -EINVAL; ++ default: ++ assert_not_reached(); ++ } ++ ++ if (arg_config && optind < argc) ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), ++ "Combination of --config and FILEs is not supported."); ++ ++ return 1; ++} ++ ++int cat_main(int argc, char *argv[], void *userdata) { ++ int r; ++ ++ r = parse_argv(argc, argv); ++ if (r <= 0) ++ return r; ++ ++ if (arg_config) ++ return conf_files_cat(arg_root, "udev/udev.conf", arg_cat_flags); ++ ++ _cleanup_strv_free_ char **files = NULL; ++ r = search_rules_files(strv_skip(argv, optind), arg_root, &files); ++ if (r < 0) ++ return r; ++ ++ /* udev rules file does not support dropin configs. So, we can safely pass multiple files as dropins. */ ++ return cat_files(/* file = */ NULL, /* dropins = */ files, arg_cat_flags); ++} +diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c +index 30b6ddb728..ebf1e5190c 100644 +--- a/src/udev/udevadm.c ++++ b/src/udev/udevadm.c +@@ -26,6 +26,7 @@ static int help(void) { + { "test", "Test an event run" }, + { "test-builtin", "Test a built-in command" }, + { "verify", "Verify udev rules files" }, ++ { "cat", "Show udev rules files" }, + { "wait", "Wait for device or device symlink" }, + { "lock", "Lock a block device" }, + }; +@@ -97,6 +98,7 @@ static int help_main(int argc, char *argv[], void *userdata) { + + static int udevadm_main(int argc, char *argv[]) { + static const Verb verbs[] = { ++ { "cat", VERB_ANY, VERB_ANY, 0, cat_main }, + { "info", VERB_ANY, VERB_ANY, 0, info_main }, + { "trigger", VERB_ANY, VERB_ANY, 0, trigger_main }, + { "settle", VERB_ANY, VERB_ANY, 0, settle_main }, +diff --git a/src/udev/udevadm.h b/src/udev/udevadm.h +index 7920a70d5b..e39dbf655d 100644 +--- a/src/udev/udevadm.h ++++ b/src/udev/udevadm.h +@@ -5,6 +5,7 @@ + + #include "macro.h" + ++int cat_main(int argc, char *argv[], void *userdata); + int info_main(int argc, char *argv[], void *userdata); + int trigger_main(int argc, char *argv[], void *userdata); + int settle_main(int argc, char *argv[], void *userdata); +diff --git a/test/units/TEST-17-UDEV.10.sh b/test/units/TEST-17-UDEV.10.sh +index be342b3468..68d310a8e5 100755 +--- a/test/units/TEST-17-UDEV.10.sh ++++ b/test/units/TEST-17-UDEV.10.sh +@@ -33,6 +33,15 @@ udevadm settle --timeout 30 + + udevadm -h + ++udevadm cat ++udevadm cat 99-systemd ++udevadm cat 99-systemd.rules ++udevadm cat /usr/lib/udev/rules.d/99-systemd.rules ++udevadm cat /usr/lib/udev/rules.d ++(! udevadm cat /dev/null) ++udevadm cat --config ++udevadm cat -h ++ + INVOCATION_ID=$(systemctl show --property InvocationID --value systemd-udevd.service) + udevadm control -e + # Wait for systemd-udevd.service being restarted. diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index fcc7c654f52dd33a9340cb79ec658362e052f15b..099853826fc11c6a31c88bc7a6820fbebda39078 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -48,7 +48,7 @@ Url: https://systemd.io # Allow users to specify the version and release when building the rpm by # setting the %%version_override and %%release_override macros. Version: %{?version_override}%{!?version_override:257} -Release: 7%{?dist} +Release: 9%{?dist} %global stable %(c="%version"; [ "$c" = "${c#*.*}" ]; echo $?) @@ -336,67 +336,126 @@ Patch0224: 0224-meson-fix-suite-of-alignment-check-tests.patch Patch0225: 0225-hwdb-Make-remote-controllable-lights-work-out-of-the.patch Patch0226: 0226-hwdb-update-to-main-2025-02-07.patch Patch0227: 0227-udevadm-test-fix-gid-check.patch -Patch0228: 0228-ci-update-workflows-to-run-on-source-git-setup.patch -Patch0229: 0229-ci-setup-source-git-automation.patch -Patch0230: 0230-ci-reconfigure-Packit-for-RHEL-10.patch -Patch0231: 0231-journal-again-create-user-journals-for-users-with-hi.patch -Patch0232: 0232-tmpfiles-make-purge-hard-to-mis-use.patch -Patch0233: 0233-fedora-use-system-auth-in-pam-systemd-user.patch -Patch0234: 0234-net-naming-scheme-start-rhel10-naming-and-include-rh.patch -Patch0235: 0235-rules-copy-40-redhat.rules-from-RHEL-9.patch -Patch0236: 0236-logind-set-RemoveIPC-to-false-by-default.patch -Patch0237: 0237-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch -Patch0238: 0238-rc-local-order-after-network-online.target.patch -Patch0239: 0239-random-util-increase-random-seed-size-to-1024.patch -Patch0240: 0240-journal-don-t-enable-systemd-journald-audit.socket-b.patch -Patch0241: 0241-journald.conf-don-t-touch-current-audit-settings.patch -Patch0242: 0242-rules-add-elevator-kernel-command-line-parameter.patch -Patch0243: 0243-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch -Patch0244: 0244-udev-net-setup-link-change-the-default-MACAddressPol.patch -Patch0245: 0245-core-decrease-log-level-of-messages-about-use-of-Kil.patch -Patch0246: 0246-taint-remove-unmerged-bin.patch -Patch0247: 0247-presets-remove-resolved.patch -Patch0248: 0248-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch -Patch0249: 0249-taint-remove-unused-variable-usr_sbin.patch -Patch0250: 0250-packit-drop-the-libarchive-workaround.patch -Patch0251: 0251-coredump-by-default-process-and-store-core-files-up-.patch -Patch0252: 0252-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch -Patch0253: 0253-unit-don-t-add-Requires-for-tmp.mount.patch -Patch0254: 0254-units-add-Install-section-to-tmp.mount.patch -Patch0255: 0255-units-don-t-enable-tmp.mount-statically-in-local-fs..patch -Patch0256: 0256-netif-naming-scheme-add-rhel-9.5-scheme.patch -Patch0257: 0257-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch -Patch0258: 0258-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch -Patch0259: 0259-netif-naming-scheme-introduce-rhel-10.0-scheme.patch -Patch0260: 0260-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch -Patch0261: 0261-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch -Patch0262: 0262-ci-fix-Packit.patch -Patch0263: 0263-ci-drop-testing-farm-test.patch -Patch0264: 0264-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch -Patch0265: 0265-manager-s-deserialized_subscribed-subscribed_as_strv.patch -Patch0266: 0266-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch -Patch0267: 0267-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch -Patch0268: 0268-shared-bus-util-move-string-set-append-get-funcs-to-.patch -Patch0269: 0269-shared-serialize-make-input-params-const.patch -Patch0270: 0270-shared-serialize-introduce-serialize_id128.patch -Patch0271: 0271-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch -Patch0272: 0272-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch -Patch0273: 0273-core-manager-drop-duplicate-bus-track-deserializatio.patch -Patch0274: 0274-bus-util-introduce-bus_get_instance_id.patch -Patch0275: 0275-core-serialize-API-bus-id-and-validate-before-deseri.patch -Patch0276: 0276-core-manager-restore-bus-track-deserialization-clean.patch -Patch0277: 0277-shared-bus-util-add-missing-set.h-include.patch -Patch0278: 0278-udevadm-test-add-missing-oom-check.patch -Patch0279: 0279-udev-rules-replace-type-func-type-func.patch -Patch0280: 0280-udev-rules-do-not-change-maximum-log-level-when-runn.patch -Patch0281: 0281-udevadm-test-introduce-v-verbose-option-to-show-verb.patch -Patch0282: 0282-udev-rules-show-original-token-string-in-log_event_e.patch -Patch0283: 0283-udev-rules-logs-result-of-format-substitution.patch -Patch0284: 0284-udev-rules-add-more-trace-logs-for-string-match.patch -Patch0285: 0285-udev-rules-introduce-udev_replace_chars_and_log.patch -Patch0286: 0286-udev-rules-ignore-whole-command-result-if-it-is-too-.patch -Patch0287: 0287-udev-rules-update-log-messages.patch -Patch0288: 0288-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch +Patch0228: 0228-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch +Patch0229: 0229-bootctl-fix-potential-uninitialized-memory-access.patch +Patch0230: 0230-bootctl-also-shown-whether-stub-loader-partition-dat.patch +Patch0231: 0231-bootctl-suppress-output-of-empty-partition-info-if-w.patch +Patch0232: 0232-bootctl-minor-reordering-of-fields-in-output.patch +Patch0233: 0233-missing_sched-add-CLONE_PIDFD.patch +Patch0234: 0234-stub-Mention-that-VirtualSize-should-be-SizeOfRawDat.patch +Patch0235: 0235-import-pubring.gpg-add-openSUSE-build-key.patch +Patch0236: 0236-import-update-to-current-fedora-keyring.patch +Patch0237: 0237-ukify-do-not-fail-if-pefile-complains-about-hardcode.patch +Patch0238: 0238-tmpfiles-fix-copypasta-in-create_symlink-FIFO-symlin.patch +Patch0239: 0239-udev-worker-add-debugging-log-about-success-of-flock.patch +Patch0240: 0240-udev-watch-mention-that-the-failure-is-ignored.patch +Patch0241: 0241-udev-watch-do-not-try-to-remove-invalid-watch-handle.patch +Patch0242: 0242-login-Continue-watching-leader-pidfd-after-stop.patch +Patch0243: 0243-login-Queue-session-for-garbage-collection-on-leader.patch +Patch0244: 0244-ukify-print-debug-progress-messages-to-stderr.patch +Patch0245: 0245-ukify-Calculate-section-size-more-correctly.patch +Patch0246: 0246-mkosi-Update-to-latest.patch +Patch0247: 0247-core-condition-fix-segfault-when-key-not-found-in-os.patch +Patch0248: 0248-meson-bump-version-to-257.3.patch +Patch0249: 0249-ci-update-workflows-to-run-on-source-git-setup.patch +Patch0250: 0250-ci-setup-source-git-automation.patch +Patch0251: 0251-ci-reconfigure-Packit-for-RHEL-10.patch +Patch0252: 0252-journal-again-create-user-journals-for-users-with-hi.patch +Patch0253: 0253-tmpfiles-make-purge-hard-to-mis-use.patch +Patch0254: 0254-fedora-use-system-auth-in-pam-systemd-user.patch +Patch0255: 0255-net-naming-scheme-start-rhel10-naming-and-include-rh.patch +Patch0256: 0256-rules-copy-40-redhat.rules-from-RHEL-9.patch +Patch0257: 0257-logind-set-RemoveIPC-to-false-by-default.patch +Patch0258: 0258-tmpfiles-don-t-create-resolv.conf-stub-resolv.conf-s.patch +Patch0259: 0259-rc-local-order-after-network-online.target.patch +Patch0260: 0260-random-util-increase-random-seed-size-to-1024.patch +Patch0261: 0261-journal-don-t-enable-systemd-journald-audit.socket-b.patch +Patch0262: 0262-journald.conf-don-t-touch-current-audit-settings.patch +Patch0263: 0263-rules-add-elevator-kernel-command-line-parameter.patch +Patch0264: 0264-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch +Patch0265: 0265-udev-net-setup-link-change-the-default-MACAddressPol.patch +Patch0266: 0266-core-decrease-log-level-of-messages-about-use-of-Kil.patch +Patch0267: 0267-taint-remove-unmerged-bin.patch +Patch0268: 0268-presets-remove-resolved.patch +Patch0269: 0269-ci-run-mkosi-test-only-for-Fedora-and-CentOS-Stream.patch +Patch0270: 0270-taint-remove-unused-variable-usr_sbin.patch +Patch0271: 0271-packit-drop-the-libarchive-workaround.patch +Patch0272: 0272-coredump-by-default-process-and-store-core-files-up-.patch +Patch0273: 0273-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch +Patch0274: 0274-unit-don-t-add-Requires-for-tmp.mount.patch +Patch0275: 0275-units-add-Install-section-to-tmp.mount.patch +Patch0276: 0276-units-don-t-enable-tmp.mount-statically-in-local-fs..patch +Patch0277: 0277-netif-naming-scheme-add-rhel-9.5-scheme.patch +Patch0278: 0278-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch +Patch0279: 0279-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch +Patch0280: 0280-netif-naming-scheme-introduce-rhel-10.0-scheme.patch +Patch0281: 0281-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch +Patch0282: 0282-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch +Patch0283: 0283-ci-fix-Packit.patch +Patch0284: 0284-ci-drop-testing-farm-test.patch +Patch0285: 0285-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch +Patch0286: 0286-manager-s-deserialized_subscribed-subscribed_as_strv.patch +Patch0287: 0287-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch +Patch0288: 0288-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch +Patch0289: 0289-shared-bus-util-move-string-set-append-get-funcs-to-.patch +Patch0290: 0290-shared-serialize-make-input-params-const.patch +Patch0291: 0291-shared-serialize-introduce-serialize_id128.patch +Patch0292: 0292-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch +Patch0293: 0293-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch +Patch0294: 0294-core-manager-drop-duplicate-bus-track-deserializatio.patch +Patch0295: 0295-bus-util-introduce-bus_get_instance_id.patch +Patch0296: 0296-core-serialize-API-bus-id-and-validate-before-deseri.patch +Patch0297: 0297-core-manager-restore-bus-track-deserialization-clean.patch +Patch0298: 0298-shared-bus-util-add-missing-set.h-include.patch +Patch0299: 0299-udevadm-test-add-missing-oom-check.patch +Patch0300: 0300-udev-rules-replace-type-func-type-func.patch +Patch0301: 0301-udev-rules-do-not-change-maximum-log-level-when-runn.patch +Patch0302: 0302-udevadm-test-introduce-v-verbose-option-to-show-verb.patch +Patch0303: 0303-udev-rules-show-original-token-string-in-log_event_e.patch +Patch0304: 0304-udev-rules-logs-result-of-format-substitution.patch +Patch0305: 0305-udev-rules-add-more-trace-logs-for-string-match.patch +Patch0306: 0306-udev-rules-introduce-udev_replace_chars_and_log.patch +Patch0307: 0307-udev-rules-ignore-whole-command-result-if-it-is-too-.patch +Patch0308: 0308-udev-rules-update-log-messages.patch +Patch0309: 0309-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch +Patch0310: 0310-udev-move-enums-to-udev-def.h.patch +Patch0311: 0311-udev-move-listen_fds-to-udev-manager.c.patch +Patch0312: 0312-udev-several-coding-style-fixes.patch +Patch0313: 0313-udev-builtin-make-udev_builtin_add_property-and-frie.patch +Patch0314: 0314-udev-introduce-reference-counter-for-UdevEvent.patch +Patch0315: 0315-udev-net-make-Link-object-take-reference-to-UdevEven.patch +Patch0316: 0316-udev-move-parsers-for-config-file-kerenel-command-li.patch +Patch0317: 0317-udev-config-introduce-UdevConfig.patch +Patch0318: 0318-udev-reload-.rules-files-and-builtins-only-when-nece.patch +Patch0319: 0319-udev-also-reload-udev.conf-when-explicitly-requested.patch +Patch0320: 0320-TEST-17-use-udevadm-control-reload-or-systemctl-relo.patch +Patch0321: 0321-udevd-add-missing-header-for-glibc-2.34.patch +Patch0322: 0322-meson-sort-source-files.patch +Patch0323: 0323-sd-json-introduce-json_dispatch_log_level.patch +Patch0324: 0324-varlink-invert-uid-check-to-reduce-call-of-getuid.patch +Patch0325: 0325-string-util-modernize-split_pair.patch +Patch0326: 0326-udev-split-manager_init-and-manager_main-into-small-.patch +Patch0327: 0327-udev-config-split-on_ctrl_msg-into-small-pieces.patch +Patch0328: 0328-udev-introduce-udev_property_name_is_valid-and-frien.patch +Patch0329: 0329-udev-ctrl-refuse-ENV-control-message-with-invalid-en.patch +Patch0330: 0330-varlink-add-comments-for-io.systemd.service-interfac.patch +Patch0331: 0331-sd-varlink-introduce-sd_varlink_get_current_method.patch +Patch0332: 0332-TEST-17-UDEV-wait-for-udevd-being-restarted-after-ex.patch +Patch0333: 0333-udev-make-worker-event-source-take-file-descriptor.patch +Patch0334: 0334-udev-dump-split-out-dump_event-from-udevadm-test.c.patch +Patch0335: 0335-udev-rules-introduce-OPTIONS-dump-token.patch +Patch0336: 0336-udev-control-move-setting-of-log-level-to-manager_ad.patch +Patch0337: 0337-udev-config-allow-to-enable-trace-logging-through-ke.patch +Patch0338: 0338-udev-dump-voidify-one-function-call.patch +Patch0339: 0339-udev-dump-also-show-written-sysfs-attributes-and-sys.patch +Patch0340: 0340-udevadm-test-allow-to-specify-extra-directories-to-l.patch +Patch0341: 0341-shell-completion-udevadm-add-net_driver.patch +Patch0342: 0342-udev-sort-builtins.patch +Patch0343: 0343-udev-rules-log-the-first-line-number-when-continued.patch +Patch0344: 0344-chase-introduce-flags-that-verify-that-chased-inode-.patch +Patch0345: 0345-udevadm-verify-chase-specified-paths.patch +Patch0346: 0346-bash-completion-udevadm-verify-suggest-found-udev-ru.patch +Patch0347: 0347-udevadm-introduce-cat-command.patch # Downstream-only patches (9000–9999) @@ -408,6 +467,7 @@ BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: clang BuildRequires: coreutils +BuildRequires: git-core BuildRequires: libcap-devel BuildRequires: libmount-devel BuildRequires: libfdisk-devel @@ -831,7 +891,7 @@ information (PSI) to monitor and take action on processes before an OOM occurs in kernel space. %prep -%autosetup -n %{?commit:%{name}-%{commit}}%{!?commit:%{name}-%{version_no_tilde}} -p1 +%autosetup -S git %build %global ntpvendor %(source /etc/os-release; echo ${ID}) @@ -1327,6 +1387,13 @@ rm -f .file-list-* rm -f %{name}.lang %changelog +* Fri Feb 14 2025 systemd maintenance team <systemd-maint@redhat.com> - 257-9 +- Add BuildRequires for git-core (RHEL-71409) + +* Fri Feb 14 2025 systemd maintenance team <systemd-maint@redhat.com> - 257-8 +- Rebase to new upstream stable release v257.3 (RHEL-71409) +- udev: introduce several features to make debugging rules easier (RHEL-75774) + * Mon Feb 10 2025 systemd maintenance team <systemd-maint@redhat.com> - 257-7 - Rebase to new upstream stable version v257.2+ (RHEL-71409)