Merge branch 'c10s' into a10s

This commit is contained in:
eabdullin 2025-02-04 13:58:13 +03:00
commit 3454cde087
31 changed files with 5223 additions and 61 deletions

View File

@ -1,58 +0,0 @@
From 2a6fbf9da93ad2f76aa5578641e39801a13fd5dd Mon Sep 17 00:00:00 2001
From: Tobias Klauser <tklauser@distanz.ch>
Date: Wed, 11 Dec 2024 15:10:39 +0100
Subject: [PATCH] profile.d: don't bail if $SHELL_* variables are unset
If - for whatever reason - a script uses set -u (nounset) and includes
/etc/profile.d/70-systemd-shell-extra.sh (e.g. transitively via
/etc/profile) the script would fail with:
/etc/profile.d/70-systemd-shell-extra.sh: line 15: SHELL_PROMPT_PREFIX: unbound variable
For example:
$ cat > foo.sh <<EOF
#!/bin/sh
set -u
source /etc/profile
EOF
$ chmod 700 foo.sh
$ ./foo.sh
/etc/profile.d/70-systemd-shell-extra.sh: line 15: SHELL_PROMPT_PREFIX: unbound variable
Fix this by using shell parameter substitution[^1] (which is a POSIX
shell concept) to set the $SHELL_* variables to the empty string if
undefined.
[^1]: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html
(cherry picked from commit 12e33d332b3f8754f4d5d0d21d5d3f0de8adc54c)
Related: RHEL-71409
---
profile.d/70-systemd-shell-extra.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/profile.d/70-systemd-shell-extra.sh b/profile.d/70-systemd-shell-extra.sh
index 70be3341b9..dae77e4bc7 100644
--- a/profile.d/70-systemd-shell-extra.sh
+++ b/profile.d/70-systemd-shell-extra.sh
@@ -12,14 +12,14 @@
# credentials shell.prompt.prefix, shell.prompt.suffix and shell.welcome, and
# are propagated into these environment variables by pam_systemd(8).
-if [ -n "$SHELL_PROMPT_PREFIX" ]; then
+if [ -n "${SHELL_PROMPT_PREFIX-}" ]; then
PS1="$SHELL_PROMPT_PREFIX$PS1"
fi
-if [ -n "$SHELL_PROMPT_SUFFIX" ]; then
+if [ -n "${SHELL_PROMPT_SUFFIX-}" ]; then
PS1="$PS1$SHELL_PROMPT_SUFFIX"
fi
-if [ -n "$SHELL_WELCOME" ]; then
+if [ -n "${SHELL_WELCOME-}" ]; then
printf '%b\n' "$SHELL_WELCOME"
fi

View File

@ -0,0 +1,25 @@
From 2c7a7aadc438ed266539e2ed705dfdf457a9e347 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
rhel-only: ci
Related: RHEL-57603
---
.github/workflows/deploy-man-pages.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/deploy-man-pages.yml b/.github/workflows/deploy-man-pages.yml
index 9739228a87..82fab81072 100644
--- a/.github/workflows/deploy-man-pages.yml
+++ b/.github/workflows/deploy-man-pages.yml
@@ -26,7 +26,7 @@ jobs:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
permissions:
pages: write

View File

@ -0,0 +1,78 @@
From 879603eda7440bf84a4094863283d556c8562907 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Thu, 9 Jan 2025 16:24:22 +0100
Subject: [PATCH] tree-wide: Fix python formatting
The new release of ruff formats a few more things which causes linter
failures in CI so let's fix those formatting nits.
(cherry picked from commit 96403d5121d93dd47dbe9dab5b90ff973e664ac3)
Related: RHEL-57603
---
src/ukify/ukify.py | 6 +++---
test/integration-test-wrapper.py | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index 3f36aa7af6..be4e30eb8e 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -763,7 +763,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) ->
cmd = [
measure_tool,
'calculate',
- *(f"--{s.name.removeprefix('.')}={s.content}" for s in to_measure.values()),
+ *(f'--{s.name.removeprefix(".")}={s.content}' for s in to_measure.values()),
*(f'--bank={bank}' for bank in banks),
# For measurement, the keys are not relevant, so we can lump all the phase paths
# into one call to systemd-measure calculate.
@@ -786,7 +786,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) ->
cmd = [
measure_tool,
'sign',
- *(f"--{s.name.removeprefix('.')}={s.content}" for s in to_measure.values()),
+ *(f'--{s.name.removeprefix(".")}={s.content}' for s in to_measure.values()),
*(f'--bank={bank}' for bank in banks),
]
@@ -1284,7 +1284,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}')
@contextlib.contextmanager
diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py
index ef6df8840f..eacfeffe9c 100755
--- a/test/integration-test-wrapper.py
+++ b/test/integration-test-wrapper.py
@@ -429,7 +429,7 @@ def main() -> None:
dropin += textwrap.dedent(
f"""
[Service]
- Environment=TEST_MATCH_SUBTEST={os.environ["TEST_MATCH_SUBTEST"]}
+ Environment=TEST_MATCH_SUBTEST={os.environ['TEST_MATCH_SUBTEST']}
"""
)
@@ -437,7 +437,7 @@ def main() -> None:
dropin += textwrap.dedent(
f"""
[Service]
- Environment=TEST_MATCH_TESTCASE={os.environ["TEST_MATCH_TESTCASE"]}
+ Environment=TEST_MATCH_TESTCASE={os.environ['TEST_MATCH_TESTCASE']}
"""
)
@@ -559,7 +559,7 @@ def main() -> None:
ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info']
- print("Test failed, relevant logs can be viewed with: \n\n" f"{(' && '.join(ops))}\n", file=sys.stderr)
+ print(f'Test failed, relevant logs can be viewed with: \n\n{(" && ".join(ops))}\n', file=sys.stderr)
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
exit(result.returncode or 1)

25
0146-ci-fix-Packit.patch Normal file
View File

@ -0,0 +1,25 @@
From 5588bd5336067976b13857b443b883b27fe8606e 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
rhel-only: ci
Related: RHEL-57603
---
.packit.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.packit.yml b/.packit.yml
index d16e630817..9d6e6c1e4e 100644
--- a/.packit.yml
+++ b/.packit.yml
@@ -7,6 +7,8 @@ files_to_sync:
- .packit.yml
- src: .packit_rpm/systemd.spec
dest: systemd.spec
+upstream_package_name: systemd
+downstream_package_name: systemd
# `git describe` returns in systemd's case 'v245-xxx' which breaks RPM version
# detection (that expects 245-xxxx'). Let's tweak the version string accordingly
upstream_tag_template: "v{version}"

View File

@ -0,0 +1,29 @@
From 956076a7fd7f02f10b28ef6de5c365f77fed4516 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
Test doesn't work on source-git repos, so let's drop it.
rhel-only: ci
Related: RHEL-57603
---
.packit.yml | 7 -------
1 file changed, 7 deletions(-)
diff --git a/.packit.yml b/.packit.yml
index 9d6e6c1e4e..a5d9aca0e1 100644
--- a/.packit.yml
+++ b/.packit.yml
@@ -48,10 +48,3 @@ jobs:
- centos-stream-10-ppc64le
- centos-stream-10-s390x
- centos-stream-10-x86_64
-
-- job: tests
- trigger: pull_request
- fmf_path: test/fmf
- tmt_plan: ci
- targets:
- - centos-stream-10-x86_64

View File

@ -0,0 +1,180 @@
From 24c7b86ce25b4bc1b55cbf0dffe4fa78925476b5 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
bus
If we unexpectly disconnect from the bus, systemd would end up dropping
the list of subscribers, which breaks the ability of clients like logind
to monitor the state of units.
Stash the list of subscribers into the deserialized state in the event
of a disconnect so that when we recover we can renew the broken
subscriptions.
(cherry picked from commit 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98)
Resolves: RHEL-73780
---
src/core/dbus.c | 21 +++++++++++++++------
src/core/dbus.h | 2 +-
src/core/manager.c | 8 ++++----
src/shared/bus-util.c | 22 ++++++++++++++++++++++
src/shared/bus-util.h | 1 +
5 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 3f0f40e702..9abc35888d 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -860,6 +860,8 @@ int bus_init_api(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to set up API bus: %m");
+ (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->deserialized_subscribed);
+ m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
m->api_bus = TAKE_PTR(bus);
return 0;
@@ -1004,8 +1006,17 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
}
/* Get rid of tracked clients on this bus */
- if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
+ if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus) {
+ _cleanup_strv_free_ char **subscribed = NULL;
+ int r;
+
+ r = bus_track_to_strv(m->subscribed, &subscribed);
+ if (r < 0)
+ log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
+ strv_free_and_replace(m->deserialized_subscribed, subscribed);
+
m->subscribed = sd_bus_track_unref(m->subscribed);
+ }
HASHMAP_FOREACH(j, m->jobs)
if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus)
@@ -1064,7 +1075,6 @@ void bus_done(Manager *m) {
assert(!m->subscribed);
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
m->polkit_registry = hashmap_free(m->polkit_registry);
}
@@ -1153,20 +1163,19 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
}
}
-int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) {
+int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l) {
int r;
- assert(m);
assert(t);
if (strv_isempty(l))
return 0;
- if (!m->api_bus)
+ if (!bus)
return 0;
if (!*t) {
- r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
+ r = sd_bus_track_new(bus, t, NULL, NULL);
if (r < 0)
return r;
}
diff --git a/src/core/dbus.h b/src/core/dbus.h
index d00c14d3b7..eb1baf6049 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -19,7 +19,7 @@ void bus_done(Manager *m);
int bus_fdset_add_all(Manager *m, FDSet *fds);
void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix);
-int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l);
+int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l);
int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata);
diff --git a/src/core/manager.c b/src/core/manager.c
index 485fdd1a66..068ea2ab03 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1803,6 +1803,9 @@ Manager* manager_free(Manager *m) {
free(m->switch_root);
free(m->switch_root_init);
+ sd_bus_track_unref(m->subscribed);
+ strv_free(m->deserialized_subscribed);
+
unit_defaults_done(&m->defaults);
FOREACH_ARRAY(map, m->units_needing_mounts_for, _UNIT_MOUNT_DEPENDENCY_TYPE_MAX) {
@@ -2139,7 +2142,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
manager_setup_bus(m);
/* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
- r = bus_track_coldplug(m, &m->subscribed, false, m->deserialized_subscribed);
+ r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->deserialized_subscribed);
if (r < 0)
log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
@@ -3813,9 +3816,6 @@ int manager_reload(Manager *m) {
/* Clean up runtime objects no longer referenced */
manager_vacuum(m);
- /* Clean up deserialized tracked clients */
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
-
/* Consider the reload process complete now. */
assert(m->n_reloading > 0);
m->n_reloading--;
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index ff80e580fc..2cdde97b78 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -698,6 +698,28 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) {
return r;
}
+int bus_track_to_strv(sd_bus_track *t, char ***ret) {
+ _cleanup_strv_free_ char **subscribed = NULL;
+ int r = 0;
+
+ assert(ret);
+
+ for (const char *n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) {
+ r = sd_bus_track_count_name(t, n);
+ if (r < 0)
+ return r;
+
+ for (int j = 0; j < r; j++) {
+ r = strv_extend(&subscribed, n);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ *ret = TAKE_PTR(subscribed);
+ return r;
+}
+
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description) {
_cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
const char *e;
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index fbccb24314..83522ad1c1 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -63,6 +63,7 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id,
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
int bus_track_add_name_many(sd_bus_track *t, char **l);
+int bus_track_to_strv(sd_bus_track *t, char ***ret);
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description);
static inline int bus_open_system_watch_bind(sd_bus **ret) {

View File

@ -0,0 +1,94 @@
From dedad9da3b54cbbe61086cac8cfe699feafeabd6 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
Now that this field may get populated at runtime, the deserialized name
is misleading. Change the name to reflect its updated purpose.
(cherry picked from commit e1315a621ae26473fcc9cd0d6013836f5f498d40)
Resolves: RHEL-73780
---
src/core/dbus.c | 6 +++---
src/core/manager-serialize.c | 2 +-
src/core/manager.c | 6 +++---
src/core/manager.h | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 9abc35888d..58cd1ee175 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -860,8 +860,8 @@ int bus_init_api(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to set up API bus: %m");
- (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->deserialized_subscribed);
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
+ (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->subscribed_as_strv);
+ m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
m->api_bus = TAKE_PTR(bus);
return 0;
@@ -1013,7 +1013,7 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
r = bus_track_to_strv(m->subscribed, &subscribed);
if (r < 0)
log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
- strv_free_and_replace(m->deserialized_subscribed, subscribed);
+ strv_free_and_replace(m->subscribed_as_strv, subscribed);
m->subscribed = sd_bus_track_unref(m->subscribed);
}
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
index 3f624619df..bc29ac91c6 100644
--- a/src/core/manager-serialize.c
+++ b/src/core/manager-serialize.c
@@ -493,7 +493,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
(void) exec_shared_runtime_deserialize_one(m, val, fds);
else if ((val = startswith(l, "subscribed="))) {
- r = strv_extend(&m->deserialized_subscribed, val);
+ r = strv_extend(&m->subscribed_as_strv, val);
if (r < 0)
return r;
} else if ((val = startswith(l, "varlink-server-socket-address="))) {
diff --git a/src/core/manager.c b/src/core/manager.c
index 068ea2ab03..4a7132274f 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1804,7 +1804,7 @@ Manager* manager_free(Manager *m) {
free(m->switch_root_init);
sd_bus_track_unref(m->subscribed);
- strv_free(m->deserialized_subscribed);
+ strv_free(m->subscribed_as_strv);
unit_defaults_done(&m->defaults);
@@ -2142,10 +2142,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
manager_setup_bus(m);
/* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
- r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->deserialized_subscribed);
+ r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->subscribed_as_strv);
if (r < 0)
log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
- m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
+ m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
r = manager_varlink_init(m);
if (r < 0)
diff --git a/src/core/manager.h b/src/core/manager.h
index e4cada80ff..7016eab2d3 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -340,7 +340,7 @@ struct Manager {
considered subscribes, since they last for very short only,
and it is much simpler that way. */
sd_bus_track *subscribed;
- char **deserialized_subscribed;
+ char **subscribed_as_strv;
/* This is used during reloading: before the reload we queue
* the reply message here, and afterwards we send it */

View File

@ -0,0 +1,197 @@
From 744459cb070eff2c30853bfd799f48878cea987a 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
bus-message-util
(cherry picked from commit ab33edb05b7d4c90fb80f46aa6b951c505048798)
Resolves: RHEL-73780
---
src/core/dbus-manager.c | 1 +
src/hostname/hostnamectl.c | 1 +
src/machine/machinectl.c | 1 +
src/machine/machined-dbus.c | 1 +
src/run/run.c | 1 +
src/shared/bus-map-properties.c | 1 +
src/shared/bus-message-util.c | 29 +++++++++++++++++++++++++++++
src/shared/bus-message-util.h | 2 ++
src/shared/bus-util.c | 28 ----------------------------
src/shared/bus-util.h | 2 --
10 files changed, 37 insertions(+), 30 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index c4a7e2a20b..8e39d67a00 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -11,6 +11,7 @@
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-log-control-api.h"
+#include "bus-message-util.h"
#include "bus-util.h"
#include "chase.h"
#include "confidential-virt.h"
diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
index cd4f86af80..2d1334f654 100644
--- a/src/hostname/hostnamectl.c
+++ b/src/hostname/hostnamectl.c
@@ -18,6 +18,7 @@
#include "bus-error.h"
#include "bus-locator.h"
#include "bus-map-properties.h"
+#include "bus-message-util.h"
#include "format-table.h"
#include "hostname-setup.h"
#include "hostname-util.h"
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 7843b9aa63..8854d9a550 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -21,6 +21,7 @@
#include "bus-error.h"
#include "bus-locator.h"
#include "bus-map-properties.h"
+#include "bus-message-util.h"
#include "bus-print-properties.h"
#include "bus-unit-procs.h"
#include "bus-unit-util.h"
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index f4915f67da..05e44b5030 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -10,6 +10,7 @@
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-locator.h"
+#include "bus-message-util.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
#include "discover-image.h"
diff --git a/src/run/run.c b/src/run/run.c
index 1b13e74b83..c4e79adc7a 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -15,6 +15,7 @@
#include "bus-error.h"
#include "bus-locator.h"
#include "bus-map-properties.h"
+#include "bus-message-util.h"
#include "bus-unit-util.h"
#include "bus-wait-for-jobs.h"
#include "calendarspec.h"
diff --git a/src/shared/bus-map-properties.c b/src/shared/bus-map-properties.c
index a6cd752894..18d83c336f 100644
--- a/src/shared/bus-map-properties.c
+++ b/src/shared/bus-map-properties.c
@@ -5,6 +5,7 @@
#include "bus-util.h"
#include "strv.h"
#include "bus-message.h"
+#include "bus-message-util.h"
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
sd_id128_t *p = userdata;
diff --git a/src/shared/bus-message-util.c b/src/shared/bus-message-util.c
index d8c483ef62..e93be9b3c5 100644
--- a/src/shared/bus-message-util.c
+++ b/src/shared/bus-message-util.c
@@ -7,6 +7,35 @@
#include "copy.h"
#include "resolve-util.h"
+int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret) {
+ const void *a;
+ size_t sz;
+ int r;
+
+ assert(m);
+
+ r = sd_bus_message_read_array(m, 'y', &a, &sz);
+ if (r < 0)
+ return r;
+
+ switch (sz) {
+
+ case 0:
+ if (ret)
+ *ret = SD_ID128_NULL;
+ return 0;
+
+ case sizeof(sd_id128_t):
+ if (ret)
+ memcpy(ret, a, sz);
+ return !memeqzero(a, sz); /* This mimics sd_id128_is_null(), but ret may be NULL,
+ * and a may be misaligned, so use memeqzero() here. */
+
+ default:
+ return -EINVAL;
+ }
+}
+
int bus_message_read_ifindex(sd_bus_message *message, sd_bus_error *error, int *ret) {
int ifindex, r;
diff --git a/src/shared/bus-message-util.h b/src/shared/bus-message-util.h
index 50025766c2..698960561c 100644
--- a/src/shared/bus-message-util.h
+++ b/src/shared/bus-message-util.h
@@ -6,6 +6,8 @@
#include "in-addr-util.h"
#include "socket-netlink.h"
+int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret);
+
int bus_message_read_ifindex(sd_bus_message *message, sd_bus_error *error, int *ret);
int bus_message_read_family(sd_bus_message *message, sd_bus_error *error, int *ret);
int bus_message_read_in_addr_auto(sd_bus_message *message, sd_bus_error *error, int *ret_family, union in_addr_union *ret_addr);
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 2cdde97b78..d3d3f1733e 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -953,34 +953,6 @@ int bus_query_sender_pidref(
return bus_creds_get_pidref(creds, ret);
}
-int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret) {
- const void *a;
- size_t sz;
- int r;
-
- assert(m);
-
- r = sd_bus_message_read_array(m, 'y', &a, &sz);
- if (r < 0)
- return r;
-
- switch (sz) {
- case 0:
- if (ret)
- *ret = SD_ID128_NULL;
- return 0;
-
- case sizeof(sd_id128_t):
- if (ret)
- memcpy(ret, a, sz);
- return !memeqzero(a, sz); /* This mimics sd_id128_is_null(), but ret may be NULL,
- * and a may be misaligned, so use memeqzero() here. */
-
- default:
- return -EINVAL;
- }
-}
-
static const char* const bus_transport_table[] = {
[BUS_TRANSPORT_LOCAL] = "local",
[BUS_TRANSPORT_REMOTE] = "remote",
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index 83522ad1c1..c2b9b126c8 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -84,6 +84,4 @@ int bus_property_get_string_set(sd_bus *bus, const char *path, const char *inter
int bus_creds_get_pidref(sd_bus_creds *c, PidRef *ret);
int bus_query_sender_pidref(sd_bus_message *m, PidRef *ret);
-int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret);
-
const char* bus_transport_to_string(BusTransport transport) _const_;

View File

@ -0,0 +1,157 @@
From 3a71e1dba1e5d56a3f0784df2ac53f5ad73a9451 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
bus-message-util
(cherry picked from commit e3d37628aabff92e4b756e63ef0a6cd4569ce743)
Resolves: RHEL-73780
---
src/home/homed-manager-bus.c | 9 +++++----
src/login/logind-brightness.c | 4 ++--
src/shared/bus-message-util.c | 4 ++++
src/shared/bus-message-util.h | 2 ++
src/shared/bus-util.c | 10 ----------
src/shared/bus-util.h | 2 --
src/systemctl/systemctl-list-units.c | 1 +
src/timedate/timedated.c | 1 +
8 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/src/home/homed-manager-bus.c b/src/home/homed-manager-bus.c
index 69c7680b9e..08c917aee2 100644
--- a/src/home/homed-manager-bus.c
+++ b/src/home/homed-manager-bus.c
@@ -4,6 +4,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
+#include "bus-message-util.h"
#include "bus-polkit.h"
#include "format-util.h"
#include "home-util.h"
@@ -704,17 +705,17 @@ static int method_rebalance(sd_bus_message *message, void *userdata, sd_bus_erro
int r;
r = manager_schedule_rebalance(m, /* immediately= */ true);
- if (r == 0)
- return sd_bus_reply_method_errorf(message, BUS_ERROR_REBALANCE_NOT_NEEDED, "No home directories need rebalancing.");
if (r < 0)
return r;
+ if (r == 0)
+ return sd_bus_reply_method_errorf(message, BUS_ERROR_REBALANCE_NOT_NEEDED, "No home directories need rebalancing.");
/* Keep a reference to this message, so that we can reply to it once we are done */
- r = set_ensure_put(&m->rebalance_queued_method_calls, &bus_message_hash_ops, message);
+ r = set_ensure_consume(&m->rebalance_queued_method_calls, &bus_message_hash_ops, sd_bus_message_ref(message));
if (r < 0)
return log_error_errno(r, "Failed to track rebalance bus message: %m");
+ assert(r > 0);
- sd_bus_message_ref(message);
return 1;
}
diff --git a/src/login/logind-brightness.c b/src/login/logind-brightness.c
index 40bcb39ce0..b3e7718394 100644
--- a/src/login/logind-brightness.c
+++ b/src/login/logind-brightness.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "bus-message-util.h"
#include "bus-util.h"
#include "device-util.h"
#include "hash-funcs.h"
@@ -173,10 +174,9 @@ static int set_add_message(Set **set, sd_bus_message *message) {
if (r <= 0)
return r;
- r = set_ensure_put(set, &bus_message_hash_ops, message);
+ r = set_ensure_consume(set, &bus_message_hash_ops, sd_bus_message_ref(message));
if (r <= 0)
return r;
- sd_bus_message_ref(message);
return 1;
}
diff --git a/src/shared/bus-message-util.c b/src/shared/bus-message-util.c
index e93be9b3c5..a6523ff00e 100644
--- a/src/shared/bus-message-util.c
+++ b/src/shared/bus-message-util.c
@@ -246,3 +246,7 @@ int bus_message_dump_fd(sd_bus_message *message) {
return 0;
}
+
+DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(bus_message_hash_ops,
+ void, trivial_hash_func, trivial_compare_func,
+ sd_bus_message, sd_bus_message_unref);
diff --git a/src/shared/bus-message-util.h b/src/shared/bus-message-util.h
index 698960561c..baec1cb92b 100644
--- a/src/shared/bus-message-util.h
+++ b/src/shared/bus-message-util.h
@@ -21,3 +21,5 @@ int bus_message_read_dns_servers(
int bus_message_dump_string(sd_bus_message *message);
int bus_message_dump_fd(sd_bus_message *message);
+
+extern const struct hash_ops bus_message_hash_ops;
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index d3d3f1733e..362dd78537 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -862,16 +862,6 @@ int bus_register_malloc_status(sd_bus *bus, const char *destination) {
return 0;
}
-static void bus_message_unref_wrapper(void *m) {
- sd_bus_message_unref(m);
-}
-
-const struct hash_ops bus_message_hash_ops = {
- .hash = trivial_hash_func,
- .compare = trivial_compare_func,
- .free_value = bus_message_unref_wrapper,
-};
-
int bus_message_append_string_set(sd_bus_message *m, Set *set) {
const char *s;
int r;
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index c2b9b126c8..a2193ebf97 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -75,8 +75,6 @@ int bus_reply_pair_array(sd_bus_message *m, char **l);
/* Listen to GetMallocInfo() calls to 'destination' and return malloc_info() via FD */
int bus_register_malloc_status(sd_bus *bus, const char *destination);
-extern const struct hash_ops bus_message_hash_ops;
-
int bus_message_append_string_set(sd_bus_message *m, Set *s);
int bus_property_get_string_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
diff --git a/src/systemctl/systemctl-list-units.c b/src/systemctl/systemctl-list-units.c
index a2f3074358..b7cb103513 100644
--- a/src/systemctl/systemctl-list-units.c
+++ b/src/systemctl/systemctl-list-units.c
@@ -5,6 +5,7 @@
#include "ansi-color.h"
#include "bus-error.h"
#include "bus-locator.h"
+#include "bus-message-util.h"
#include "format-table.h"
#include "locale-util.h"
#include "path-util.h"
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index c79bb864df..b196034a25 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -17,6 +17,7 @@
#include "bus-locator.h"
#include "bus-log-control-api.h"
#include "bus-map-properties.h"
+#include "bus-message-util.h"
#include "bus-polkit.h"
#include "bus-unit-util.h"
#include "clock-util.h"

View File

@ -0,0 +1,184 @@
From b1e0b30efe89592eff532a35b14345bc48b2afce 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
bus-message-util and bus-get-properties, respectively
(cherry picked from commit 91080bc9733b5b2478bfc0ed58f6a7ae5da7e639)
Resolves: RHEL-73780
---
src/core/dbus-cgroup.c | 1 +
src/shared/bus-get-properties.c | 19 +++++++++++++++++
src/shared/bus-get-properties.h | 2 ++
src/shared/bus-message-util.c | 19 +++++++++++++++++
src/shared/bus-message-util.h | 2 ++
src/shared/bus-util.c | 37 ---------------------------------
src/shared/bus-util.h | 4 ----
7 files changed, 43 insertions(+), 41 deletions(-)
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index fd48f3b07c..c99f1e29ac 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -7,6 +7,7 @@
#include "bpf-firewall.h"
#include "bpf-foreign.h"
#include "bus-get-properties.h"
+#include "bus-message-util.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "cgroup.h"
diff --git a/src/shared/bus-get-properties.c b/src/shared/bus-get-properties.c
index 53e5d6b99f..bf267a23a5 100644
--- a/src/shared/bus-get-properties.c
+++ b/src/shared/bus-get-properties.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "bus-get-properties.h"
+#include "bus-message-util.h"
#include "rlimit-util.h"
#include "stdio-util.h"
#include "string-util.h"
@@ -164,3 +165,21 @@ int bus_property_get_rlimit(
return sd_bus_message_append(reply, "t", u);
}
+
+int bus_property_get_string_set(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Set **s = ASSERT_PTR(userdata);
+
+ assert(bus);
+ assert(property);
+ assert(reply);
+
+ return bus_message_append_string_set(reply, *s);
+}
diff --git a/src/shared/bus-get-properties.h b/src/shared/bus-get-properties.h
index 4c35126502..9ddf5454de 100644
--- a/src/shared/bus-get-properties.h
+++ b/src/shared/bus-get-properties.h
@@ -52,6 +52,8 @@ assert_cc(sizeof(mode_t) == sizeof(uint32_t));
int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
+int bus_property_get_string_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
+
#define BUS_DEFINE_PROPERTY_GET_GLOBAL(function, bus_type, val) \
int function(sd_bus *bus, \
const char *path, \
diff --git a/src/shared/bus-message-util.c b/src/shared/bus-message-util.c
index a6523ff00e..8da112cacc 100644
--- a/src/shared/bus-message-util.c
+++ b/src/shared/bus-message-util.c
@@ -216,6 +216,25 @@ clear:
return r;
}
+int bus_message_append_string_set(sd_bus_message *m, const Set *set) {
+ int r;
+
+ assert(m);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return r;
+
+ const char *s;
+ SET_FOREACH(s, set) {
+ r = sd_bus_message_append(m, "s", s);
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_message_close_container(m);
+}
+
int bus_message_dump_string(sd_bus_message *message) {
const char *s;
int r;
diff --git a/src/shared/bus-message-util.h b/src/shared/bus-message-util.h
index baec1cb92b..d4a05f5b9c 100644
--- a/src/shared/bus-message-util.h
+++ b/src/shared/bus-message-util.h
@@ -19,6 +19,8 @@ int bus_message_read_dns_servers(
struct in_addr_full ***ret_dns,
size_t *ret_n_dns);
+int bus_message_append_string_set(sd_bus_message *m, const Set *s);
+
int bus_message_dump_string(sd_bus_message *message);
int bus_message_dump_fd(sd_bus_message *message);
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 362dd78537..bdce97790d 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -862,43 +862,6 @@ int bus_register_malloc_status(sd_bus *bus, const char *destination) {
return 0;
}
-int bus_message_append_string_set(sd_bus_message *m, Set *set) {
- const char *s;
- int r;
-
- assert(m);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return r;
-
- SET_FOREACH(s, set) {
- r = sd_bus_message_append(m, "s", s);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(m);
-}
-
-int bus_property_get_string_set(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Set **s = ASSERT_PTR(userdata);
-
- assert(bus);
- assert(property);
- assert(reply);
-
- return bus_message_append_string_set(reply, *s);
-}
-
int bus_creds_get_pidref(
sd_bus_creds *c,
PidRef *ret) {
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index a2193ebf97..e49ba66a10 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -75,10 +75,6 @@ int bus_reply_pair_array(sd_bus_message *m, char **l);
/* Listen to GetMallocInfo() calls to 'destination' and return malloc_info() via FD */
int bus_register_malloc_status(sd_bus *bus, const char *destination);
-int bus_message_append_string_set(sd_bus_message *m, Set *s);
-
-int bus_property_get_string_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-
int bus_creds_get_pidref(sd_bus_creds *c, PidRef *ret);
int bus_query_sender_pidref(sd_bus_message *m, PidRef *ret);

View File

@ -0,0 +1,68 @@
From 47224a5d1eae82421419fb9bcf2916ee1de041dd 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
(cherry picked from commit 3f03d39ca3b2f25f521342f2b0e49f60c51246e1)
Resolves: RHEL-73780
---
src/shared/serialize.c | 9 ++++++---
src/shared/serialize.h | 4 ++--
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/shared/serialize.c b/src/shared/serialize.c
index 735caf4978..58773e5ddd 100644
--- a/src/shared/serialize.c
+++ b/src/shared/serialize.c
@@ -164,11 +164,14 @@ int serialize_dual_timestamp(FILE *f, const char *name, const dual_timestamp *t)
return serialize_item_format(f, name, USEC_FMT " " USEC_FMT, t->realtime, t->monotonic);
}
-int serialize_strv(FILE *f, const char *key, char **l) {
+int serialize_strv(FILE *f, const char *key, char * const *l) {
int ret = 0, r;
/* Returns the first error, or positive if anything was serialized, 0 otherwise. */
+ assert(f);
+ assert(key);
+
STRV_FOREACH(i, l) {
r = serialize_item_escaped(f, key, *i);
if ((ret >= 0 && r < 0) ||
@@ -267,8 +270,7 @@ int serialize_item_base64mem(FILE *f, const char *key, const void *p, size_t l)
return 1;
}
-int serialize_string_set(FILE *f, const char *key, Set *s) {
- const char *e;
+int serialize_string_set(FILE *f, const char *key, const Set *s) {
int r;
assert(f);
@@ -279,6 +281,7 @@ int serialize_string_set(FILE *f, const char *key, Set *s) {
/* Serialize as individual items, as each element might contain separators and escapes */
+ const char *e;
SET_FOREACH(e, s) {
r = serialize_item(f, key, e);
if (r < 0)
diff --git a/src/shared/serialize.h b/src/shared/serialize.h
index 355eff9b8f..a1350533cf 100644
--- a/src/shared/serialize.h
+++ b/src/shared/serialize.h
@@ -21,10 +21,10 @@ int serialize_fd(FILE *f, FDSet *fds, const char *key, int fd);
int serialize_fd_many(FILE *f, FDSet *fds, const char *key, const int fd_array[], size_t n_fd_array);
int serialize_usec(FILE *f, const char *key, usec_t usec);
int serialize_dual_timestamp(FILE *f, const char *key, const dual_timestamp *t);
-int serialize_strv(FILE *f, const char *key, char **l);
+int serialize_strv(FILE *f, const char *key, char * const *l);
int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref);
int serialize_ratelimit(FILE *f, const char *key, const RateLimit *rl);
-int serialize_string_set(FILE *f, const char *key, Set *s);
+int serialize_string_set(FILE *f, const char *key, const Set *s);
int serialize_image_policy(FILE *f, const char *key, const ImagePolicy *p);
static inline int serialize_bool(FILE *f, const char *key, bool b) {

View File

@ -0,0 +1,70 @@
From 6eda0675d5a30080c6dd68c863707e22192b9e42 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()
(cherry picked from commit 38a2c2bf6a89def24007c0dac529c07da713abfb)
Resolves: RHEL-73780
---
src/core/unit-serialize.c | 3 +--
src/shared/serialize.c | 10 ++++++++++
src/shared/serialize.h | 3 +++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c
index 82102c0c32..2b5b472c47 100644
--- a/src/core/unit-serialize.c
+++ b/src/core/unit-serialize.c
@@ -117,8 +117,7 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
if (gid_is_valid(u->ref_gid))
(void) serialize_item_format(f, "ref-gid", GID_FMT, u->ref_gid);
- if (!sd_id128_is_null(u->invocation_id))
- (void) serialize_item_format(f, "invocation-id", SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id));
+ (void) serialize_id128(f, "invocation-id", u->invocation_id);
(void) serialize_item(f, "freezer-state", freezer_state_to_string(u->freezer_state));
diff --git a/src/shared/serialize.c b/src/shared/serialize.c
index 58773e5ddd..44148bea2c 100644
--- a/src/shared/serialize.c
+++ b/src/shared/serialize.c
@@ -182,6 +182,16 @@ int serialize_strv(FILE *f, const char *key, char * const *l) {
return ret;
}
+int serialize_id128(FILE *f, const char *key, sd_id128_t id) {
+ assert(f);
+ assert(key);
+
+ if (sd_id128_is_null(id))
+ return 0;
+
+ return serialize_item_format(f, key, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));
+}
+
int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref) {
int r;
diff --git a/src/shared/serialize.h b/src/shared/serialize.h
index a1350533cf..f2be84807a 100644
--- a/src/shared/serialize.h
+++ b/src/shared/serialize.h
@@ -3,6 +3,8 @@
#include <stdio.h>
+#include "sd-id128.h"
+
#include "fdset.h"
#include "image-policy.h"
#include "macro.h"
@@ -22,6 +24,7 @@ int serialize_fd_many(FILE *f, FDSet *fds, const char *key, const int fd_array[]
int serialize_usec(FILE *f, const char *key, usec_t usec);
int serialize_dual_timestamp(FILE *f, const char *key, const dual_timestamp *t);
int serialize_strv(FILE *f, const char *key, char * const *l);
+int serialize_id128(FILE *f, const char *key, sd_id128_t id);
int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref);
int serialize_ratelimit(FILE *f, const char *key, const RateLimit *rl);
int serialize_string_set(FILE *f, const char *key, const Set *s);

View File

@ -0,0 +1,55 @@
From 370d94580947ffbc2e3e1bee30564b98896d9d02 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
sd_bus_track_count_name()
Follow-up for 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98
While at it, turn the retval check for sd_bus_track_count_name()
into assertion, given we're working with already established tracks
(service_name_is_valid() should never yield false in this case).
Addresses https://github.com/systemd/systemd/pull/35406#discussion_r1912066774
(cherry picked from commit 33eeea4128f31df7ab4bd8866b582062d70114ae)
Resolves: RHEL-73780
---
src/shared/bus-util.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index bdce97790d..1fda013697 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -700,16 +700,15 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) {
int bus_track_to_strv(sd_bus_track *t, char ***ret) {
_cleanup_strv_free_ char **subscribed = NULL;
- int r = 0;
+ int r;
assert(ret);
for (const char *n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) {
- r = sd_bus_track_count_name(t, n);
- if (r < 0)
- return r;
+ int c = sd_bus_track_count_name(t, n);
+ assert(c >= 0);
- for (int j = 0; j < r; j++) {
+ for (int j = 0; j < c; j++) {
r = strv_extend(&subscribed, n);
if (r < 0)
return r;
@@ -717,7 +716,7 @@ int bus_track_to_strv(sd_bus_track *t, char ***ret) {
}
*ret = TAKE_PTR(subscribed);
- return r;
+ return 0;
}
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description) {

View File

@ -0,0 +1,36 @@
From 19b9d9140cbb9270119f807e8b7fe4047d5aae4a 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
(cherry picked from commit a7516260b32dd26fb61b1dd702b9bc718cd420f9)
Resolves: RHEL-73780
---
src/core/manager.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/core/manager.c b/src/core/manager.c
index 4a7132274f..96fc8941eb 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1816,15 +1816,16 @@ Manager* manager_free(Manager *m) {
hashmap_free(m->uid_refs);
hashmap_free(m->gid_refs);
- for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++)
- m->prefix[dt] = mfree(m->prefix[dt]);
+ FOREACH_ARRAY(i, m->prefix, _EXEC_DIRECTORY_TYPE_MAX)
+ free(*i);
+
free(m->received_credentials_directory);
free(m->received_encrypted_credentials_directory);
free(m->watchdog_pretimeout_governor);
free(m->watchdog_pretimeout_governor_overridden);
- m->fw_ctx = fw_ctx_free(m->fw_ctx);
+ fw_ctx_free(m->fw_ctx);
#if BPF_FRAMEWORK
bpf_restrict_fs_destroy(m->restrict_fs);

View File

@ -0,0 +1,32 @@
From 860690d1fb190600ec6c8db9052ec4c9fac0666f 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
bus_init_api() now does this internally
(after 8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98).
(cherry picked from commit af0e10354e567bfd0b9521376b2aad55f12a4e3d)
Resolves: RHEL-73780
---
src/core/manager.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/core/manager.c b/src/core/manager.c
index 96fc8941eb..38fe53c319 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2142,12 +2142,6 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
/* Connect to the bus if we are good for it */
manager_setup_bus(m);
- /* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
- r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->subscribed_as_strv);
- if (r < 0)
- log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
- m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
-
r = manager_varlink_init(m);
if (r < 0)
log_warning_errno(r, "Failed to set up Varlink, ignoring: %m");

View File

@ -0,0 +1,58 @@
From b5b61bf95b6d7d7ab1b01eb7e5195eb99b06635d 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()
(cherry picked from commit a9a8d2e12fe01b928135895f00c5bca465b7d13b)
Resolves: RHEL-73780
---
src/shared/bus-util.c | 23 +++++++++++++++++++++++
src/shared/bus-util.h | 2 ++
2 files changed, 25 insertions(+)
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 1fda013697..8eb3fbbf54 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -905,6 +905,29 @@ int bus_query_sender_pidref(
return bus_creds_get_pidref(creds, ret);
}
+int bus_get_instance_id(sd_bus *bus, sd_id128_t *ret) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ int r;
+
+ assert(bus);
+ assert(ret);
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId",
+ /* error = */ NULL, &reply,
+ NULL);
+ if (r < 0)
+ return r;
+
+ const char *id;
+
+ r = sd_bus_message_read_basic(reply, 's', &id);
+ if (r < 0)
+ return r;
+
+ return sd_id128_from_string(id, ret);
+}
+
static const char* const bus_transport_table[] = {
[BUS_TRANSPORT_LOCAL] = "local",
[BUS_TRANSPORT_REMOTE] = "remote",
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index e49ba66a10..fe85d815b8 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -78,4 +78,6 @@ int bus_register_malloc_status(sd_bus *bus, const char *destination);
int bus_creds_get_pidref(sd_bus_creds *c, PidRef *ret);
int bus_query_sender_pidref(sd_bus_message *m, PidRef *ret);
+int bus_get_instance_id(sd_bus *bus, sd_id128_t *ret);
+
const char* bus_transport_to_string(BusTransport transport) _const_;

View File

@ -0,0 +1,203 @@
From 1c3965954b88c0ac3811d29a186382633f336db7 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
bus tracks
(cherry picked from commit 1446e3c3921067e3a6228a3e172b5dfd95437136)
Resolves: RHEL-73780
---
src/core/dbus.c | 55 +++++++++++++++++++-----------------
src/core/dbus.h | 1 -
src/core/manager-serialize.c | 8 +++++-
src/core/manager.h | 11 +++++---
src/shared/bus-util.c | 2 +-
src/shared/bus-util.h | 2 +-
6 files changed, 45 insertions(+), 34 deletions(-)
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 58cd1ee175..a2a2611a03 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include "sd-bus.h"
+#include "sd-id128.h"
#include "alloc-util.h"
#include "bus-common-errors.h"
@@ -774,6 +775,24 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
return 0;
}
+static int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, char * const *l) {
+ int r;
+
+ assert(bus);
+ assert(t);
+
+ if (strv_isempty(l))
+ return 0;
+
+ if (!*t) {
+ r = sd_bus_track_new(bus, t, NULL, NULL);
+ if (r < 0)
+ return r;
+ }
+
+ return bus_track_add_name_many(*t, l);
+}
+
static int bus_setup_api(Manager *m, sd_bus *bus) {
char *name;
Unit *u;
@@ -860,10 +879,15 @@ int bus_init_api(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to set up API bus: %m");
- (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->subscribed_as_strv);
+ r = bus_get_instance_id(bus, &m->bus_id);
+ if (r < 0)
+ log_warning_errno(r, "Failed to query API bus instance ID, not deserializing subscriptions: %m");
+ else if (sd_id128_is_null(m->deserialized_bus_id) || sd_id128_equal(m->bus_id, m->deserialized_bus_id))
+ (void) bus_track_coldplug(bus, &m->subscribed, m->subscribed_as_strv);
m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
- m->api_bus = TAKE_PTR(bus);
+ m->deserialized_bus_id = SD_ID128_NULL;
+ m->api_bus = TAKE_PTR(bus);
return 0;
}
@@ -1015,6 +1039,9 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m");
strv_free_and_replace(m->subscribed_as_strv, subscribed);
+ m->deserialized_bus_id = m->bus_id;
+ m->bus_id = SD_ID128_NULL;
+
m->subscribed = sd_bus_track_unref(m->subscribed);
}
@@ -1163,30 +1190,6 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
}
}
-int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l) {
- int r;
-
- assert(t);
-
- if (strv_isempty(l))
- return 0;
-
- if (!bus)
- return 0;
-
- if (!*t) {
- r = sd_bus_track_new(bus, t, NULL, NULL);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_track_set_recursive(*t, recursive);
- if (r < 0)
- return r;
-
- return bus_track_add_name_many(*t, l);
-}
-
uint64_t manager_bus_n_queued_write(Manager *m) {
uint64_t c = 0;
sd_bus *b;
diff --git a/src/core/dbus.h b/src/core/dbus.h
index eb1baf6049..0f81102fc1 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -19,7 +19,6 @@ void bus_done(Manager *m);
int bus_fdset_add_all(Manager *m, FDSet *fds);
void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix);
-int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l);
int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata);
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
index bc29ac91c6..b225799ed9 100644
--- a/src/core/manager-serialize.c
+++ b/src/core/manager-serialize.c
@@ -158,6 +158,7 @@ int manager_serialize(
(void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit);
(void) serialize_ratelimit(f, "reload-reexec-ratelimit", &m->reload_reexec_ratelimit);
+ (void) serialize_id128(f, "bus-id", m->bus_id);
bus_track_serialize(m->subscribed, f, "subscribed");
r = dynamic_user_serialize(m, f, fds);
@@ -491,7 +492,12 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
manager_deserialize_gid_refs_one(m, val);
else if ((val = startswith(l, "exec-runtime=")))
(void) exec_shared_runtime_deserialize_one(m, val, fds);
- else if ((val = startswith(l, "subscribed="))) {
+ else if ((val = startswith(l, "bus-id="))) {
+
+ r = sd_id128_from_string(val, &m->deserialized_bus_id);
+ if (r < 0)
+ return r;
+ } else if ((val = startswith(l, "subscribed="))) {
r = strv_extend(&m->subscribed_as_strv, val);
if (r < 0)
diff --git a/src/core/manager.h b/src/core/manager.h
index 7016eab2d3..c5bd242968 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -335,13 +335,16 @@ struct Manager {
int private_listen_fd;
sd_event_source *private_listen_event_source;
- /* Contains all the clients that are subscribed to signals via
- the API bus. Note that private bus connections are always
- considered subscribes, since they last for very short only,
- and it is much simpler that way. */
+ /* Contains all the clients that are subscribed to signals via the API bus. Note that private bus
+ * connections are always considered subscribes, since they last for very short only, and it is
+ * much simpler that way. */
sd_bus_track *subscribed;
char **subscribed_as_strv;
+ /* The bus id of API bus acquired through org.freedesktop.DBus.GetId, which before deserializing
+ * subscriptions we'd use to verify the bus is still the same instance as before. */
+ sd_id128_t bus_id, deserialized_bus_id;
+
/* This is used during reloading: before the reload we queue
* the reply message here, and afterwards we send it */
sd_bus_message *pending_reload_message;
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 8eb3fbbf54..9255dbc9b6 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -686,7 +686,7 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send
return 1;
}
-int bus_track_add_name_many(sd_bus_track *t, char **l) {
+int bus_track_add_name_many(sd_bus_track *t, char * const *l) {
int r = 0;
assert(t);
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index fe85d815b8..024b54648d 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -62,7 +62,7 @@ int bus_log_connect_error(int r, BusTransport transport, RuntimeScope scope);
int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
-int bus_track_add_name_many(sd_bus_track *t, char **l);
+int bus_track_add_name_many(sd_bus_track *t, char * const *l);
int bus_track_to_strv(sd_bus_track *t, char ***ret);
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description);

View File

@ -0,0 +1,32 @@
From ce3d2da71072a3bb4d2ea49159cba8a671bcde90 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
manager_reload()
There's zero explanation why it got (spuriously) removed in
8402ca04d1a063c3d8a9e3d5c16df8bb8778ae98...
(cherry picked from commit 34f4b817f67b002eae7e2c09b19bf4b66c4791b6)
Resolves: RHEL-73780
---
src/core/manager.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/core/manager.c b/src/core/manager.c
index 38fe53c319..cd8cdd87a5 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -3805,6 +3805,11 @@ int manager_reload(Manager *m) {
(void) manager_setup_handoff_timestamp_fd(m);
(void) manager_setup_pidref_transport_fd(m);
+ /* Clean up deserialized bus track information. They're never consumed during reload (as opposed to
+ * reexec) since we do not disconnect from the bus. */
+ m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
+ m->deserialized_bus_id = SD_ID128_NULL;
+
/* Third, fire things up! */
manager_coldplug(m);

View File

@ -0,0 +1,40 @@
From 4ffeaa184cc33612e7229328a9272059f4d3ce34 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
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
```
In file included from ../src/shared/bus-get-properties.c:4:
../src/shared/bus-message-util.h:22:60: error: unknown type name Set
22 | int bus_message_append_string_set(sd_bus_message *m, const Set *s);
| ^~~
../src/shared/bus-get-properties.c: In function bus_property_get_string_set:
../src/shared/bus-get-properties.c:178:9: error: unknown type name Set
178 | Set **s = ASSERT_PTR(userdata);
| ^~~
```
follow-up to https://github.com/systemd/systemd/commit/91080bc9733b5b2478bfc0ed58f6a7ae5da7e639
(cherry picked from commit ca97d48bd425685d4ec20397812c3b1b006f5070)
Resolves: RHEL-73780
---
src/shared/bus-message-util.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/shared/bus-message-util.h b/src/shared/bus-message-util.h
index d4a05f5b9c..02c670695e 100644
--- a/src/shared/bus-message-util.h
+++ b/src/shared/bus-message-util.h
@@ -4,6 +4,7 @@
#include "sd-bus.h"
#include "in-addr-util.h"
+#include "set.h"
#include "socket-netlink.h"
int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret);

View File

@ -0,0 +1,27 @@
From 6368b96d9333723c70413511d87630df896ff48c 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
(cherry picked from commit 22ca9406c45bb07a02d28da13f6e3909071c9176)
Resolves: RHEL-75774
---
src/udev/udevadm-test.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 748bcaf364..34bc80ff4b 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -129,6 +129,10 @@ int test_main(int argc, char *argv[], void *userdata) {
device_seal(dev);
event = udev_event_new(dev, NULL, EVENT_UDEVADM_TEST);
+ if (!event) {
+ log_oom();
+ goto out;
+ }
assert_se(sigfillset(&mask) >= 0);
assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0);

View File

@ -0,0 +1,43 @@
From 69af60a47f87b85bc4f4bd82f61baa791c631138 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()'
(cherry picked from commit a75aeca78c3ad88dc9840f45963f86097d20cf6f)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 85ae1c2163..8d00702595 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -345,7 +345,7 @@ static void log_event_truncated(
/*** Other functions ***/
-static UdevRuleToken *udev_rule_token_free(UdevRuleToken *token) {
+static UdevRuleToken* udev_rule_token_free(UdevRuleToken *token) {
if (!token)
return NULL;
@@ -364,7 +364,7 @@ static void udev_rule_line_clear_tokens(UdevRuleLine *rule_line) {
udev_rule_token_free(i);
}
-static UdevRuleLine *udev_rule_line_free(UdevRuleLine *rule_line) {
+static UdevRuleLine* udev_rule_line_free(UdevRuleLine *rule_line) {
if (!rule_line)
return NULL;
@@ -379,7 +379,7 @@ static UdevRuleLine *udev_rule_line_free(UdevRuleLine *rule_line) {
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevRuleLine*, udev_rule_line_free);
-static UdevRuleFile *udev_rule_file_free(UdevRuleFile *rule_file) {
+static UdevRuleFile* udev_rule_file_free(UdevRuleFile *rule_file) {
if (!rule_file)
return NULL;

View File

@ -0,0 +1,42 @@
From be7684d1738dfd62415a5f1f05318a7a4caacd18 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
test mode
When udev rules are being tested, log level specified by SYSTEMD_LOG_LEVEL=
environment variable should be honored, and should not be overridden by
the rules.
(cherry picked from commit 0363a45898b304b6040cd20e132a3dd946faae50)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 8d00702595..60e1976c5a 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -2394,11 +2394,18 @@ static int udev_rule_apply_token_to_event(
if (level < 0)
level = event->default_log_level;
- log_set_max_level(level);
+ if (event->event_mode == EVENT_UDEV_WORKER)
+ log_set_max_level(level);
+ else {
+ _cleanup_free_ char *level_str = NULL;
+ (void) log_level_to_string_alloc(level, &level_str);
+ log_event_debug(dev, token, "Running in test mode, skipping changing maximum log level to %s.", strna(level_str));
+ }
if (level == LOG_DEBUG && !event->log_level_was_debug) {
/* The log level becomes LOG_DEBUG at first time. Let's log basic information. */
- log_device_uevent(dev, "The log level is changed to 'debug' while processing device");
+ if (event->event_mode == EVENT_UDEV_WORKER)
+ log_device_uevent(dev, "The log level is changed to 'debug' while processing device");
event->log_level_was_debug = true;
}

View File

@ -0,0 +1,209 @@
From e1941a839bc22c7a84b78a68537b03e4e0b995b3 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
log messages
Currently this does not show any extra log messages. In later commits,
more verbose log messages will be added.
(cherry picked from commit 8846df63fa30d2fb8749ed1753ddc397b1ff411e)
Resolves: RHEL-75774
---
man/udevadm.xml | 9 +++++++++
shell-completion/bash/udevadm | 13 +++++--------
shell-completion/zsh/_udevadm | 1 +
src/udev/udev-event.h | 1 +
src/udev/udevadm-test.c | 25 +++++++++++++++++++------
test/units/TEST-17-UDEV.10.sh | 1 +
6 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/man/udevadm.xml b/man/udevadm.xml
index eb77356d86..caa41bd204 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -869,6 +869,15 @@
<xi:include href="version-info.xml" xpointer="v209"/>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>Shows verbose logs in processing udev rules.</para>
+
+ <xi:include href="version-info.xml" xpointer="v258"/>
+ </listitem>
+ </varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
</variablelist>
diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm
index 3842d722e7..af3a0b9058 100644
--- a/shell-completion/bash/udevadm
+++ b/shell-completion/bash/udevadm
@@ -69,7 +69,8 @@ _udevadm() {
[CONTROL_ARG]='-l --log-priority -p --property -m --children-max -t --timeout'
[MONITOR_STANDALONE]='-k --kernel -u --udev -p --property'
[MONITOR_ARG]='-s --subsystem-match -t --tag-match'
- [TEST]='-a --action -N --resolve-names'
+ [TEST_STANDALONE]='-v --verbose'
+ [TEST_ARG]='-a --action -N --resolve-names'
[TEST_BUILTIN]='-a --action'
[VERIFY]='-N --resolve-names --root --no-summary --no-style'
[WAIT]='-t --timeout --initialized=no --removed --settle'
@@ -216,7 +217,7 @@ _udevadm() {
;;
'test')
- if __contains_word "$prev" ${OPTS[TEST]}; then
+ if __contains_word "$prev" ${OPTS[TEST_ARG]}; then
case $prev in
-a|--action)
comps=$( udevadm test --action help )
@@ -225,12 +226,8 @@ _udevadm() {
comps='early late never'
;;
esac
- COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
- return 0
- fi
-
- if [[ $cur = -* ]]; then
- comps="${OPTS[COMMON]} ${OPTS[TEST]}"
+ elif [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[TEST_ARG]} ${OPTS[TEST_STANDALONE]}"
else
comps=$( __get_all_devices )
local IFS=$'\n'
diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm
index 9ff87d8312..5c3d3c93ef 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.]' \
+ '(-v --verbose)'{-v,--verbose}'[Show verbose logs.]' \
'*::devpath:_files -P /sys/ -W /sys'
}
diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h
index 3dc89365bb..22388fe904 100644
--- a/src/udev/udev-event.h
+++ b/src/udev/udev-event.h
@@ -53,6 +53,7 @@ typedef struct UdevEvent {
bool name_final;
bool devlink_final;
bool run_final;
+ bool trace;
bool log_level_was_debug;
int default_log_level;
EventMode event_mode;
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 34bc80ff4b..199ee0c18d 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -33,6 +33,7 @@
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 bool arg_verbose = false;
static int help(void) {
@@ -41,7 +42,8 @@ static int help(void) {
" -h --help Show this help\n"
" -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",
+ " -N --resolve-names=early|late|never When to resolve names\n"
+ " -v --verbose Show verbose logs\n",
program_invocation_short_name);
return 0;
@@ -51,6 +53,7 @@ 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' },
{}
@@ -58,7 +61,7 @@ static int parse_argv(int argc, char *argv[]) {
int r, c;
- while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "a:N:vVh", options, NULL)) >= 0)
switch (c) {
case 'a':
r = parse_device_action(optarg, &arg_action);
@@ -73,6 +76,9 @@ 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 'v':
+ arg_verbose = true;
+ break;
case 'V':
return print_version();
case 'h':
@@ -104,20 +110,23 @@ int test_main(int argc, char *argv[], void *userdata) {
if (r <= 0)
return r;
- printf("This program is for debugging only, it does not run any program\n"
- "specified by a RUN key. It may show incorrect results, because\n"
- "some values may be different, or not available at a simulation run.\n"
- "\n");
+ puts("This program is for debugging only, it does not run any program\n"
+ "specified by a RUN key. It may show incorrect results, because\n"
+ "some values may be different, or not available at a simulation run.");
assert_se(sigprocmask(SIG_SETMASK, NULL, &sigmask_orig) >= 0);
+ puts("\nLoading builtins...");
udev_builtin_init();
+ puts("Loading builtins done.");
+ puts("\nLoading udev rules files...");
r = udev_rules_load(&rules, arg_resolve_name_timing);
if (r < 0) {
log_error_errno(r, "Failed to read udev rules: %m");
goto out;
}
+ puts("Loading udev rules files done.");
r = find_device_with_action(arg_syspath, arg_action, &dev);
if (r < 0) {
@@ -133,12 +142,16 @@ int test_main(int argc, char *argv[], void *userdata) {
log_oom();
goto out;
}
+ event->trace = arg_verbose;
assert_se(sigfillset(&mask) >= 0);
assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0);
+ printf("\nProcessing udev rules%s...\n", arg_verbose ? "" : " (verbose logs can be shown by -v/--verbose)");
udev_event_execute_rules(event, rules);
+ 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);
diff --git a/test/units/TEST-17-UDEV.10.sh b/test/units/TEST-17-UDEV.10.sh
index 7ca05f5287..6820e76679 100755
--- a/test/units/TEST-17-UDEV.10.sh
+++ b/test/units/TEST-17-UDEV.10.sh
@@ -130,6 +130,7 @@ udevadm test -N early /sys/class/net/$netdev
udevadm test -N late /sys/class/net/$netdev
udevadm test --resolve-names never /sys/class/net/$netdev
(! udevadm test -N hello /sys/class/net/$netdev)
+udevadm test -v /sys/class/net/$netdev
udevadm test -h
# udevadm test-builtin path_id "$loopdev"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,524 @@
From 11c7cc1bd95c80d8a92656aa432de4a9cadf69c2 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
This also drops redundant token string in log message on truncation.
No functional change, but should improve debuggability.
(cherry picked from commit a3ab06ab21528138160eb3d40c3e661fc53a8158)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 243 ++++++++++++++++++------------------------
1 file changed, 105 insertions(+), 138 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index c33d17aa47..3a61403338 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -297,6 +297,23 @@ static bool token_is_for_parents(UdevRuleToken *token) {
#define log_event_trace(event, ...) \
_log_event_trace(event, UNIQ_T(e, UNIQ), __VA_ARGS__)
+#define _log_event_truncated(event, token, token_u, what, format) \
+ ({ \
+ UdevRuleToken *token_u = ASSERT_PTR(token); \
+ \
+ token_u->type < _TK_M_MAX ? \
+ log_event_debug(event, token_u, \
+ "The %s is truncated while substituting into \"%s\", assuming the token fails.", \
+ what, (const char*) format) : \
+ log_event_warning( \
+ event, token_u, \
+ "The %s is truncated while substituting into \"%s\", refusing to apply the token.", \
+ what, (const char*) format); \
+ })
+
+#define log_event_truncated(event, token, what, format) \
+ _log_event_truncated(event, token, UNIQ_T(t, UNIQ), what, format)
+
/* Mainly used when parsing .rules files. */
#define log_file_full_errno_zerook(...) \
log_udev_rule_file_full(NULL, __VA_ARGS__)
@@ -351,26 +368,6 @@ static void log_unknown_owner(sd_device *dev, UdevRuleLine *line, int error, con
log_udev_rule_line_full(dev, line, LOG_ERR, error, "Failed to resolve %s '%s', ignoring: %m", entity, name);
}
-static void log_event_truncated(
- UdevEvent *event,
- UdevRuleToken *token,
- const char *what,
- const char *format,
- const char *key,
- bool is_match) {
-
- if (is_match)
- log_event_debug(event, token,
- "The %s is truncated while substituting into '%s', "
- "assuming the %s key does not match.",
- what, format, key);
- else
- log_event_warning(event, token,
- "The %s is truncated while substituting into '%s', "
- "refusing to apply the %s key.",
- what, format, key);
-}
-
/*** Other functions ***/
static UdevRuleToken* udev_rule_token_free(UdevRuleToken *token) {
@@ -1776,6 +1773,54 @@ bool udev_rules_should_reload(UdevRules *rules) {
return false;
}
+static bool apply_format_full(
+ UdevEvent *event,
+ UdevRuleToken *token,
+ const char *format,
+ char *result,
+ size_t result_size,
+ bool replace_whitespace,
+ const char *what) {
+
+ assert(event);
+ assert(token);
+ assert(format);
+ assert(result);
+ assert(what);
+
+ bool truncated = false;
+ (void) udev_event_apply_format(event, format, result, result_size, replace_whitespace, &truncated);
+ if (truncated) {
+ log_event_truncated(event, token, what, format);
+ return false;
+ }
+
+ if (event->trace && !streq(format, result))
+ log_event_trace(event, token, "Format substitution: \"%s\" -> \"%s\"", format, result);
+
+ return true;
+}
+
+static bool apply_format_value(
+ UdevEvent *event,
+ UdevRuleToken *token,
+ char *result,
+ size_t result_size,
+ const char *what) {
+
+ return apply_format_full(event, token, token->value, result, result_size, /* replace_whitespace = */ false, what);
+}
+
+static bool apply_format_attr(
+ UdevEvent *event,
+ UdevRuleToken *token,
+ char *result,
+ size_t result_size,
+ const char *what) {
+
+ return apply_format_full(event, token, token->data, result, result_size, /* replace_whitespace = */ false, what);
+}
+
static bool token_match_string(UdevRuleToken *token, const char *str) {
const char *value;
bool match = false, case_insensitive;
@@ -1834,7 +1879,6 @@ static bool token_match_string(UdevRuleToken *token, const char *str) {
static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *event) {
char nbuf[UDEV_NAME_SIZE], vbuf[UDEV_NAME_SIZE];
const char *name, *value;
- bool truncated;
assert(token);
assert(IN_SET(token->type, TK_M_ATTR, TK_M_PARENTS_ATTR));
@@ -1845,12 +1889,8 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev
switch (token->attr_subst_type) {
case SUBST_TYPE_FORMAT:
- (void) udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "sysfs attribute name", name,
- token->type == TK_M_ATTR ? "ATTR" : "ATTRS", /* is_match = */ true);
+ if (!apply_format_attr(event, token, nbuf, sizeof(nbuf), "sysfs attribute name"))
return false;
- }
name = nbuf;
_fallthrough_;
@@ -2118,13 +2158,9 @@ static int udev_rule_apply_token_to_event(
case TK_M_SYSCTL: {
_cleanup_free_ char *value = NULL;
char buf[UDEV_PATH_SIZE];
- bool truncated;
- (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "sysctl entry name", token->data, "SYSCTL", /* is_match = */ true);
+ if (!apply_format_attr(event, token, buf, sizeof(buf), "sysctl entry name"))
return false;
- }
r = sysctl_read(sysctl_normalize(buf), &value);
if (r < 0 && r != -ENOENT)
@@ -2136,13 +2172,10 @@ static int udev_rule_apply_token_to_event(
mode_t mode = PTR_TO_MODE(token->data);
char buf[UDEV_PATH_SIZE];
struct stat statbuf;
- bool match, truncated;
+ bool match;
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "file name", token->value, "TEST", /* is_match = */ true);
+ if (!apply_format_value(event, token, buf, sizeof(buf), "file name"))
return false;
- }
if (!path_is_absolute(buf) &&
udev_resolve_subsys_kernel(buf, buf, sizeof(buf), false) < 0) {
@@ -2153,6 +2186,7 @@ static int udev_rule_apply_token_to_event(
if (r < 0)
return log_event_error_errno(event, token, r, "Failed to get syspath: %m");
+ bool truncated;
strscpy_full(tmp, sizeof(tmp), buf, &truncated);
assert(!truncated);
strscpyl_full(buf, sizeof(buf), &truncated, val, "/", tmp, NULL);
@@ -2177,15 +2211,12 @@ static int udev_rule_apply_token_to_event(
}
case TK_M_PROGRAM: {
char buf[UDEV_LINE_SIZE], result[UDEV_LINE_SIZE];
- bool truncated;
size_t count;
event->program_result = mfree(event->program_result);
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "command", token->value, "PROGRAM", /* is_match = */ true);
+
+ if (!apply_format_value(event, token, buf, sizeof(buf), "command"))
return false;
- }
log_event_debug(event, token, "Running PROGRAM=\"%s\"", buf);
@@ -2211,13 +2242,9 @@ static int udev_rule_apply_token_to_event(
case TK_M_IMPORT_FILE: {
_cleanup_fclose_ FILE *f = NULL;
char buf[UDEV_PATH_SIZE];
- bool truncated;
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "file name to be imported", token->value, "IMPORT", /* is_match = */ true);
+ if (!apply_format_value(event, token, buf, sizeof(buf), "file name to be imported"))
return false;
- }
log_event_debug(event, token, "Importing properties from '%s'", buf);
@@ -2264,11 +2291,8 @@ static int udev_rule_apply_token_to_event(
char buf[UDEV_LINE_SIZE], result[UDEV_LINE_SIZE];
bool truncated;
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "command", token->value, "IMPORT", /* is_match = */ true);
+ if (!apply_format_value(event, token, buf, sizeof(buf), "command"))
return false;
- }
log_event_debug(event, token, "Importing properties from results of '%s'", buf);
@@ -2329,7 +2353,6 @@ static int udev_rule_apply_token_to_event(
assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
unsigned mask = 1U << (int) cmd;
char buf[UDEV_LINE_SIZE];
- bool truncated;
if (udev_builtin_run_once(cmd)) {
/* check if we ran already */
@@ -2343,11 +2366,8 @@ static int udev_rule_apply_token_to_event(
event->builtin_run |= mask;
}
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "builtin command", token->value, "IMPORT", /* is_match = */ true);
+ if (!apply_format_value(event, token, buf, sizeof(buf), "builtin command"))
return false;
- }
log_event_debug(event, token, "Importing properties from results of builtin command '%s'", buf);
@@ -2397,13 +2417,9 @@ static int udev_rule_apply_token_to_event(
}
case TK_M_IMPORT_PARENT: {
char buf[UDEV_PATH_SIZE];
- bool truncated;
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "property name", token->value, "IMPORT", /* is_match = */ true);
+ if (!apply_format_value(event, token, buf, sizeof(buf), "property name"))
return false;
- }
r = import_parent_into_properties(dev, buf);
if (r < 0)
@@ -2460,18 +2476,14 @@ static int udev_rule_apply_token_to_event(
case TK_A_OWNER: {
char owner[UDEV_NAME_SIZE];
const char *ow = owner;
- bool truncated;
if (event->owner_final)
break;
if (token->op == OP_ASSIGN_FINAL)
event->owner_final = true;
- (void) udev_event_apply_format(event, token->value, owner, sizeof(owner), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "user name", token->value, "OWNER", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, owner, sizeof(owner), "user name"))
+ return true;
r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0)
@@ -2483,18 +2495,14 @@ static int udev_rule_apply_token_to_event(
case TK_A_GROUP: {
char group[UDEV_NAME_SIZE];
const char *gr = group;
- bool truncated;
if (event->group_final)
break;
if (token->op == OP_ASSIGN_FINAL)
event->group_final = true;
- (void) udev_event_apply_format(event, token->value, group, sizeof(group), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "group name", token->value, "GROUP", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, group, sizeof(group), "group name"))
+ return true;
r = get_group_creds(&gr, &event->gid, USER_CREDS_ALLOW_MISSING);
if (r < 0)
@@ -2505,18 +2513,14 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_MODE: {
char mode_str[UDEV_NAME_SIZE];
- bool truncated;
if (event->mode_final)
break;
if (token->op == OP_ASSIGN_FINAL)
event->mode_final = true;
- (void) udev_event_apply_format(event, token->value, mode_str, sizeof(mode_str), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "mode", token->value, "MODE", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, mode_str, sizeof(mode_str), "mode"))
+ return true;
r = parse_mode(mode_str, &event->mode);
if (r < 0)
@@ -2558,17 +2562,13 @@ static int udev_rule_apply_token_to_event(
case TK_A_SECLABEL: {
_cleanup_free_ char *name = NULL, *label = NULL;
char label_str[UDEV_LINE_SIZE] = {};
- bool truncated;
name = strdup(token->data);
if (!name)
return log_oom();
- (void) udev_event_apply_format(event, token->value, label_str, sizeof(label_str), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "security label", token->value, "SECLABEL", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, label_str, sizeof(label_str), "security label"))
+ return true;
if (!isempty(label_str))
label = strdup(label_str);
@@ -2596,7 +2596,6 @@ static int udev_rule_apply_token_to_event(
const char *val, *name = token->data;
char value_new[UDEV_NAME_SIZE], *p = value_new;
size_t count, l = sizeof(value_new);
- bool truncated;
if (isempty(token->value)) {
if (token->op == OP_ADD)
@@ -2609,6 +2608,7 @@ static int udev_rule_apply_token_to_event(
if (token->op == OP_ADD &&
device_get_property_value_with_fallback(dev, name, event->worker ? event->worker->properties : NULL, &val) >= 0) {
+ bool truncated;
l = strpcpyl_full(&p, l, &truncated, val, " ", NULL);
if (truncated) {
log_event_warning(event, token,
@@ -2618,13 +2618,8 @@ static int udev_rule_apply_token_to_event(
}
}
- (void) udev_event_apply_format(event, token->value, p, l, false, &truncated);
- if (truncated) {
- _cleanup_free_ char *key_with_name = strjoin("ENV{", name, "}");
- log_event_truncated(event, token, "property value", token->value,
- key_with_name ?: "ENV", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, p, l, "property value"))
+ return true;
if (event->esc == ESCAPE_REPLACE) {
count = udev_replace_chars(p, NULL);
@@ -2641,13 +2636,9 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_TAG: {
char buf[UDEV_PATH_SIZE];
- bool truncated;
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "tag name", token->value, "TAG", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, buf, sizeof(buf), "tag name"))
+ return true;
if (token->op == OP_ASSIGN)
device_cleanup_tags(dev);
@@ -2665,7 +2656,6 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_NAME: {
char buf[UDEV_PATH_SIZE];
- bool truncated;
size_t count;
if (event->name_final)
@@ -2680,11 +2670,8 @@ static int udev_rule_apply_token_to_event(
break;
}
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "network interface name", token->value, "NAME", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, buf, sizeof(buf), "network interface name"))
+ return true;
if (IN_SET(event->esc, ESCAPE_UNSET, ESCAPE_REPLACE)) {
if (naming_scheme_has(NAMING_REPLACE_STRICTLY))
@@ -2705,7 +2692,6 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_DEVLINK: {
char buf[UDEV_PATH_SIZE];
- bool truncated;
size_t count;
if (event->devlink_final)
@@ -2717,12 +2703,10 @@ static int udev_rule_apply_token_to_event(
if (IN_SET(token->op, OP_ASSIGN, OP_ASSIGN_FINAL))
device_cleanup_devlinks(dev);
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf),
- /* replace_whitespace = */ event->esc != ESCAPE_NONE, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "symbolic link path", token->value, "SYMLINK", /* is_match = */ false);
- break;
- }
+ if (!apply_format_full(event, token, token->value, buf, sizeof(buf),
+ /* replace_whitespace = */ event->esc != ESCAPE_NONE,
+ "symbolic link path"))
+ return true;
/* By default or string_escape=none, allow multiple symlinks separated by spaces. */
if (event->esc == ESCAPE_UNSET)
@@ -2772,10 +2756,10 @@ static int udev_rule_apply_token_to_event(
case TK_A_ATTR: {
char buf[UDEV_PATH_SIZE], value[UDEV_NAME_SIZE];
const char *val, *key_name = token->data;
- bool truncated;
if (udev_resolve_subsys_kernel(key_name, buf, sizeof(buf), false) < 0 &&
sd_device_get_syspath(dev, &val) >= 0) {
+ bool truncated;
strscpyl_full(buf, sizeof(buf), &truncated, val, "/", key_name, NULL);
if (truncated) {
log_event_warning(event, token,
@@ -2790,11 +2774,9 @@ static int udev_rule_apply_token_to_event(
log_event_error_errno(event, token, r, "Could not find file matches '%s', ignoring: %m", buf);
break;
}
- (void) udev_event_apply_format(event, token->value, value, sizeof(value), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "attribute value", token->value, "ATTR", /* is_match = */ false);
- break;
- }
+
+ if (!apply_format_value(event, token, value, sizeof(value), "attribute value"))
+ return true;
if (EVENT_MODE_DESTRUCTIVE(event)) {
log_event_debug(event, token, "Writing ATTR{'%s'}=\"%s\".", buf, value);
@@ -2812,21 +2794,12 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_SYSCTL: {
char buf[UDEV_PATH_SIZE], value[UDEV_NAME_SIZE];
- bool truncated;
- (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "sysctl entry name", token->data, "SYSCTL", /* is_match = */ false);
- break;
- }
+ if (!apply_format_attr(event, token, buf, sizeof(buf), "sysctl entry name"))
+ return true;
- (void) udev_event_apply_format(event, token->value, value, sizeof(value), false, &truncated);
- if (truncated) {
- _cleanup_free_ char *key_with_name = strjoin("SYSCTL{", buf, "}");
- log_event_truncated(event, token, "sysctl value", token->value,
- key_with_name ?: "SYSCTL", /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, value, sizeof(value), "sysctl value"))
+ return true;
sysctl_normalize(buf);
@@ -2844,7 +2817,6 @@ static int udev_rule_apply_token_to_event(
case TK_A_RUN_PROGRAM: {
_cleanup_free_ char *cmd = NULL;
char buf[UDEV_LINE_SIZE];
- bool truncated;
if (event->run_final)
break;
@@ -2854,13 +2826,8 @@ static int udev_rule_apply_token_to_event(
if (IN_SET(token->op, OP_ASSIGN, OP_ASSIGN_FINAL))
ordered_hashmap_clear_free_key(event->run_list);
- (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated);
- if (truncated) {
- log_event_truncated(event, token, "command", token->value,
- token->type == TK_A_RUN_BUILTIN ? "RUN{builtin}" : "RUN{program}",
- /* is_match = */ false);
- break;
- }
+ if (!apply_format_value(event, token, buf, sizeof(buf), "command"))
+ return true;
cmd = strdup(buf);
if (!cmd)

View File

@ -0,0 +1,205 @@
From 49cc87a059b24a6c81e954425599a7253c05beb4 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
(cherry picked from commit 0febeccfdc4839ace732280f06005e81f5cadff7)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 81 ++++++++++++++++++++++++++++++++++---------
1 file changed, 65 insertions(+), 16 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 3a61403338..35a3a9cc69 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -1821,10 +1821,11 @@ static bool apply_format_attr(
return apply_format_full(event, token, token->data, result, result_size, /* replace_whitespace = */ false, what);
}
-static bool token_match_string(UdevRuleToken *token, const char *str) {
+static bool token_match_string(UdevEvent *event, UdevRuleToken *token, const char *str, bool log_result) {
const char *value;
bool match = false, case_insensitive;
+ assert(event);
assert(token);
assert(token->value);
assert(token->type < _TK_M_MAX);
@@ -1873,7 +1874,51 @@ static bool token_match_string(UdevRuleToken *token, const char *str) {
assert_not_reached();
}
- return token->op == (match ? OP_MATCH : OP_NOMATCH);
+ bool result = token->op == (match ? OP_MATCH : OP_NOMATCH);
+
+ if (event->trace)
+ switch (token->match_type & _MATCH_TYPE_MASK) {
+ case MATCH_TYPE_EMPTY:
+ log_event_trace(event, token, "String \"%s\" is%s empty%s",
+ strempty(str), match ? "" : " not",
+ log_result ? result ? ": PASS" : ": FAIL" : ".");
+ break;
+ case MATCH_TYPE_SUBSYSTEM:
+ log_event_trace(event, token,
+ "String \"%s\" matches %s of \"subsystem\", \"class\", or \"bus\"%s",
+ strempty(str), match ? "one" : "neither",
+ log_result ? result ? ": PASS" : ": FAIL" : ".");
+ break;
+ case MATCH_TYPE_PLAIN_WITH_EMPTY:
+ case MATCH_TYPE_PLAIN:
+ case MATCH_TYPE_GLOB_WITH_EMPTY:
+ case MATCH_TYPE_GLOB: {
+ _cleanup_free_ char *joined = NULL;
+ unsigned c = 0;
+
+ if (IN_SET(token->match_type & _MATCH_TYPE_MASK, MATCH_TYPE_PLAIN_WITH_EMPTY, MATCH_TYPE_GLOB_WITH_EMPTY)) {
+ (void) strextend_with_separator(&joined, ", ", "\"\"");
+ c++;
+ }
+
+ NULSTR_FOREACH(i, value) {
+ (void) strextendf_with_separator(&joined, ", ", "\"%s\"", i);
+ c++;
+ }
+
+ assert(c > 0);
+ log_event_trace(event, token, "String \"%s\" %s %s%s",
+ strempty(str),
+ match ? (c > 1 ? "matches one of" : "matches") : (c > 1 ? "matches neither of" : "does not match"),
+ strempty(joined),
+ log_result ? result ? ": PASS" : ": FAIL" : ".");
+ break;
+ }
+ default:
+ assert_not_reached();
+ }
+
+ return result;
}
static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *event) {
@@ -1904,7 +1949,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev
value = delete_trailing_chars(vbuf, NULL);
}
- return token_match_string(token, value);
+ return token_match_string(event, token, value, /* log_result = */ true);
case SUBST_TYPE_SUBSYS:
if (udev_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) < 0)
@@ -1914,7 +1959,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev
if (FLAGS_SET(token->match_type, MATCH_REMOVE_TRAILING_WHITESPACE))
delete_trailing_chars(vbuf, NULL);
- return token_match_string(token, vbuf);
+ return token_match_string(event, token, vbuf, /* log_result = */ true);
default:
assert_not_reached();
@@ -2074,7 +2119,7 @@ static int udev_rule_apply_token_to_event(
if (r < 0)
return log_event_error_errno(event, token, r, "Failed to get uevent action type: %m");
- return token_match_string(token, device_action_to_string(a));
+ return token_match_string(event, token, device_action_to_string(a), /* log_result = */ true);
}
case TK_M_DEVPATH: {
const char *val;
@@ -2083,7 +2128,7 @@ static int udev_rule_apply_token_to_event(
if (r < 0)
return log_event_error_errno(event, token, r, "Failed to get devpath: %m");
- return token_match_string(token, val);
+ return token_match_string(event, token, val, /* log_result = */ true);
}
case TK_M_KERNEL:
case TK_M_PARENTS_KERNEL: {
@@ -2093,21 +2138,23 @@ static int udev_rule_apply_token_to_event(
if (r < 0)
return log_event_error_errno(event, token, r, "Failed to get sysname: %m");
- return token_match_string(token, val);
+ return token_match_string(event, token, val, /* log_result = */ true);
}
case TK_M_DEVLINK:
FOREACH_DEVICE_DEVLINK(dev, val)
- if (token_match_string(token, strempty(startswith(val, "/dev/"))) == (token->op == OP_MATCH))
+ if (token_match_string(event, token, strempty(startswith(val, "/dev/")), /* log_result = */ false) == (token->op == OP_MATCH))
return token->op == OP_MATCH;
return token->op == OP_NOMATCH;
+
case TK_M_NAME:
- return token_match_string(token, event->name);
+ return token_match_string(event, token, event->name, /* log_result = */ true);
+
case TK_M_ENV: {
const char *val = NULL;
(void) device_get_property_value_with_fallback(dev, token->data, event->worker ? event->worker->properties : NULL, &val);
- return token_match_string(token, val);
+ return token_match_string(event, token, val, /* log_result = */ true);
}
case TK_M_CONST: {
const char *val, *k = token->data;
@@ -2120,14 +2167,15 @@ static int udev_rule_apply_token_to_event(
val = confidential_virtualization_to_string(detect_confidential_virtualization());
else
assert_not_reached();
- return token_match_string(token, val);
+ return token_match_string(event, token, val, /* log_result = */ true);
}
case TK_M_TAG:
case TK_M_PARENTS_TAG:
FOREACH_DEVICE_CURRENT_TAG(dev, val)
- if (token_match_string(token, val) == (token->op == OP_MATCH))
+ if (token_match_string(event, token, val, /* log_result = */ false) == (token->op == OP_MATCH))
return token->op == OP_MATCH;
return token->op == OP_NOMATCH;
+
case TK_M_SUBSYSTEM:
case TK_M_PARENTS_SUBSYSTEM: {
const char *val;
@@ -2138,7 +2186,7 @@ static int udev_rule_apply_token_to_event(
else if (r < 0)
return log_event_error_errno(event, token, r, "Failed to get subsystem: %m");
- return token_match_string(token, val);
+ return token_match_string(event, token, val, /* log_result = */ true);
}
case TK_M_DRIVER:
case TK_M_PARENTS_DRIVER: {
@@ -2150,11 +2198,12 @@ static int udev_rule_apply_token_to_event(
else if (r < 0)
return log_event_error_errno(event, token, r, "Failed to get driver: %m");
- return token_match_string(token, val);
+ return token_match_string(event, token, val, /* log_result = */ true);
}
case TK_M_ATTR:
case TK_M_PARENTS_ATTR:
return token_match_attr(token, dev, event);
+
case TK_M_SYSCTL: {
_cleanup_free_ char *value = NULL;
char buf[UDEV_PATH_SIZE];
@@ -2166,7 +2215,7 @@ static int udev_rule_apply_token_to_event(
if (r < 0 && r != -ENOENT)
return log_event_error_errno(event, token, r, "Failed to read sysctl '%s': %m", buf);
- return token_match_string(token, strstrip(value));
+ return token_match_string(event, token, strstrip(value), /* log_result = */ true);
}
case TK_M_TEST: {
mode_t mode = PTR_TO_MODE(token->data);
@@ -2429,7 +2478,7 @@ static int udev_rule_apply_token_to_event(
return token->op == (r > 0 ? OP_MATCH : OP_NOMATCH);
}
case TK_M_RESULT:
- return token_match_string(token, event->program_result);
+ return token_match_string(event, token, event->program_result, /* log_result = */ true);
case TK_A_OPTIONS_STRING_ESCAPE_NONE:
event->esc = ESCAPE_NONE;
break;

View File

@ -0,0 +1,163 @@
From 4106dbe04d90031197b4317b7c8ae36e2fb76984 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()
And logs about replacement only when trace logging is enabled.
(cherry picked from commit a79cd8c2be447367dc2d70615dc9e3e0c91d5cf4)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 74 +++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 35 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 35a3a9cc69..53370f6085 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -2079,7 +2079,7 @@ static int attr_subst_subdir(char attr[static UDEV_PATH_SIZE]) {
return -ENOENT;
}
-static size_t udev_replace_ifname(char *str) {
+static size_t udev_replace_ifname_strict(char *str) {
size_t replaced = 0;
assert(str);
@@ -2095,6 +2095,35 @@ static size_t udev_replace_ifname(char *str) {
return replaced;
}
+static void udev_replace_ifname(UdevEvent *event, UdevRuleToken *token, char *buf) {
+ assert(event);
+ assert(token);
+ assert(buf);
+
+ size_t count;
+ if (naming_scheme_has(NAMING_REPLACE_STRICTLY))
+ count = udev_replace_ifname_strict(buf);
+ else
+ count = udev_replace_chars(buf, "/");
+ if (count > 0)
+ log_event_trace(event, token,
+ "Replaced %zu character(s) from network interface name, results to \"%s\"",
+ count, buf);
+}
+
+static void udev_replace_chars_and_log(UdevEvent *event, UdevRuleToken *token, char *buf, const char *allow, const char *what) {
+ assert(event);
+ assert(token);
+ assert(buf);
+ assert(what);
+
+ size_t count = udev_replace_chars(buf, allow);
+ if (count > 0)
+ log_event_trace(event, token,
+ "Replaced %zu character(s) from %s, results to \"%s\"",
+ count, what, buf);
+}
+
static int udev_rule_apply_token_to_event(
UdevRuleToken *token,
sd_device *dev,
@@ -2260,7 +2289,6 @@ static int udev_rule_apply_token_to_event(
}
case TK_M_PROGRAM: {
char buf[UDEV_LINE_SIZE], result[UDEV_LINE_SIZE];
- size_t count;
event->program_result = mfree(event->program_result);
@@ -2279,11 +2307,7 @@ static int udev_rule_apply_token_to_event(
}
delete_trailing_chars(result, "\n");
- count = udev_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
- if (count > 0)
- log_event_debug(event, token,
- "Replaced %zu character(s) in result of \"%s\"",
- count, buf);
+ udev_replace_chars_and_log(event, token, result, UDEV_ALLOWED_CHARS_INPUT, "command output");
event->program_result = strdup(result);
return token->op == OP_MATCH;
@@ -2644,7 +2668,7 @@ static int udev_rule_apply_token_to_event(
case TK_A_ENV: {
const char *val, *name = token->data;
char value_new[UDEV_NAME_SIZE], *p = value_new;
- size_t count, l = sizeof(value_new);
+ size_t l = sizeof(value_new);
if (isempty(token->value)) {
if (token->op == OP_ADD)
@@ -2670,13 +2694,8 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, p, l, "property value"))
return true;
- if (event->esc == ESCAPE_REPLACE) {
- count = udev_replace_chars(p, NULL);
- if (count > 0)
- log_event_debug(event, token,
- "Replaced %zu slash(es) from result of ENV{%s}%s=\"%s\"",
- count, name, token->op == OP_ADD ? "+" : "", token->value);
- }
+ if (event->esc == ESCAPE_REPLACE)
+ udev_replace_chars_and_log(event, token, p, /* allow = */ NULL, "property value");
r = device_add_property(dev, name, value_new);
if (r < 0)
@@ -2705,7 +2724,6 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_NAME: {
char buf[UDEV_PATH_SIZE];
- size_t count;
if (event->name_final)
break;
@@ -2722,16 +2740,9 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "network interface name"))
return true;
- if (IN_SET(event->esc, ESCAPE_UNSET, ESCAPE_REPLACE)) {
- if (naming_scheme_has(NAMING_REPLACE_STRICTLY))
- count = udev_replace_ifname(buf);
- else
- count = udev_replace_chars(buf, "/");
- if (count > 0)
- log_event_debug(event, token,
- "Replaced %zu character(s) from result of NAME=\"%s\"",
- count, token->value);
- }
+ if (IN_SET(event->esc, ESCAPE_UNSET, ESCAPE_REPLACE))
+ udev_replace_ifname(event, token, buf);
+
r = free_and_strdup_warn(&event->name, buf);
if (r < 0)
return r;
@@ -2741,7 +2752,6 @@ static int udev_rule_apply_token_to_event(
}
case TK_A_DEVLINK: {
char buf[UDEV_PATH_SIZE];
- size_t count;
if (event->devlink_final)
break;
@@ -2759,15 +2769,9 @@ static int udev_rule_apply_token_to_event(
/* By default or string_escape=none, allow multiple symlinks separated by spaces. */
if (event->esc == ESCAPE_UNSET)
- count = udev_replace_chars(buf, /* allow = */ "/ ");
+ udev_replace_chars_and_log(event, token, buf, /* allow = */ "/ ", "device node symlink");
else if (event->esc == ESCAPE_REPLACE)
- count = udev_replace_chars(buf, /* allow = */ "/");
- else
- count = 0;
- if (count > 0)
- log_event_debug(event, token,
- "Replaced %zu character(s) from result of SYMLINK=\"%s\"",
- count, token->value);
+ udev_replace_chars_and_log(event, token, buf, /* allow = */ "/", "device node symlink");
for (const char *p = buf;;) {
_cleanup_free_ char *path = NULL;

View File

@ -0,0 +1,38 @@
From 95534ef8f7558b5f7f93991043441adb9c7ddf33 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
does not contain newline
(cherry picked from commit 68b1e1b61ab333bb4dee4a43373bad54080e755f)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 53370f6085..9aa98a3b3c 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -2379,15 +2379,18 @@ static int udev_rule_apply_token_to_event(
}
if (truncated) {
- bool found = false;
+ log_event_debug(event, token, "Result of \"%s\" is too long and truncated, ignoring the last line of the result.", buf);
/* Drop the last line. */
+ bool found = false;
for (char *p = PTR_SUB1(buf + strlen(buf), buf); p; p = PTR_SUB1(p, buf))
if (strchr(NEWLINE, *p)) {
*p = '\0';
found = true;
- } else if (found)
break;
+ }
+ if (!found)
+ buf[0] = '\0';
}
r = strv_split_newlines_full(&lines, result, EXTRACT_RETAIN_ESCAPE);

View File

@ -0,0 +1,900 @@
From 9345b1fd8d04c0b222b94dd68e0f255c7358c792 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
This also adds trace logs about token result, and skipping assignment
caused by final value already assigned.
(cherry picked from commit 354d063fbcadb277094e47a79e7cde62ae269199)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 433 ++++++++++++++++++++++++------------------
1 file changed, 248 insertions(+), 185 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 9aa98a3b3c..c5fa2c660c 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -297,6 +297,37 @@ static bool token_is_for_parents(UdevRuleToken *token) {
#define log_event_trace(event, ...) \
_log_event_trace(event, UNIQ_T(e, UNIQ), __VA_ARGS__)
+#define _log_event_result(event, token, result, result_u) \
+ ({ \
+ bool result_u = (result); \
+ \
+ log_event_trace(event, token, "%s", \
+ result_u ? "PASS" : "FAIL"); \
+ result_u; \
+ })
+
+#define log_event_result(event, token, result) \
+ _log_event_result(event, token, result, UNIQ_T(r, UNIQ))
+
+#define log_event_done(event, token) \
+ ({ \
+ log_event_trace(event, token, "DONE"); \
+ true; \
+ })
+
+#define _log_event_final_set(event, token, token_u) \
+ ({ \
+ UdevRuleToken *token_u = ASSERT_PTR(token); \
+ \
+ log_event_trace(event, token_u, \
+ "Already assigned final value, ignoring further %s.", \
+ token_u->op == OP_REMOVE ? "modification" : "assignment"); \
+ true; \
+ })
+
+#define log_event_final_set(event, token) \
+ _log_event_final_set(event, token, UNIQ_T(t, UNIQ))
+
#define _log_event_truncated(event, token, token_u, what, format) \
({ \
UdevRuleToken *token_u = ASSERT_PTR(token); \
@@ -358,16 +389,6 @@ static bool token_is_for_parents(UdevRuleToken *token) {
"Invalid value \"%s\" for %s (char %zu: %s), ignoring.", \
value, key, offset, hint)
-static void log_unknown_owner(sd_device *dev, UdevRuleLine *line, int error, const char *entity, const char *name) {
- assert(line);
- ASSERT_NON_ZERO(error);
-
- if (IN_SET(abs(error), ENOENT, ESRCH))
- log_udev_rule_line_full(dev, line, LOG_ERR, error, "Unknown %s '%s', ignoring.", entity, name);
- else
- log_udev_rule_line_full(dev, line, LOG_ERR, error, "Failed to resolve %s '%s', ignoring: %m", entity, name);
-}
-
/*** Other functions ***/
static UdevRuleToken* udev_rule_token_free(UdevRuleToken *token) {
@@ -452,7 +473,11 @@ static int rule_resolve_user(UdevRuleLine *rule_line, const char *name, uid_t *r
r = get_user_creds(&name, &uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0) {
- log_unknown_owner(NULL, rule_line, r, "user", name);
+ if (IN_SET(r, -ENOENT, -ESRCH))
+ log_line_error_errno(rule_line, r, "Unknown user '%s', ignoring.", name);
+ else
+ log_line_error_errno(rule_line, r, "Failed to resolve user '%s', ignoring: %m", name);
+
*ret = UID_INVALID;
return 0;
}
@@ -488,7 +513,11 @@ static int rule_resolve_group(UdevRuleLine *rule_line, const char *name, gid_t *
r = get_group_creds(&name, &gid, USER_CREDS_ALLOW_MISSING);
if (r < 0) {
- log_unknown_owner(NULL, rule_line, r, "group", name);
+ if (IN_SET(r, -ENOENT, -ESRCH))
+ log_line_error_errno(rule_line, r, "Unknown group '%s', ignoring.", name);
+ else
+ log_line_error_errno(rule_line, r, "Failed to resolve group '%s', ignoring: %m", name);
+
*ret = GID_INVALID;
return 0;
}
@@ -2011,30 +2040,6 @@ static int get_property_from_string(char *line, char **ret_key, char **ret_value
return 1;
}
-static int import_parent_into_properties(sd_device *dev, const char *filter) {
- sd_device *parent;
- int r;
-
- assert(dev);
- assert(filter);
-
- r = sd_device_get_parent(dev, &parent);
- if (r == -ENOENT)
- return 0;
- if (r < 0)
- return r;
-
- FOREACH_DEVICE_PROPERTY(parent, key, val) {
- if (fnmatch(filter, key, 0) != 0)
- continue;
- r = device_add_property(dev, key, val);
- if (r < 0)
- return r;
- }
-
- return 1;
-}
-
static int attr_subst_subdir(char attr[static UDEV_PATH_SIZE]) {
_cleanup_closedir_ DIR *dir = NULL;
char buf[UDEV_PATH_SIZE], *p;
@@ -2172,8 +2177,8 @@ static int udev_rule_apply_token_to_event(
case TK_M_DEVLINK:
FOREACH_DEVICE_DEVLINK(dev, val)
if (token_match_string(event, token, strempty(startswith(val, "/dev/")), /* log_result = */ false) == (token->op == OP_MATCH))
- return token->op == OP_MATCH;
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_MATCH);
+ return log_event_result(event, token, token->op == OP_NOMATCH);
case TK_M_NAME:
return token_match_string(event, token, event->name, /* log_result = */ true);
@@ -2202,8 +2207,8 @@ static int udev_rule_apply_token_to_event(
case TK_M_PARENTS_TAG:
FOREACH_DEVICE_CURRENT_TAG(dev, val)
if (token_match_string(event, token, val, /* log_result = */ false) == (token->op == OP_MATCH))
- return token->op == OP_MATCH;
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_MATCH);
+ return log_event_result(event, token, token->op == OP_NOMATCH);
case TK_M_SUBSYSTEM:
case TK_M_PARENTS_SUBSYSTEM: {
@@ -2242,7 +2247,7 @@ static int udev_rule_apply_token_to_event(
r = sysctl_read(sysctl_normalize(buf), &value);
if (r < 0 && r != -ENOENT)
- return log_event_error_errno(event, token, r, "Failed to read sysctl '%s': %m", buf);
+ return log_event_error_errno(event, token, r, "Failed to read sysctl \"%s\": %m", buf);
return token_match_string(event, token, strstrip(value), /* log_result = */ true);
}
@@ -2269,23 +2274,26 @@ static int udev_rule_apply_token_to_event(
assert(!truncated);
strscpyl_full(buf, sizeof(buf), &truncated, val, "/", tmp, NULL);
if (truncated)
- return false;
+ return log_event_result(event, token, false);
}
r = attr_subst_subdir(buf);
if (r == -ENOENT)
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_NOMATCH);
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to test for the existence of '%s': %m", buf);
+ return log_event_error_errno(event, token, r, "Failed to test for the existence of \"%s\": %m", buf);
- if (stat(buf, &statbuf) < 0)
- return token->op == OP_NOMATCH;
+ if (stat(buf, &statbuf) < 0) {
+ if (errno != ENOENT)
+ log_event_warning_errno(event, token, errno, "Failed to stat \"%s\", ignoring: %m", buf);
+ return log_event_result(event, token, token->op == OP_NOMATCH);
+ }
if (mode == MODE_INVALID)
- return token->op == OP_MATCH;
+ return log_event_result(event, token, token->op == OP_MATCH);
match = (statbuf.st_mode & mode) > 0;
- return token->op == (match ? OP_MATCH : OP_NOMATCH);
+ return log_event_result(event, token, token->op == (match ? OP_MATCH : OP_NOMATCH));
}
case TK_M_PROGRAM: {
char buf[UDEV_LINE_SIZE], result[UDEV_LINE_SIZE];
@@ -2295,7 +2303,7 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "command"))
return false;
- log_event_debug(event, token, "Running PROGRAM=\"%s\"", buf);
+ log_event_debug(event, token, "Running command \"%s\"", buf);
r = udev_event_spawn(event, /* accept_failure = */ true, buf, result, sizeof(result), NULL);
if (r != 0) {
@@ -2303,14 +2311,14 @@ static int udev_rule_apply_token_to_event(
log_event_warning_errno(event, token, r, "Failed to execute \"%s\": %m", buf);
else /* returned value is positive when program fails */
log_event_debug(event, token, "Command \"%s\" returned %d (error)", buf, r);
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_NOMATCH);
}
delete_trailing_chars(result, "\n");
udev_replace_chars_and_log(event, token, result, UDEV_ALLOWED_CHARS_INPUT, "command output");
event->program_result = strdup(result);
- return token->op == OP_MATCH;
+ return log_event_result(event, token, token->op == OP_MATCH);
}
case TK_M_IMPORT_FILE: {
_cleanup_fclose_ FILE *f = NULL;
@@ -2319,13 +2327,13 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "file name to be imported"))
return false;
- log_event_debug(event, token, "Importing properties from '%s'", buf);
+ log_event_debug(event, token, "Importing properties from \"%s\"", buf);
f = fopen(buf, "re");
if (!f) {
if (errno != ENOENT)
- return log_event_error_errno(event, token, errno, "Failed to open '%s': %m", buf);
- return token->op == OP_NOMATCH;
+ return log_event_error_errno(event, token, errno, "Failed to open \"%s\": %m", buf);
+ return log_event_result(event, token, token->op == OP_NOMATCH);
}
for (;;) {
@@ -2334,16 +2342,16 @@ static int udev_rule_apply_token_to_event(
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0) {
- log_event_debug_errno(event, token, r, "Failed to read '%s', ignoring: %m", buf);
- return token->op == OP_NOMATCH;
+ log_event_debug_errno(event, token, r, "Failed to read \"%s\", ignoring: %m", buf);
+ return log_event_result(event, token, token->op == OP_NOMATCH);
}
if (r == 0)
- break;
+ return log_event_result(event, token, token->op == OP_MATCH);
r = get_property_from_string(line, &key, &value);
if (r < 0) {
log_event_debug_errno(event, token, r,
- "Failed to parse key and value from '%s', ignoring: %m",
+ "Failed to parse key and value from \"%s\", ignoring: %m",
line);
continue;
}
@@ -2355,9 +2363,10 @@ static int udev_rule_apply_token_to_event(
return log_event_error_errno(event, token, r,
"Failed to add property %s=%s: %m",
key, value);
+ log_event_trace(event, token, "Imported property \"%s=%s\".", key, value);
}
- return token->op == OP_MATCH;
+ assert_not_reached();
}
case TK_M_IMPORT_PROGRAM: {
_cleanup_strv_free_ char **lines = NULL;
@@ -2367,15 +2376,15 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "command"))
return false;
- log_event_debug(event, token, "Importing properties from results of '%s'", buf);
+ log_event_debug(event, token, "Importing properties from results of \"%s\"", buf);
r = udev_event_spawn(event, /* accept_failure = */ true, buf, result, sizeof result, &truncated);
if (r != 0) {
if (r < 0)
- log_event_warning_errno(event, token, r, "Failed to execute '%s', ignoring: %m", buf);
+ log_event_warning_errno(event, token, r, "Failed to execute \"%s\", ignoring: %m", buf);
else /* returned value is positive when program fails */
log_event_debug(event, token, "Command \"%s\" returned %d (error), ignoring", buf, r);
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_NOMATCH);
}
if (truncated) {
@@ -2399,7 +2408,7 @@ static int udev_rule_apply_token_to_event(
if (r < 0) {
log_event_warning_errno(event, token, r,
"Failed to extract lines from result of command \"%s\", ignoring: %m", buf);
- return false;
+ return log_event_result(event, token, false);
}
STRV_FOREACH(line, lines) {
@@ -2408,7 +2417,7 @@ static int udev_rule_apply_token_to_event(
r = get_property_from_string(*line, &key, &value);
if (r < 0) {
log_event_debug_errno(event, token, r,
- "Failed to parse key and value from '%s', ignoring: %m",
+ "Failed to parse key and value from \"%s\", ignoring: %m",
*line);
continue;
}
@@ -2420,9 +2429,10 @@ static int udev_rule_apply_token_to_event(
return log_event_error_errno(event, token, r,
"Failed to add property %s=%s: %m",
key, value);
+ log_event_trace(event, token, "Imported property \"%s=%s\".", key, value);
}
- return token->op == OP_MATCH;
+ return log_event_result(event, token, token->op == OP_MATCH);
}
case TK_M_IMPORT_BUILTIN: {
UdevBuiltinCommand cmd = PTR_TO_UDEV_BUILTIN_CMD(token->data);
@@ -2433,10 +2443,10 @@ static int udev_rule_apply_token_to_event(
if (udev_builtin_run_once(cmd)) {
/* check if we ran already */
if (event->builtin_run & mask) {
- log_event_debug(event, token, "Skipping builtin '%s' in IMPORT key",
+ log_event_debug(event, token, "Builtin command \"%s\" has already run, skipping.",
udev_builtin_name(cmd));
/* return the result from earlier run */
- return token->op == (event->builtin_ret & mask ? OP_NOMATCH : OP_MATCH);
+ return log_event_result(event, token, token->op == (event->builtin_ret & mask ? OP_NOMATCH : OP_MATCH));
}
/* mark as ran */
event->builtin_run |= mask;
@@ -2445,34 +2455,36 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "builtin command"))
return false;
- log_event_debug(event, token, "Importing properties from results of builtin command '%s'", buf);
+ log_event_debug(event, token, "Importing properties from results of builtin command \"%s\".", buf);
r = udev_builtin_run(event, cmd, buf);
if (r < 0) {
/* remember failure */
- log_event_debug_errno(event, token, r, "Failed to run builtin '%s': %m", buf);
+ log_event_debug_errno(event, token, r, "Failed to run builtin \"%s\": %m", buf);
event->builtin_ret |= mask;
}
- return token->op == (r >= 0 ? OP_MATCH : OP_NOMATCH);
+ return log_event_result(event, token, token->op == (r >= 0 ? OP_MATCH : OP_NOMATCH));
}
case TK_M_IMPORT_DB: {
const char *val;
if (!event->dev_db_clone)
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_NOMATCH);
r = sd_device_get_property_value(event->dev_db_clone, token->value, &val);
if (r == -ENOENT)
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_NOMATCH);
if (r < 0)
return log_event_error_errno(event, token, r,
- "Failed to get property '%s' from database: %m",
+ "Failed to get property \"%s\" from database: %m",
token->value);
r = device_add_property(dev, token->value, val);
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to add property '%s=%s': %m",
+ return log_event_error_errno(event, token, r, "Failed to add property \"%s=%s\": %m",
token->value, val);
- return token->op == OP_MATCH;
+ log_event_trace(event, token, "Imported property \"%s=%s\".", token->value, val);
+
+ return log_event_result(event, token, token->op == OP_MATCH);
}
case TK_M_IMPORT_CMDLINE: {
_cleanup_free_ char *value = NULL;
@@ -2480,16 +2492,19 @@ static int udev_rule_apply_token_to_event(
r = proc_cmdline_get_key(token->value, PROC_CMDLINE_VALUE_OPTIONAL|PROC_CMDLINE_IGNORE_EFI_OPTIONS, &value);
if (r < 0)
return log_event_error_errno(event, token, r,
- "Failed to read '%s' option from /proc/cmdline: %m",
+ "Failed to read \"%s\" option from /proc/cmdline: %m",
token->value);
if (r == 0)
- return token->op == OP_NOMATCH;
+ return log_event_result(event, token, token->op == OP_NOMATCH);
- r = device_add_property(dev, token->value, value ?: "1");
+ const char *val = value ?: "1";
+ r = device_add_property(dev, token->value, val);
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to add property '%s=%s': %m",
- token->value, value ?: "1");
- return token->op == OP_MATCH;
+ return log_event_error_errno(event, token, r, "Failed to add property \"%s=%s\": %m",
+ token->value, val);
+ log_event_trace(event, token, "Imported property \"%s=%s\".", token->value, val);
+
+ return log_event_result(event, token, token->op == OP_MATCH);
}
case TK_M_IMPORT_PARENT: {
char buf[UDEV_PATH_SIZE];
@@ -2497,35 +2512,56 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "property name"))
return false;
- r = import_parent_into_properties(dev, buf);
+ sd_device *parent;
+ r = sd_device_get_parent(dev, &parent);
+ if (ERRNO_IS_NEG_DEVICE_ABSENT(r))
+ return log_event_result(event, token, token->op == OP_NOMATCH);
if (r < 0)
- return log_event_error_errno(event, token, r,
- "Failed to import properties '%s' from parent: %m",
- buf);
- return token->op == (r > 0 ? OP_MATCH : OP_NOMATCH);
+ return log_event_error_errno(event, token, r, "Failed to get parent device: %m");
+
+ bool have = false;
+ FOREACH_DEVICE_PROPERTY(parent, key, val) {
+ if (fnmatch(buf, key, 0) != 0)
+ continue;
+
+ r = device_add_property(dev, key, val);
+ if (r < 0)
+ return log_event_error_errno(event, token, r, "Failed to add property \"%s=%s\": %m", key, val);
+ log_event_trace(event, token, "Imported property \"%s=%s\".", key, val);
+ have = true;
+ }
+
+ return log_event_result(event, token, token->op == (have ? OP_MATCH : OP_NOMATCH));
}
case TK_M_RESULT:
return token_match_string(event, token, event->program_result, /* log_result = */ true);
+
case TK_A_OPTIONS_STRING_ESCAPE_NONE:
event->esc = ESCAPE_NONE;
- break;
+ return log_event_done(event, token);
+
case TK_A_OPTIONS_STRING_ESCAPE_REPLACE:
event->esc = ESCAPE_REPLACE;
- break;
+ return log_event_done(event, token);
+
case TK_A_OPTIONS_DB_PERSIST:
device_set_db_persist(dev);
- break;
+ return log_event_done(event, token);
+
case TK_A_OPTIONS_INOTIFY_WATCH:
if (event->inotify_watch_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->inotify_watch_final = true;
event->inotify_watch = token->data;
- break;
+ return log_event_done(event, token);
+
case TK_A_OPTIONS_DEVLINK_PRIORITY:
device_set_devlink_priority(dev, PTR_TO_INT(token->data));
- break;
+ return log_event_done(event, token);
+
case TK_A_OPTIONS_LOG_LEVEL: {
int level = PTR_TO_INT(token->data);
@@ -2547,14 +2583,15 @@ static int udev_rule_apply_token_to_event(
event->log_level_was_debug = true;
}
- break;
+ return log_event_done(event, token);
}
case TK_A_OWNER: {
char owner[UDEV_NAME_SIZE];
const char *ow = owner;
if (event->owner_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->owner_final = true;
@@ -2562,18 +2599,21 @@ static int udev_rule_apply_token_to_event(
return true;
r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
- if (r < 0)
- log_unknown_owner(dev, token->rule_line, r, "user", owner);
+ if (IN_SET(r, -ENOENT, -ESRCH))
+ log_event_error_errno(event, token, r, "Unknown user \"%s\", ignoring.", owner);
+ else if (r < 0)
+ log_event_error_errno(event, token, r, "Failed to resolve user \"%s\", ignoring: %m", owner);
else
- log_event_debug(event, token, "OWNER %s(%u)", owner, event->uid);
- break;
+ log_event_debug(event, token, "Set owner: %s(%u)", owner, event->uid);
+ return true;
}
case TK_A_GROUP: {
char group[UDEV_NAME_SIZE];
const char *gr = group;
if (event->group_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->group_final = true;
@@ -2581,17 +2621,20 @@ static int udev_rule_apply_token_to_event(
return true;
r = get_group_creds(&gr, &event->gid, USER_CREDS_ALLOW_MISSING);
- if (r < 0)
- log_unknown_owner(dev, token->rule_line, r, "group", group);
+ if (IN_SET(r, -ENOENT, -ESRCH))
+ log_event_error_errno(event, token, r, "Unknown group \"%s\", ignoring.", group);
+ else if (r < 0)
+ log_event_error_errno(event, token, r, "Failed to resolve group \"%s\", ignoring: %m", group);
else
- log_event_debug(event, token, "GROUP %s(%u)", group, event->gid);
- break;
+ log_event_debug(event, token, "Set group: %s(%u)", group, event->gid);
+ return true;
}
case TK_A_MODE: {
char mode_str[UDEV_NAME_SIZE];
if (event->mode_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->mode_final = true;
@@ -2600,41 +2643,44 @@ static int udev_rule_apply_token_to_event(
r = parse_mode(mode_str, &event->mode);
if (r < 0)
- log_event_error_errno(event, token, r, "Failed to parse mode '%s', ignoring: %m", mode_str);
+ log_event_error_errno(event, token, r, "Failed to parse mode \"%s\", ignoring: %m", mode_str);
else
- log_event_debug(event, token, "MODE %#o", event->mode);
- break;
+ log_event_debug(event, token, "Set mode: %#o", event->mode);
+ return true;
}
case TK_A_OWNER_ID:
if (event->owner_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->owner_final = true;
- if (!token->data)
- break;
- event->uid = PTR_TO_UID(token->data);
- log_event_debug(event, token, "OWNER %u", event->uid);
- break;
+
+ event->uid = PTR_TO_UID(ASSERT_PTR(token->data));
+ log_event_debug(event, token, "Set owner ID: %u", event->uid);
+ return true;
+
case TK_A_GROUP_ID:
if (event->group_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->group_final = true;
- if (!token->data)
- break;
- event->gid = PTR_TO_GID(token->data);
- log_event_debug(event, token, "GROUP %u", event->gid);
- break;
+
+ event->gid = PTR_TO_GID(ASSERT_PTR(token->data));
+ log_event_debug(event, token, "Set group ID: %u", event->gid);
+ return true;
+
case TK_A_MODE_ID:
if (event->mode_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->mode_final = true;
- if (!token->data)
- break;
- event->mode = PTR_TO_MODE(token->data);
- log_event_debug(event, token, "MODE %#o", event->mode);
- break;
+
+ event->mode = PTR_TO_MODE(ASSERT_PTR(token->data));
+ log_event_debug(event, token, "Set mode: %#o", event->mode);
+ return true;
+
case TK_A_SECLABEL: {
_cleanup_free_ char *name = NULL, *label = NULL;
char label_str[UDEV_LINE_SIZE] = {};
@@ -2660,13 +2706,13 @@ static int udev_rule_apply_token_to_event(
if (r == -ENOMEM)
return log_oom();
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to store SECLABEL{%s}='%s': %m", name, label);
+ return log_event_error_errno(event, token, r, "Failed to store security label \"%s=%s\": %m", name, label);
- log_event_debug(event, token, "SECLABEL{%s}='%s'", name, label);
+ log_event_debug(event, token, "Set security label: %s=%s", name, label);
TAKE_PTR(name);
TAKE_PTR(label);
- break;
+ return true;
}
case TK_A_ENV: {
const char *val, *name = token->data;
@@ -2675,11 +2721,13 @@ static int udev_rule_apply_token_to_event(
if (isempty(token->value)) {
if (token->op == OP_ADD)
- break;
+ return log_event_done(event, token);
+
r = device_add_property(dev, name, NULL);
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to remove property '%s': %m", name);
- break;
+ return log_event_error_errno(event, token, r, "Failed to remove property \"%s\": %m", name);
+ log_event_trace(event, token, "Removed property \"%s\".", name);
+ return true;
}
if (token->op == OP_ADD &&
@@ -2688,9 +2736,9 @@ static int udev_rule_apply_token_to_event(
l = strpcpyl_full(&p, l, &truncated, val, " ", NULL);
if (truncated) {
log_event_warning(event, token,
- "The buffer for the property '%s' is full, "
- "refusing to append the new value '%s'.", name, token->value);
- break;
+ "The buffer for the property is full, refusing to append new property \"%s=%s\".",
+ name, token->value);
+ return true;
}
}
@@ -2702,8 +2750,9 @@ static int udev_rule_apply_token_to_event(
r = device_add_property(dev, name, value_new);
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to add property '%s=%s': %m", name, value_new);
- break;
+ return log_event_error_errno(event, token, r, "Failed to set property \"%s=%s\": %m", name, value_new);
+ log_event_trace(event, token, "Set property \"%s=%s\".", name, value_new);
+ return true;
}
case TK_A_TAG: {
char buf[UDEV_PATH_SIZE];
@@ -2711,33 +2760,39 @@ static int udev_rule_apply_token_to_event(
if (!apply_format_value(event, token, buf, sizeof(buf), "tag name"))
return true;
+ if (token->op == OP_REMOVE) {
+ device_remove_tag(dev, buf);
+ log_event_trace(event, token, "Removed tag \"%s\".", buf);
+ return true;
+ }
+
+ assert(IN_SET(token->op, OP_ASSIGN, OP_ADD));
+
if (token->op == OP_ASSIGN)
device_cleanup_tags(dev);
- if (token->op == OP_REMOVE)
- device_remove_tag(dev, buf);
- else {
- r = device_add_tag(dev, buf, true);
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0)
- log_event_warning_errno(event, token, r, "Failed to add tag '%s', ignoring: %m", buf);
- }
- break;
+ r = device_add_tag(dev, buf, /* both = */ true);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ log_event_warning_errno(event, token, r, "Failed to %s tag \"%s\", ignoring: %m",
+ token->op == OP_ASSIGN ? "set" : "add", buf);
+ else
+ log_event_trace(event, token, "%s tag \"%s\".", token->op == OP_ASSIGN ? "Set" : "Added", buf);
+ return true;
}
case TK_A_NAME: {
char buf[UDEV_PATH_SIZE];
if (event->name_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->name_final = true;
if (sd_device_get_ifindex(dev, NULL) < 0) {
- log_event_error(event, token,
- "Only network interfaces can be renamed, ignoring NAME=\"%s\".",
- token->value);
- break;
+ log_event_warning(event, token, "Only network interfaces can be renamed, ignoring.");
+ return true;
}
if (!apply_format_value(event, token, buf, sizeof(buf), "network interface name"))
@@ -2750,18 +2805,23 @@ static int udev_rule_apply_token_to_event(
if (r < 0)
return r;
- log_event_debug(event, token, "NAME '%s'", event->name);
- break;
+ log_event_debug(event, token, "Set network interface name: %s", event->name);
+ return true;
}
case TK_A_DEVLINK: {
char buf[UDEV_PATH_SIZE];
if (event->devlink_final)
- break;
- if (sd_device_get_devnum(dev, NULL) < 0)
- break;
+ return log_event_final_set(event, token);
+
+ if (sd_device_get_devnum(dev, NULL) < 0) {
+ log_event_debug(event, token, "Device does not have device node, ignoring to manage device node symlink.");
+ return true;
+ }
+
if (token->op == OP_ASSIGN_FINAL)
event->devlink_final = true;
+
if (IN_SET(token->op, OP_ASSIGN, OP_ASSIGN_FINAL))
device_cleanup_devlinks(dev);
@@ -2783,31 +2843,31 @@ static int udev_rule_apply_token_to_event(
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_warning_errno(r, "Failed to extract first path in SYMLINK=, ignoring: %m");
- break;
+ log_warning_errno(r, "Failed to extract first path in device node symlinks, ignoring: %m");
+ return true;
}
if (r == 0)
- break;
+ return true;
if (token->op == OP_REMOVE) {
r = device_remove_devlink(dev, path);
if (r == -ENOMEM)
return log_oom();
if (r < 0)
- log_event_warning_errno(event, token, r, "Failed to remove devlink '%s', ignoring: %m", path);
+ log_event_warning_errno(event, token, r, "Failed to remove device node symlink \"%s\", ignoring: %m", path);
else if (r > 0)
- log_event_debug(event, token, "Dropped SYMLINK '%s'", path);
+ log_event_debug(event, token, "Removed device node symlink \"%s\"", path);
} else {
r = device_add_devlink(dev, path);
if (r == -ENOMEM)
return log_oom();
if (r < 0)
- log_event_warning_errno(event, token, r, "Failed to add devlink '%s', ignoring: %m", path);
+ log_event_warning_errno(event, token, r, "Failed to add device node symlink \"%s\", ignoring: %m", path);
else if (r > 0)
- log_event_debug(event, token, "Added SYMLINK '%s'", path);
+ log_event_debug(event, token, "Added device node symlink \"%s\".", path);
}
}
- break;
+ assert_not_reached();
}
case TK_A_ATTR: {
char buf[UDEV_PATH_SIZE], value[UDEV_NAME_SIZE];
@@ -2819,34 +2879,36 @@ static int udev_rule_apply_token_to_event(
strscpyl_full(buf, sizeof(buf), &truncated, val, "/", key_name, NULL);
if (truncated) {
log_event_warning(event, token,
- "The path to the attribute '%s/%s' is too long, refusing to set the attribute.",
+ "The path to the attribute \"%s/%s\" is too long, refusing to set the attribute.",
val, key_name);
- break;
+ return true;
}
}
r = attr_subst_subdir(buf);
if (r < 0) {
- log_event_error_errno(event, token, r, "Could not find file matches '%s', ignoring: %m", buf);
- break;
+ log_event_error_errno(event, token, r, "Could not find file matches \"%s\", ignoring: %m", buf);
+ return true;
}
if (!apply_format_value(event, token, value, sizeof(value), "attribute value"))
return true;
if (EVENT_MODE_DESTRUCTIVE(event)) {
- log_event_debug(event, token, "Writing ATTR{'%s'}=\"%s\".", buf, value);
+ log_event_debug(event, token, "Writing \"%s\" to sysfs attribute \"%s\".", value, buf);
r = write_string_file(buf, value,
WRITE_STRING_FILE_VERIFY_ON_FAILURE |
WRITE_STRING_FILE_DISABLE_BUFFER |
WRITE_STRING_FILE_AVOID_NEWLINE |
WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE);
if (r < 0)
- log_event_error_errno(event, token, r, "Failed to write ATTR{%s}=\"%s\", ignoring: %m", buf, value);
+ log_event_error_errno(event, token, r, "Failed to write \"%s\" to sysfs attribute \"%s\", ignoring: %m", value, buf);
+ else
+ log_event_done(event, token);
} else
- log_event_debug(event, token, "Running in test mode, skipping writing ATTR{%s}=\"%s\".", buf, value);
+ log_event_debug(event, token, "Running in test mode, skipping writing \"%s\" to sysfs attribute \"%s\".", value, buf);
- break;
+ return true;
}
case TK_A_SYSCTL: {
char buf[UDEV_PATH_SIZE], value[UDEV_NAME_SIZE];
@@ -2860,14 +2922,16 @@ static int udev_rule_apply_token_to_event(
sysctl_normalize(buf);
if (EVENT_MODE_DESTRUCTIVE(event)) {
- log_event_debug(event, token, "Writing SYSCTL{%s}=\"%s\".", buf, value);
+ log_event_debug(event, token, "Writing \"%s\" to sysctl entry \"%s\".", value, buf);
r = sysctl_write(buf, value);
if (r < 0)
- log_event_error_errno(event, token, r, "Failed to write SYSCTL{%s}=\"%s\", ignoring: %m", buf, value);
+ log_event_error_errno(event, token, r, "Failed to write \"%s\" to sysctl entry \"%s\", ignoring: %m", value, buf);
+ else
+ log_event_done(event, token);
} else
- log_event_debug(event, token, "Running in test mode, skipping writing SYSCTL{%s}=\"%s\".", buf, value);
+ log_event_debug(event, token, "Running in test mode, skipping writing \"%s\" to sysctl entry \"%s\".", value, buf);
- break;
+ return true;
}
case TK_A_RUN_BUILTIN:
case TK_A_RUN_PROGRAM: {
@@ -2875,7 +2939,8 @@ static int udev_rule_apply_token_to_event(
char buf[UDEV_LINE_SIZE];
if (event->run_final)
- break;
+ return log_event_final_set(event, token);
+
if (token->op == OP_ASSIGN_FINAL)
event->run_final = true;
@@ -2890,24 +2955,22 @@ static int udev_rule_apply_token_to_event(
return log_oom();
r = ordered_hashmap_ensure_put(&event->run_list, NULL, cmd, token->data);
- if (r == -ENOMEM)
- return log_oom();
if (r < 0)
- return log_event_error_errno(event, token, r, "Failed to store command '%s': %m", cmd);
+ return log_event_error_errno(event, token, r, "Failed to store command \"%s\": %m", cmd);
+ log_event_debug(event, token, "Set command: %s", cmd);
TAKE_PTR(cmd);
-
- log_event_debug(event, token, "RUN '%s'", token->value);
- break;
+ return true;
}
case TK_A_OPTIONS_STATIC_NODE:
/* do nothing for events. */
- break;
+ return true;
+
default:
assert_not_reached();
}
- return true;
+ assert_not_reached();
}
static int udev_rule_apply_parent_token_to_event(UdevRuleToken *head_token, UdevEvent *event) {

View File

@ -0,0 +1,103 @@
From 7f14a15e480fd4392bc86f7927c9b14dfe833d83 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
(cherry picked from commit c547b9e278b86cd2318cb69319aaadad9004d96a)
Resolves: RHEL-75774
---
src/udev/udev-rules.c | 48 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index c5fa2c660c..4f2021b8c4 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -345,6 +345,20 @@ static bool token_is_for_parents(UdevRuleToken *token) {
#define log_event_truncated(event, token, what, format) \
_log_event_truncated(event, token, UNIQ_T(t, UNIQ), what, format)
+#define _log_event_line(event, event_u, line, ...) \
+ ({ \
+ UdevEvent *event_u = ASSERT_PTR(event); \
+ \
+ event_u->trace ? \
+ log_udev_rule_line_full( \
+ event_u->dev, line, \
+ LOG_DEBUG, 0, __VA_ARGS__) : \
+ 0; \
+ })
+
+#define log_event_line(event, line, ...) \
+ _log_event_line(event, UNIQ_T(e, UNIQ), line, __VA_ARGS__)
+
/* Mainly used when parsing .rules files. */
#define log_file_full_errno_zerook(...) \
log_udev_rule_file_full(NULL, __VA_ARGS__)
@@ -2977,14 +2991,30 @@ static int udev_rule_apply_parent_token_to_event(UdevRuleToken *head_token, Udev
int r;
assert(head_token);
+ assert(token_is_for_parents(head_token));
assert(event);
+ UdevRuleLine *line = head_token->rule_line;
+ if (event->trace) {
+ _cleanup_free_ char *joined = NULL;
+
+ LIST_FOREACH(tokens, token, head_token)
+ if (token_is_for_parents(token))
+ (void) strextend_with_separator(&joined, ", ", token->token_str);
+ else
+ break;
+
+ log_event_line(event, line, "Checking conditions for parent devices: %s", strna(joined));
+ }
+
event->dev_parent = ASSERT_PTR(event->dev);
for (;;) {
LIST_FOREACH(tokens, token, head_token) {
- if (!token_is_for_parents(token))
- return true; /* All parent tokens match. */
+ if (!token_is_for_parents(token)) {
+ r = 1; /* avoid false maybe-uninitialized warning */
+ break; /* All parent tokens match. */
+ }
r = udev_rule_apply_token_to_event(token, event->dev_parent, event);
if (r < 0)
@@ -2992,12 +3022,18 @@ static int udev_rule_apply_parent_token_to_event(UdevRuleToken *head_token, Udev
if (r == 0)
break;
}
- if (r > 0)
- /* All parent tokens match, and no more token (except for GOTO) in the line. */
+ if (r > 0) {
+ if (event->trace) {
+ const char *s = NULL;
+ (void) sd_device_get_syspath(event->dev_parent, &s);
+ log_event_line(event, line, "Parent device \"%s\" passed all parent conditions.", strna(s));
+ }
return true;
+ }
if (sd_device_get_parent(event->dev_parent, &event->dev_parent) < 0) {
event->dev_parent = NULL;
+ log_event_line(event, line, "No parent device passed parent conditions.");
return false;
}
}
@@ -3054,8 +3090,10 @@ static int udev_rule_apply_line_to_event(
return r;
}
- if (line->goto_line)
+ if (line->goto_line) {
+ log_event_line(event, line, "GOTO=%s", strna(line->goto_label));
*next_line = line->goto_line; /* update next_line only when the line has GOTO token. */
+ }
return 0;
}

View File

@ -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: 3%{?dist}.alma.1
Release: 4%{?dist}.alma.1
%global stable %(c="%version"; [ "$c" = "${c#*.*}" ]; echo $?)
@ -252,6 +252,35 @@ Patch0140: 0140-netif-naming-scheme-rename-rhel-10.0-to-rhel-10.0.be.patch
Patch0141: 0141-net-naming-scheme-disable-NAMING_FIRMWARE_NODE_SUN.patch
Patch0142: 0142-netif-naming-scheme-introduce-rhel-10.0-scheme.patch
Patch0143: 0143-udev-net_id-introduce-naming-scheme-for-RHEL-9.6.patch
Patch0144: 0144-ci-use-ubuntu-22-04-for-deploy-of-man-pages.patch
Patch0145: 0145-tree-wide-Fix-python-formatting.patch
Patch0146: 0146-ci-fix-Packit.patch
Patch0147: 0147-ci-drop-testing-farm-test.patch
Patch0148: 0148-dbus-stash-the-subscriber-list-when-we-disconenct-fr.patch
Patch0149: 0149-manager-s-deserialized_subscribed-subscribed_as_strv.patch
Patch0150: 0150-shared-bus-util-move-bus_message_read_id128-to-bus-m.patch
Patch0151: 0151-shared-bus-util-move-bus_message_hash_ops-to-bus-mes.patch
Patch0152: 0152-shared-bus-util-move-string-set-append-get-funcs-to-.patch
Patch0153: 0153-shared-serialize-make-input-params-const.patch
Patch0154: 0154-shared-serialize-introduce-serialize_id128.patch
Patch0155: 0155-bus-util-do-not-reset-the-count-returned-by-sd_bus_t.patch
Patch0156: 0156-core-manager-use-FOREACH_ARRAY-at-one-more-place.patch
Patch0157: 0157-core-manager-drop-duplicate-bus-track-deserializatio.patch
Patch0158: 0158-bus-util-introduce-bus_get_instance_id.patch
Patch0159: 0159-core-serialize-API-bus-id-and-validate-before-deseri.patch
Patch0160: 0160-core-manager-restore-bus-track-deserialization-clean.patch
Patch0161: 0161-shared-bus-util-add-missing-set.h-include.patch
Patch0162: 0162-udevadm-test-add-missing-oom-check.patch
Patch0163: 0163-udev-rules-replace-type-func-type-func.patch
Patch0164: 0164-udev-rules-do-not-change-maximum-log-level-when-runn.patch
Patch0165: 0165-udevadm-test-introduce-v-verbose-option-to-show-verb.patch
Patch0166: 0166-udev-rules-show-original-token-string-in-log_event_e.patch
Patch0167: 0167-udev-rules-logs-result-of-format-substitution.patch
Patch0168: 0168-udev-rules-add-more-trace-logs-for-string-match.patch
Patch0169: 0169-udev-rules-introduce-udev_replace_chars_and_log.patch
Patch0170: 0170-udev-rules-ignore-whole-command-result-if-it-is-too-.patch
Patch0171: 0171-udev-rules-update-log-messages.patch
Patch0172: 0172-udev-rules-add-trace-logs-for-GOTO-and-parent-condit.patch
# Downstream-only patches (90009999)
@ -1182,10 +1211,41 @@ rm -f .file-list-*
rm -f %{name}.lang
%changelog
* Thu Jan 16 2025 Andrew Lukoshko <alukoshko@almalinux.org> - 257-3.alma.1
* Thu Jan 16 2025 Andrew Lukoshko <alukoshko@almalinux.org> - 257-4.alma.1
- Debrand for AlmaLinux
* Wed Jan 08 2024 Jan Macku <jamacku@redhat.com> - 257-3
* Thu Jan 30 2025 systemd maintenance team <systemd-maint@redhat.com> - 257-4
- ci: use ubuntu 22:04 for deploy of man pages (RHEL-57603)
- tree-wide: Fix python formatting (RHEL-57603)
- ci: fix Packit (RHEL-57603)
- ci: drop testing farm test (RHEL-57603)
- dbus: stash the subscriber list when we disconenct from the bus (RHEL-73780)
- manager: s/deserialized_subscribed/subscribed_as_strv (RHEL-73780)
- shared/bus-util: move bus_message_read_id128() to bus-message-util (RHEL-73780)
- shared/bus-util: move bus_message_hash_ops to bus-message-util (RHEL-73780)
- shared/bus-util: move string set append/get funcs to bus-message-util and bus-get-properties, respectively (RHEL-73780)
- shared/serialize: make input params const (RHEL-73780)
- shared/serialize: introduce serialize_id128() (RHEL-73780)
- bus-util: do not reset the count returned by sd_bus_track_count_name() (RHEL-73780)
- core/manager: use FOREACH_ARRAY at one more place (RHEL-73780)
- core/manager: drop duplicate bus track deserialization (RHEL-73780)
- bus-util: introduce bus_get_instance_id() (RHEL-73780)
- core: serialize API bus id and validate before deserializing bus tracks (RHEL-73780)
- core/manager: restore bus track deserialization cleanup in manager_reload() (RHEL-73780)
- shared/bus-util: add missing `set.h` include (RHEL-73780)
- udevadm-test: add missing oom check (RHEL-75774)
- udev-rules: replace 'type *func()' -> 'type* func()' (RHEL-75774)
- udev-rules: do not change maximum log level when running in test mode (RHEL-75774)
- udevadm-test: introduce -v/--verbose option to show verbose log messages (RHEL-75774)
- udev-rules: show original token string in log_event_error() and friends (RHEL-75774)
- udev-rules: logs result of format substitution (RHEL-75774)
- udev-rules: add more trace logs for string match (RHEL-75774)
- udev-rules: introduce udev_replace_chars_and_log() (RHEL-75774)
- udev-rules: ignore whole command result if it is too long and does not contain newline (RHEL-75774)
- udev-rules: update log messages (RHEL-75774)
- udev-rules: add trace logs for GOTO and parent conditions (RHEL-75774)
* Wed Jan 08 2025 Jan Macku <jamacku@redhat.com> - 257-3
- udev/net_id: introduce naming scheme for RHEL-9.6 (RHEL-44417)
- Rebase to new upstream stable release v257.2 (RHEL-71409)