Projects
openEuler:Mainline
systemd
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 5
View file
_service:tar_scm:systemd.spec
Changed
@@ -21,7 +21,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd Version: 249 -Release: 50 +Release: 52 License: MIT and LGPLv2+ and GPLv2+ Summary: System and Service Manager @@ -451,6 +451,65 @@ Patch6404: backport-core-unit-merge-unit-names-after-merging-deps.patch Patch6405: backport-core-unit-fix-log-message.patch Patch6406: backport-test-add-test-case-for-sysv-generator-and-invalid-de.patch +Patch6407: backport-udev-also-rename-struct-udev_ctrl-UdevCtrl.patch +Patch6408: backport-udev-move-several-functions.patch +Patch6409: backport-udev-update-log-message-to-clarify-that-the-error-is-ignored.patch +Patch6410: backport-udev-make-event_free-return-NULL.patch +Patch6411: backport-udev-make-event_queue_start-return-negative-errno-on-error.patch +Patch6412: backport-udev-add-usec_add-at-one-more-place.patch +Patch6413: backport-udev-propagate-error-on-spawning-a-worker.patch +Patch6414: backport-udev-do-not-try-to-process-events-if-there-is-no-free-worker.patch +Patch6415: backport-udev-rename-is_device_busy-event_is_blocked.patch +Patch6416: backport-list-introduce-LIST_FOREACH_BACKWARDS-macro-and-drop.patch +Patch6417: backport-udev-do-not-try-to-find-blocker-again-when-no-blocker-found.patch +Patch6418: backport-udev-skip-event-when-its-dependency-cannot-be-checked.patch +Patch6419: backport-event-util-introduce-event_reset_time_relative.patch +Patch6420: backport-udev-update-comment-and-log-messages.patch +Patch6421: backport-udev-remove-run-udev-queue-in-on_post.patch +Patch6422: backport-errno-util-add-ERRNO_IS_DEVICE_ABSENT-macro.patch +Patch6423: backport-udev-only-ignore-ENOENT-or-friends-which-suggest-the-block.patch +Patch6424: backport-udev-assume-there-is-no-blocker-when-failed-to-check-event.patch +Patch6425: backport-udev-drop-unnecessary-clone-of-received-sd-device-object.patch +Patch6426: backport-udev-introduce-device_broadcast_helper_function.patch +Patch6427: backport-udev-store-action-in-struct-Event.patch +Patch6428: backport-udev-requeue-event-when-the-corresponding-block-device-is.patch +Patch6429: backport-udev-split-worker_lock_block_device-into-two.patch +Patch6430: backport-udev-assume-block-device-is-not-locked-when-a-new-event-is-queued.patch +Patch6431: backport-udev-fix-inversed-inequality-for-timeout-of-retrying-event.patch +Patch6432: backport-udev-certainly-restart-event-for-previously-locked-device.patch +Patch6433: backport-udev-drop-unnecessary-calls-of-event_queue_start.patch +Patch6434: backport-timedatectl-fix-a-memory-leak.patch +Patch6435: backport-core-slice-make-slice_freezer_action-return-0-if-fre.patch +Patch6436: backport-core-unit-fix-use-after-free.patch +Patch6437: backport-shared-json-fix-memory-leak-on-failed-normalization.patch +Patch6438: backport-core-timer-fix-memleak.patch +Patch6439: backport-core-timer-fix-potential-use-after-free.patch +Patch6440: backport-units-remove-the-restart-limit-on-the-modprobe-.serv.patch +Patch6441: backport-udev-cdrom_id-check-last-track-info.patch +Patch6442: backport-manager-reformat-boolean-expression-in-unit_is_prist.patch +Patch6443: backport-manager-allow-transient-units-to-have-drop-ins.patch +Patch6444: backport-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch +Patch6445: backport-TEST-15-add-test-for-transient-units-with-drop-ins.patch +Patch6446: backport-TEST-15-add-one-more-test-for-drop-in-precedence.patch +Patch6447: backport-sd-event-always-initialize-sd_event.perturb.patch +Patch6448: backport-sd-event-fix-error-handling.patch +Patch6449: backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch +Patch6450: backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch +Patch6451: backport-core-device-drop-unnecessary-condition.patch +Patch6452: backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch +Patch6453: backport-test-cover-initrd-sysroot-transition-in-TEST-24.patch +Patch6454: backport-test-generate-a-custom-initrd-for-TEST-24-if-INITRD-.patch +Patch6455: backport-test-store-the-key-on-a-separate-device.patch +Patch6456: backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch +Patch6457: backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch +Patch6458: backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch +Patch6459: backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch +Patch6460: backport-core-device-update-comment.patch +Patch6461: backport-core-device-also-serialize-deserialize-device-syspat.patch +Patch6462: backport-core-device-verify-device-syspath-on-switching-root.patch +Patch6463: backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch +Patch6464: backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch +Patch6465: backport-sysext-refuse-empty-release-ID-to-avoid-triggering-a.patch Patch9001: update-rtc-with-system-clock-when-shutdown.patch Patch9002: udev-add-actions-while-rename-netif-failed.patch @@ -1922,6 +1981,12 @@ %{_libdir}/security/pam_systemd.so %changelog +* Thu Jun 15 2023 hongjinghao <hongjinghao@huawei.com> - 249-52 +- backport: sync patches from systemd community + +* Mon Jun 12 2023 chenjiayi <chenjiayi22@huawei.com> - 249-51 +- backport upstream patches to fix event loss when the whole disk is locked + * Thu Jun 8 2023 licunlong <licunlong1@huawei.com> - 249-50 - set the cpuset.cpus/mems of machine.slice to all by default
View file
_service:tar_scm:Retry-to-handle-the-uevent-when-worker-is-terminated.patch
Changed
@@ -5,32 +5,32 @@ When processing uevent events fails, retry it. --- - src/udev/udevd.c | 41 ++++++++++++++++++++++++++++++++++++----- - 1 file changed, 36 insertions(+), 5 deletions(-) + src/udev/udevd.c | 35 +++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c -index eb94ed3..5b743ad 100644 +index 75e2086..023fe55 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c -@@ -70,6 +70,7 @@ +@@ -69,6 +69,7 @@ #include "version.h" #define WORKER_NUM_MAX 2048U +#define UEVENT_MAX_RETRY_TIMES 3 + #define EVENT_RETRY_INTERVAL_USEC (200 * USEC_PER_MSEC) + #define EVENT_RETRY_TIMEOUT_USEC (3 * USEC_PER_MINUTE) - static bool arg_debug = false; - static int arg_daemonize = false; -@@ -114,6 +115,7 @@ typedef struct Event { +@@ -123,6 +124,7 @@ typedef struct Event { Manager *manager; Worker *worker; EventState state; + int retry; sd_device *dev; - sd_device *dev_kernel; /* clone of originally received device */ -@@ -148,6 +150,32 @@ typedef struct Worker { - typedef struct WorkerMessage { - } WorkerMessage; + +@@ -166,6 +168,32 @@ typedef enum EventResult { + _EVENT_RESULT_INVALID = -EINVAL, + } EventResult; +static bool event_retry(Event *event) { + if (!event) @@ -58,36 +58,30 @@ + return true; +} + - static void event_free(Event *event) { + static Event *event_free(Event *event) { if (!event) - return; -@@ -638,6 +666,7 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { - .dev_kernel = TAKE_PTR(clone), + return NULL; +@@ -1118,6 +1146,7 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { .seqnum = seqnum, + .action = action, .state = EVENT_QUEUED, + .retry = UEVENT_MAX_RETRY_TIMES, }; if (LIST_IS_EMPTY(manager->events)) { -@@ -1314,11 +1343,13 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi +@@ -1547,8 +1576,10 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi device_delete_db(worker->event->dev); device_tag_index(worker->event->dev, NULL, false); -- if (manager->monitor) { -- /* forward kernel event without amending it */ -- r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel); -- if (r < 0) -- log_device_error_errno(worker->event->dev_kernel, r, "Failed to send back device to kernel: %m"); +- /* Forward kernel event to libudev listeners */ +- device_broadcast(manager->monitor, worker->event->dev); + if (event_retry(worker->event) == false) { -+ if (manager->monitor) { -+ /* forward kernel event without amending it */ -+ r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel); -+ if (r < 0) -+ log_device_error_errno(worker->event->dev_kernel, r, "Failed to send back device to kernel: %m"); -+ } - } ++ /* Forward kernel event to libudev listeners */ ++ device_broadcast(manager->monitor, worker->event->dev); ++ } } + worker_free(worker); -- -2.23.0 +2.33.0
View file
_service:tar_scm:backport-TEST-15-add-one-more-test-for-drop-in-precedence.patch
Added
@@ -0,0 +1,66 @@ +From c3fa408dcc03bb6dbd11f180540fb9e684893c39 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Sun, 16 Oct 2022 21:52:43 +0200 +Subject: PATCH TEST-15: add one more test for drop-in precedence + +--- + test/units/testsuite-15.sh | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh +index ed6d5f838d..079c8b290e 100755 +--- a/test/units/testsuite-15.sh ++++ b/test/units/testsuite-15.sh +@@ -282,6 +282,41 @@ MemoryMax=1000000001 + clear_services a-b-c.slice + } + ++test_transient_service_dropins () { ++ echo "Testing dropins for a transient service..." ++ echo "*** test transient service drop-ins" ++ ++ mkdir -p /etc/systemd/system/service.d ++ mkdir -p /etc/systemd/system/a-.service.d ++ mkdir -p /etc/systemd/system/a-b-.service.d ++ mkdir -p /etc/systemd/system/a-b-c.service.d ++ ++ echo -e 'Service\nStandardInputText=aaa' >/etc/systemd/system/service.d/drop1.conf ++ echo -e 'Service\nStandardInputText=bbb' >/etc/systemd/system/a-.service.d/drop2.conf ++ echo -e 'Service\nStandardInputText=ccc' >/etc/systemd/system/a-b-.service.d/drop3.conf ++ echo -e 'Service\nStandardInputText=ddd' >/etc/systemd/system/a-b-c.service.d/drop4.conf ++ ++ # There's no fragment yet, so this fails ++ systemctl cat a-b-c.service && exit 1 ++ ++ # xxx → eHh4Cg== ++ systemd-run -u a-b-c.service -p StandardInputData=eHh4Cg== sleep infinity ++ ++ data=$(systemctl show -P StandardInputData a-b-c.service) ++ # xxx\naaa\n\bbb\nccc\nddd\n → eHh4… ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ # Do a reload and check again ++ systemctl daemon-reload ++ data=$(systemctl show -P StandardInputData a-b-c.service) ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ clear_services a-b-c.service ++ rm /etc/systemd/system/service.d/drop1.conf \ ++ /etc/systemd/system/a-.service.d/drop2.conf \ ++ /etc/systemd/system/a-b-.service.d/drop3.conf ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -621,6 +656,7 @@ test_linked_units + test_template_alias + test_hierarchical_service_dropins + test_hierarchical_slice_dropins ++test_transient_service_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins +-- +2.33.0 +
View file
_service:tar_scm:backport-TEST-15-add-test-for-transient-units-with-drop-ins.patch
Added
@@ -0,0 +1,108 @@ +From 6854434cfb5dda10c07d95835c38b75e5e71c2b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Sun, 16 Oct 2022 14:02:45 +0200 +Subject: PATCH TEST-15: add test for transient units with drop-ins + +We want to test four things: +- that the transient units are successfully started when drop-ins exist +- that the transient setings override the defaults +- the drop-ins override the transient settings (the same as for a normal unit) +- that things are the same before and after a reload + +To make things more fun, we start and stop units in two different ways: via +systemctl and via a direct busctl invocation. This gives us a bit more coverage +of different code paths. +--- + test/units/testsuite-15.sh | 62 ++++++++++++++++++++++++++++++++++---- + 1 file changed, 56 insertions(+), 6 deletions(-) + +diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh +index 8b44d76982..ed6d5f838d 100755 +--- a/test/units/testsuite-15.sh ++++ b/test/units/testsuite-15.sh +@@ -181,19 +181,40 @@ test_hierarchical_service_dropins () { + echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c +- check_ko a-b-c ExecCondition "/bin/echo service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ check_ko a-b-c ExecCondition "echo service.d" ++ check_ko a-b-c ExecCondition "echo a-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-c.service.d" + + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + mkdir -p /usr/lib/systemd/system/$dropin + echo " + Service +-ExecCondition=/bin/echo $dropin ++ExecCondition=echo $dropin + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload +- check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ check_ok a-b-c ExecCondition "echo $dropin" ++ ++ # Check that we can start a transient service in presence of the drop-ins ++ systemd-run -u a-b-c2.service -p Description='sleepy' sleep infinity ++ ++ # The transient setting replaces the default ++ check_ok a-b-c2.service Description "sleepy" ++ ++ # The override takes precedence for ExecCondition ++ # (except the last iteration when it only applies to the other service) ++ if "$dropin" != "a-b-c.service.d" ; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c2.service Description "sleepy" ++ if "$dropin" != "a-b-c.service.d" ; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ systemctl stop a-b-c2.service + done + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + rm -rf /usr/lib/systemd/system/$dropin +@@ -218,6 +239,35 @@ MemoryMax=1000000000 + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload + check_ok a-b-c.slice MemoryMax "1000000000" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StartTransientUnit 'ssa(sv)a(sa(sv))' \ ++ 'a-b-c.slice' 'replace' \ ++ 2 \ ++ 'Description' s 'slice too' \ ++ 'MemoryMax' t 1000000002 \ ++ 0 ++ ++ # The override takes precedence for MemoryMax ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ # The transient setting replaces the default ++ check_ok a-b-c.slice Description "slice too" ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ check_ok a-b-c.slice Description "slice too" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StopUnit 'ss' \ ++ 'a-b-c.slice' 'replace' ++ + rm /usr/lib/systemd/system/$dropin/override.conf + done + +-- +2.33.0 +
View file
_service:tar_scm:backport-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch
Added
@@ -0,0 +1,78 @@ +From f80c874af376052b6b81f47cbbc43d7fecd98cd6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Sun, 16 Oct 2022 12:54:34 +0200 +Subject: PATCH TEST-15: also test hierarchical drop-ins for slices + +Slices are worth testing too, because they don't need a fragment path so they +behave slightly differently than service units. I'm making this a separate +patch from the actual tests that I wanted to add later because it's complex +enough on its own. +--- + test/units/testsuite-15.sh | 37 ++++++++++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) + +diff --git a/test/units/testsuite-15.sh b/test/units/testsuite-15.sh +index c3784e2..8bae64d 100755 +--- a/test/units/testsuite-15.sh ++++ b/test/units/testsuite-15.sh +@@ -174,8 +174,8 @@ test_template_alias() { + clear_services test15-a@ test15-b@ + } + +-test_hierarchical_dropins () { +- echo "Testing hierarchical dropins..." ++test_hierarchical_service_dropins () { ++ echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c + check_ko a-b-c ExecCondition "/bin/echo service.d" +@@ -199,6 +199,36 @@ ExecCondition=/bin/echo $dropin + clear_services a-b-c + } + ++test_hierarchical_slice_dropins () { ++ echo "Testing hierarchical slice dropins..." ++ echo "*** test slice.d/ top level drop-in" ++ # Slice units don't even need a fragment, so we test the defaults here ++ check_ok a-b-c.slice Description "Slice /a/b/c" ++ check_ok a-b-c.slice MemoryMax "infinity" ++ ++ # Test drop-ins ++ for dropin in slice.d a-.slice.d a-b-.slice.d a-b-c.slice.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++Slice ++MemoryMax=1000000000 ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ rm /usr/lib/systemd/system/$dropin/override.conf ++ done ++ ++ # Test unit with a fragment ++ echo " ++Slice ++MemoryMax=1000000001 ++ " >/usr/lib/systemd/system/a-b-c.slice ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000001" ++ ++ clear_services a-b-c.slice ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -517,7 +547,8 @@ test_invalid_dropins () { + test_basic_dropins + test_linked_units + test_template_alias +-test_hierarchical_dropins ++test_hierarchical_service_dropins ++test_hierarchical_slice_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-also-serialize-deserialize-device-syspat.patch
Added
@@ -0,0 +1,65 @@ +From 1ea74fca3a3c737f3901bc10d879b7830b3528bf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 25 Oct 2022 21:41:17 +0900 +Subject: PATCH core/device: also serialize/deserialize device syspath + +The field will be used in later commits. +--- + src/core/device.c | 13 ++++++++++++- + src/core/device.h | 2 +- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 9d694aa..26a6d1f 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -114,6 +114,7 @@ static void device_done(Unit *u) { + assert(d); + + device_unset_sysfs(d); ++ d->deserialized_sysfs = mfree(d->deserialized_sysfs); + d->wants_property = strv_free(d->wants_property); + } + +@@ -295,6 +296,9 @@ static int device_serialize(Unit *u, FILE *f, FDSet *fds) { + assert(f); + assert(fds); + ++ if (d->sysfs) ++ (void) serialize_item(f, "sysfs", d->sysfs); ++ + (void) serialize_item(f, "state", device_state_to_string(d->state)); + + if (device_found_to_string_many(d->found, &s) >= 0) +@@ -312,7 +316,14 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value, + assert(value); + assert(fds); + +- if (streq(key, "state")) { ++ if (streq(key, "sysfs")) { ++ if (!d->deserialized_sysfs) { ++ d->deserialized_sysfs = strdup(value); ++ if (!d->deserialized_sysfs) ++ log_oom_debug(); ++ } ++ ++ } else if (streq(key, "state")) { + DeviceState state; + + state = device_state_from_string(value); +diff --git a/src/core/device.h b/src/core/device.h +index dfe8a13..99bf134 100644 +--- a/src/core/device.h ++++ b/src/core/device.h +@@ -20,7 +20,7 @@ typedef enum DeviceFound { + struct Device { + Unit meta; + +- char *sysfs; ++ char *sysfs, *deserialized_sysfs; + + /* In order to be able to distinguish dependencies on different device nodes we might end up creating multiple + * devices for the same sysfs path. We chain them up here. */ +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-device_coldplug-don-t-set-DEVICE_DEAD.patch
Added
@@ -0,0 +1,43 @@ +From cf1ac0cfe44997747b0f857a1d0b67cea1298272 Mon Sep 17 00:00:00 2001 +From: Martin Wilck <mwilck@suse.com> +Date: Wed, 25 May 2022 12:01:00 +0200 +Subject: PATCH core/device: device_coldplug(): don't set DEVICE_DEAD + +dm-crypt device units generated by systemd-cryptsetup-generator +habe BindsTo= dependencies on their backend devices. The dm-crypt +devices have the db_persist flag set, and thus survive the udev db +cleanup while switching root. But backend devices usually don't survive. +These devices are neither mounted nor used for swap, thus they will +seen as DEVICE_NOT_FOUND after switching root. + +The BindsTo dependency will cause systemd to schedule a stop +job for the dm-crypt device, breaking boot: + + 68.929457 krypton systemd1: systemd-cryptsetup@cr_root.service: Unit is stopped because bound to inactive unit dev-disk-by\x2duuid-3bf91f73\x2d1ee8\x2d4cfc\x2d9048\x2d93ba349b786d.device. + 68.945660 krypton systemd1: systemd-cryptsetup@cr_root.service: Trying to enqueue job systemd-cryptsetup@cr_root.service/stop/replace + 69.473459 krypton systemd1: systemd-cryptsetup@cr_root.service: Installed new job systemd-cryptsetup@cr_root.service/stop as 343 + +Avoid this by not setting the state of the backend devices to +DEVICE_DEAD. + +Fixes the LUKS setup issue reported in #23429. +--- + src/core/device.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 4c261ec554..8728630523 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -205,8 +205,6 @@ static int device_coldplug(Unit *u) { + found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ + if (state == DEVICE_PLUGGED) + state = DEVICE_TENTATIVE; /* downgrade state */ +- if (found == DEVICE_NOT_FOUND) +- state = DEVICE_DEAD; /* If nobody sees the device, downgrade more */ + } + + if (d->found == found && d->state == state) +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-do-not-downgrade-device-state-if-it-is-a.patch
Added
@@ -0,0 +1,36 @@ +From 4fc69e8a0949c2537019466f839d9b7aee5628c9 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 20 May 2022 10:25:12 +0200 +Subject: PATCH core/device: do not downgrade device state if it is already + enumerated + +On switching root, a device may have a persistent databse. In that case, +Device.enumerated_found may have DEVICE_FOUND_UDEV flag, and it is not +necessary to downgrade the Device.deserialized_found and +Device.deserialized_state. Otherwise, the state of the device unit may +be changed plugged -> dead -> plugged, if the device has not been mounted. + +Fixes #23429. + +mwilck: cherry-picked from #23437 +--- + src/core/device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 8728630523..fcde8a420e 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -201,7 +201,8 @@ static int device_coldplug(Unit *u) { + * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by + * device_catchup() or uevents. */ + +- if (!m->honor_device_enumeration && !MANAGER_IS_USER(m)) { ++ if (!m->honor_device_enumeration && !MANAGER_IS_USER(m) && ++ !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) { + found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ + if (state == DEVICE_PLUGGED) + state = DEVICE_TENTATIVE; /* downgrade state */ +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-drop-unnecessary-condition.patch
Added
@@ -0,0 +1,28 @@ +From f33bc87989a87475ed41bc9cd715c4cbb18ee389 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 1 May 2022 21:42:43 +0900 +Subject: PATCH core/device: drop unnecessary condition + +--- + src/core/device.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 44425cda3c..934676287e 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -179,10 +179,7 @@ static void device_catchup(Unit *u) { + + assert(d); + +- /* Second, let's update the state with the enumerated state if it's different */ +- if (d->enumerated_found == d->found) +- return; +- ++ /* Second, let's update the state with the enumerated state */ + device_update_found_one(d, d->enumerated_found, DEVICE_FOUND_MASK); + } + +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-ignore-DEVICE_FOUND_UDEV-bit-on-switchin.patch
Added
@@ -0,0 +1,117 @@ +From 75d7b5989f99125e52d5c0e5656fa1cd0fae2405 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 29 Apr 2022 20:29:11 +0900 +Subject: PATCH core/device: ignore DEVICE_FOUND_UDEV bit on switching root + +The issue #12953 is caused by the following: +On switching root, +- deserialized_found == DEVICE_FOUND_UDEV | DEVICE_FOUND_MOUNT, +- deserialized_state == DEVICE_PLUGGED, +- enumerated_found == DEVICE_FOUND_MOUNT, +On switching root, most devices are not found by the enumeration process. +Hence, the device state is set to plugged by device_coldplug(), and then +changed to the dead state in device_catchup(). So the corresponding +mount point is unmounted. Later when the device is processed by udevd, it +will be changed to plugged state again. + +The issue #23208 is caused by the fact that generated udev database in +initramfs and the main system are often different. + +So, the two issues have the same root; we should not honor +DEVICE_FOUND_UDEV bit in the deserialized_found on switching root. + +This partially reverts c6e892bc0eebe1d42c282bd2d8bae149fbeba85f. + +Fixes #12953 and #23208. +Replaces #23215. + +Co-authored-by: Martin Wilck <mwilck@suse.com> +--- + src/core/device.c | 59 +++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 49 insertions(+), 10 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 934676287e..1a4563a3d9 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -163,14 +163,57 @@ static int device_coldplug(Unit *u) { + assert(d->state == DEVICE_DEAD); + + /* First, let's put the deserialized state and found mask into effect, if we have it. */ ++ if (d->deserialized_state < 0) ++ return 0; ++ ++ Manager *m = u->manager; ++ DeviceFound found = d->deserialized_found; ++ DeviceState state = d->deserialized_state; ++ ++ /* On initial boot, switch-root, reload, reexecute, the following happen: ++ * 1. MANAGER_IS_RUNNING() == false ++ * 2. enumerate devices: manager_enumerate() -> device_enumerate() ++ * Device.enumerated_found is set. ++ * 3. deserialize devices: manager_deserialize() -> device_deserialize() ++ * Device.deserialize_state and Device.deserialized_found are set. ++ * 4. coldplug devices: manager_coldplug() -> device_coldplug() ++ * deserialized properties are copied to the main properties. ++ * 5. MANAGER_IS_RUNNING() == true: manager_ready() ++ * 6. catchup devices: manager_catchup() -> device_catchup() ++ * Device.enumerated_found is applied to Device.found, and state is updated based on that. ++ * ++ * Notes: ++ * - On initial boot, no udev database exists. Hence, no devices are enumerated in the step 2. ++ * Also, there is no deserialized device. Device units are (a) generated based on dependencies of ++ * other units, or (b) generated when uevents are received. ++ * ++ * - On switch-root, the udev databse may be cleared, except for devices with sticky bit, i.e. ++ * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general, ++ * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be ++ * ignored, as udev rules in initramfs and the main system are often different. If the deserialized ++ * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE (or DEVICE_DEAD if nobody ++ * sees the device). Unlike the other starting mode, Manager.honor_device_enumeration == false ++ * (maybe, it is better to rename the flag) when device_coldplug() and device_catchup() are called. ++ * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd ++ * will (re-)process all devices, and the Device.found and Device.state will be adjusted. ++ * ++ * - On reload or reexecute, we can trust enumerated_found, deserialized_found, and deserialized_state. ++ * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by ++ * device_catchup() or uevents. */ ++ ++ if (!m->honor_device_enumeration && !MANAGER_IS_USER(m)) { ++ found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ ++ if (state == DEVICE_PLUGGED) ++ state = DEVICE_TENTATIVE; /* downgrade state */ ++ if (found == DEVICE_NOT_FOUND) ++ state = DEVICE_DEAD; /* If nobody sees the device, downgrade more */ ++ } + +- if (d->deserialized_state < 0 || +- (d->deserialized_state == d->state && +- d->deserialized_found == d->found)) ++ if (d->found == found && d->state == state) + return 0; + +- d->found = d->deserialized_found; +- device_set_state(d, d->deserialized_state); ++ d->found = found; ++ device_set_state(d, state); + return 0; + } + +@@ -644,13 +687,9 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no + } + + static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) { +- Manager *m; +- + assert(d); + +- m = UNIT(d)->manager; +- +- if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) { ++ if (MANAGER_IS_RUNNING(UNIT(d)->manager)) { + DeviceFound n, previous; + + /* When we are already running, then apply the new mask right-away, and trigger state changes +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-update-comment.patch
Added
@@ -0,0 +1,64 @@ +From 54a4d71509c0f3401aa576346754a0781795214a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 25 Oct 2022 21:40:21 +0900 +Subject: PATCH core/device: update comment + +--- + src/core/device.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 0bca0ff..9d694aa 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -172,7 +172,7 @@ static int device_coldplug(Unit *u) { + * 1. MANAGER_IS_RUNNING() == false + * 2. enumerate devices: manager_enumerate() -> device_enumerate() + * Device.enumerated_found is set. +- * 3. deserialize devices: manager_deserialize() -> device_deserialize() ++ * 3. deserialize devices: manager_deserialize() -> device_deserialize_item() + * Device.deserialize_state and Device.deserialized_found are set. + * 4. coldplug devices: manager_coldplug() -> device_coldplug() + * deserialized properties are copied to the main properties. +@@ -187,22 +187,27 @@ static int device_coldplug(Unit *u) { + * + * - On switch-root, the udev databse may be cleared, except for devices with sticky bit, i.e. + * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general, +- * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be +- * ignored, as udev rules in initramfs and the main system are often different. If the deserialized +- * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE. Unlike the other starting +- * mode, MANAGER_IS_SWITCHING_ROOT() is true when device_coldplug() and device_catchup() are called. +- * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd +- * will (re-)process all devices, and the Device.found and Device.state will be adjusted. ++ * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the ++ * Device.deserialized_found must be ignored, as udev rules in initrd and the main system are often ++ * different. If the deserialized state is DEVICE_PLUGGED, we need to downgrade it to ++ * DEVICE_TENTATIVE. Unlike the other starting mode, MANAGER_IS_SWITCHING_ROOT() is true when ++ * device_coldplug() and device_catchup() are called. Hence, let's conditionalize the operations by ++ * using the flag. After switch-root, systemd-udevd will (re-)process all devices, and the ++ * Device.found and Device.state will be adjusted. + * +- * - On reload or reexecute, we can trust enumerated_found, deserialized_found, and deserialized_state. +- * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by +- * device_catchup() or uevents. */ ++ * - On reload or reexecute, we can trust Device.enumerated_found, Device.deserialized_found, and ++ * Device.deserialized_state. Of course, deserialized parameters may be outdated, but the unit ++ * state can be adjusted later by device_catchup() or uevents. */ + + if (MANAGER_IS_SWITCHING_ROOT(m) && + !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) { +- found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ ++ /* The device has not been enumerated. On switching-root, such situation is natural. See the ++ * above comment. To prevent problematic state transition active → dead → active, let's ++ * drop the DEVICE_FOUND_UDEV flag and downgrade state to DEVICE_TENTATIVE(activating). See ++ * issue #12953 and #23208. */ ++ found &= ~DEVICE_FOUND_UDEV; + if (state == DEVICE_PLUGGED) +- state = DEVICE_TENTATIVE; /* downgrade state */ ++ state = DEVICE_TENTATIVE; + } + + if (d->found == found && d->state == state) +-- +2.33.0 +
View file
_service:tar_scm:backport-core-device-verify-device-syspath-on-switching-root.patch
Added
@@ -0,0 +1,42 @@ +From b6c86ae28149c4abb2f0bd6acab13153382da9e7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Wed, 26 Oct 2022 01:18:05 +0900 +Subject: PATCH core/device: verify device syspath on switching root + +Otherwise, if a device is removed while switching root, then the +corresponding .device unit will never go to inactive state. + +This replaces the code dropped by cf1ac0cfe44997747b0f857a1d0b67cea1298272. + +Fixes #25106. +--- + src/core/device.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/core/device.c b/src/core/device.c +index 7e354b2b4a..6e07f2745b 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -305,6 +305,19 @@ static int device_coldplug(Unit *u) { + found &= ~DEVICE_FOUND_UDEV; + if (state == DEVICE_PLUGGED) + state = DEVICE_TENTATIVE; ++ ++ /* Also check the validity of the device syspath. Without this check, if the device was ++ * removed while switching root, it would never go to inactive state, as both Device.found ++ * and Device.enumerated_found do not have the DEVICE_FOUND_UDEV flag, so device_catchup() in ++ * device_update_found_one() does nothing in most cases. See issue #25106. Note that the ++ * syspath field is only serialized when systemd is sufficiently new and the device has been ++ * already processed by udevd. */ ++ if (d->deserialized_sysfs) { ++ _cleanup_(sd_device_unrefp) sd_device *dev = NULL; ++ ++ if (sd_device_new_from_syspath(&dev, d->deserialized_sysfs) < 0) ++ state = DEVICE_DEAD; ++ } + } + + if (d->found == found && d->state == state) +-- +2.33.0 +
View file
_service:tar_scm:backport-core-introduce-MANAGER_IS_SWITCHING_ROOT-helper-func.patch
Added
@@ -0,0 +1,91 @@ +From d35fe8c0afaa55441608cb7bbfa4af908e1ea8e3 Mon Sep 17 00:00:00 2001 +From: Franck Bui <fbui@suse.com> +Date: Thu, 5 May 2022 08:49:56 +0200 +Subject: PATCH core: introduce MANAGER_IS_SWITCHING_ROOT() helper function + +Will be used by the following commit. +--- + src/core/main.c | 3 +++ + src/core/manager.c | 6 ++++++ + src/core/manager.h | 6 ++++++ + 3 files changed, 15 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index 1213ad6..df4fb9d 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1981,6 +1981,8 @@ static int invoke_main_loop( + return 0; + + case MANAGER_SWITCH_ROOT: ++ manager_set_switching_root(m, true); ++ + if (!m->switch_root_init) { + r = prepare_reexecute(m, &arg_serialization, ret_fds, true); + if (r < 0) { +@@ -2899,6 +2901,7 @@ int main(int argc, char *argv) { + set_manager_defaults(m); + set_manager_settings(m); + manager_set_first_boot(m, first_boot); ++ manager_set_switching_root(m, arg_switched_root); + + /* Remember whether we should queue the default job */ + queue_default_job = !arg_serialization || arg_switched_root; +diff --git a/src/core/manager.c b/src/core/manager.c +index abc63a7..d3b7fc5 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -756,6 +756,10 @@ static int manager_setup_sigchld_event_source(Manager *m) { + return 0; + } + ++void manager_set_switching_root(Manager *m, bool switching_root) { ++ m->switching_root = MANAGER_IS_SYSTEM(m) && switching_root; ++} ++ + int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **_m) { + _cleanup_(manager_freep) Manager *m = NULL; + const char *e; +@@ -1799,6 +1803,8 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + + manager_ready(m); + ++ manager_set_switching_root(m, false); ++ + return 0; + } + +diff --git a/src/core/manager.h b/src/core/manager.h +index 14a80b3..453706c 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -400,6 +400,9 @@ struct Manager { + char *switch_root; + char *switch_root_init; + ++ /* This is true before and after switching root. */ ++ bool switching_root; ++ + /* This maps all possible path prefixes to the units needing + * them. It's a hashmap with a path string as key and a Set as + * value where Unit objects are contained. */ +@@ -461,6 +464,8 @@ static inline usec_t manager_default_timeout_abort_usec(Manager *m) { + /* The objective is set to OK as soon as we enter the main loop, and set otherwise as soon as we are done with it */ + #define MANAGER_IS_RUNNING(m) ((m)->objective == MANAGER_OK) + ++#define MANAGER_IS_SWITCHING_ROOT(m) ((m)->switching_root) ++ + #define MANAGER_IS_TEST_RUN(m) ((m)->test_run_flags != 0) + + int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **m); +@@ -525,6 +530,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason); + void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason); + + void manager_set_first_boot(Manager *m, bool b); ++void manager_set_switching_root(Manager *m, bool switching_root); + + void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5); + +-- +2.33.0 +
View file
_service:tar_scm:backport-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch
Added
@@ -0,0 +1,91 @@ +From fe432460c2ecbd3dd7f0fa16278b9d4ca57a0de3 Mon Sep 17 00:00:00 2001 +From: Mike Yuan <me@yhndnzj.com> +Date: Wed, 10 May 2023 13:54:15 +0800 +Subject: PATCH core: only refuse Type=dbus service enqueuing if dbus has + stop job + +Follow-up for #27579 + +In #27579 we refused all StartUnit requests for Type=dbus units +if dbus is not running, which means if dbus is manually stopped, +user can't use systemctl to start Type=dbus units again, which +is incorrect. + +The only culprit that leads to the cancellation of the whole +transaction mentioned in #26799 is job type conflict on dbus. +So let's relax the restriction and only refuse job enqueuing +if dbus has a stop job. + +To summarize, the case we want to avoid is: + +1. dbus has a stop job installed +2. StartUnit/ActivationRequest is received +3. Type=dbus service gets started, which has Requires=dbus.socket +4. dbus is pulled in again, resulting in job type conflict + +What we can support is: + +1. dbus is already stopped +2. StartUnit is received (possibly through systemctl, i.e. on private bus) +3. Type=dbus service gets started, which will wait for dbus to start +4. dbus is started again, thus the job for Type=dbus service + +Replaces #27590 +Fixes #27588 +--- + src/core/dbus-unit.c | 32 +++++++++++++++++++++++++------- + 1 file changed, 25 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index 295e271..24e4d25 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -1849,6 +1849,7 @@ int bus_unit_queue_job( + sd_bus_error *error) { + + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; ++ const char *dbus_unit; + int r; + + assert(message); +@@ -1879,13 +1880,30 @@ int bus_unit_queue_job( + (type == JOB_STOP && u->refuse_manual_stop) || + (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) || + (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start)) +- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id); +- +- /* dbus-broker issues StartUnit for activation requests, so let's apply the same check +- * used in signal_activation_request(). */ +- if (type == JOB_START && u->type == UNIT_SERVICE && +- SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager)) +- return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running."); ++ return sd_bus_error_setf(error, ++ BUS_ERROR_ONLY_BY_DEPENDENCY, ++ "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", ++ u->id); ++ ++ /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically ++ * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start ++ * job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting ++ * job enqueuing early. ++ * ++ * Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending() ++ * here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl ++ * to start Type=dbus services even when dbus is inactive. */ ++ if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS) ++ FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) { ++ Unit *dbus; ++ ++ dbus = manager_get_unit(u->manager, dbus_unit); ++ if (dbus && unit_stop_pending(dbus)) ++ return sd_bus_error_setf(error, ++ BUS_ERROR_SHUTTING_DOWN, ++ "Operation for unit %s refused, D-Bus is shutting down.", ++ u->id); ++ } + + r = sd_bus_message_new_method_return(message, &reply); + if (r < 0) +-- +2.33.0 +
View file
_service:tar_scm:backport-core-refuse-dbus-activation-if-dbus-is-not-running.patch
Added
@@ -0,0 +1,43 @@ +From 53964fd26b4a01191609ffc064aa8ccccd28e377 Mon Sep 17 00:00:00 2001 +From: Mike Yuan <me@yhndnzj.com> +Date: Tue, 9 May 2023 00:07:45 +0800 +Subject: PATCH core: refuse dbus activation if dbus is not running + +dbus-broker issues StartUnit directly for activation requests, +so let's add a check on bus state in bus_unit_queue_job to refuse +that if dbus is not running. + +Replaces #27570 +Closes #26799 +--- + src/core/dbus-unit.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index c42ae5e..295e271 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -21,6 +21,7 @@ + #include "path-util.h" + #include "process-util.h" + #include "selinux-access.h" ++#include "service.h" + #include "signal-util.h" + #include "special.h" + #include "string-table.h" +@@ -1880,6 +1881,12 @@ int bus_unit_queue_job( + (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start)) + return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id); + ++ /* dbus-broker issues StartUnit for activation requests, so let's apply the same check ++ * used in signal_activation_request(). */ ++ if (type == JOB_START && u->type == UNIT_SERVICE && ++ SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager)) ++ return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running."); ++ + r = sd_bus_message_new_method_return(message, &reply); + if (r < 0) + return r; +-- +2.33.0 +
View file
_service:tar_scm:backport-core-replace-m-honor_device_enumeration-with-MANAGER.patch
Added
@@ -0,0 +1,113 @@ +From 7870de03c52982290f9b8ae11eb4d89db66f4be3 Mon Sep 17 00:00:00 2001 +From: Franck Bui <fbui@suse.com> +Date: Thu, 5 May 2022 11:11:57 +0200 +Subject: PATCH core: replace m->honor_device_enumeration with + MANAGER_IS_SWITCHING_ROOT() + +--- + src/core/device.c | 7 +++---- + src/core/manager.c | 21 +-------------------- + src/core/manager.h | 2 -- + 3 files changed, 4 insertions(+), 26 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index d9669e3..0bca0ff 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -189,9 +189,8 @@ static int device_coldplug(Unit *u) { + * OPTIONS="db_persist". Hence, almost no devices are enumerated in the step 2. However, in general, + * we have several serialized devices. So, DEVICE_FOUND_UDEV bit in the deserialized_found must be + * ignored, as udev rules in initramfs and the main system are often different. If the deserialized +- * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE (or DEVICE_DEAD if nobody +- * sees the device). Unlike the other starting mode, Manager.honor_device_enumeration == false +- * (maybe, it is better to rename the flag) when device_coldplug() and device_catchup() are called. ++ * state is DEVICE_PLUGGED, we need to downgrade it to DEVICE_TENTATIVE. Unlike the other starting ++ * mode, MANAGER_IS_SWITCHING_ROOT() is true when device_coldplug() and device_catchup() are called. + * Hence, let's conditionalize the operations by using the flag. After switch-root, systemd-udevd + * will (re-)process all devices, and the Device.found and Device.state will be adjusted. + * +@@ -199,7 +198,7 @@ static int device_coldplug(Unit *u) { + * Of course, deserialized parameters may be outdated, but the unit state can be adjusted later by + * device_catchup() or uevents. */ + +- if (!m->honor_device_enumeration && !MANAGER_IS_USER(m) && ++ if (MANAGER_IS_SWITCHING_ROOT(m) && + !FLAGS_SET(d->enumerated_found, DEVICE_FOUND_UDEV)) { + found &= ~DEVICE_FOUND_UDEV; /* ignore DEVICE_FOUND_UDEV bit */ + if (state == DEVICE_PLUGGED) +diff --git a/src/core/manager.c b/src/core/manager.c +index 5ed7191..91e9b2a 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1689,8 +1689,6 @@ static void manager_ready(Manager *m) { + + /* Let's finally catch up with any changes that took place while we were reloading/reexecing */ + manager_catchup(m); +- +- m->honor_device_enumeration = true; + } + + static Manager* manager_reloading_start(Manager *m) { +@@ -3259,9 +3257,6 @@ int manager_serialize( + (void) serialize_bool(f, "taint-logged", m->taint_logged); + (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs); + +- /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */ +- (void) serialize_bool(f, "honor-device-enumeration", !switching_root); +- + if (m->show_status_overridden != _SHOW_STATUS_INVALID) + (void) serialize_item(f, "show-status-overridden", + show_status_to_string(m->show_status_overridden)); +@@ -3635,15 +3630,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + else + m->service_watchdogs = b; + +- } else if ((val = startswith(l, "honor-device-enumeration="))) { +- int b; +- +- b = parse_boolean(val); +- if (b < 0) +- log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val); +- else +- m->honor_device_enumeration = b; +- + } else if ((val = startswith(l, "show-status-overridden="))) { + ShowStatus s; + +@@ -3767,7 +3753,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + + if (q < _MANAGER_TIMESTAMP_MAX) /* found it */ + (void) deserialize_dual_timestamp(val, m->timestamps + q); +- else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */ ++ else if (!STARTSWITH_SET(l, "kdbus-fd=", "honor-device-enumeration=")) /* ignore deprecated values */ + log_notice("Unknown serialization item '%s', ignoring.", l); + } + } +@@ -3860,11 +3846,6 @@ int manager_reload(Manager *m) { + assert(m->n_reloading > 0); + m->n_reloading--; + +- /* On manager reloading, device tag data should exists, thus, we should honor the results of device +- * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So, +- * let's always set the flag here for safety. */ +- m->honor_device_enumeration = true; +- + manager_ready(m); + + m->send_reloading_done = true; +diff --git a/src/core/manager.h b/src/core/manager.h +index 453706c..67c204f 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -442,8 +442,6 @@ struct Manager { + unsigned sigchldgen; + unsigned notifygen; + +- bool honor_device_enumeration; +- + VarlinkServer *varlink_server; + /* Only systemd-oomd should be using this to subscribe to changes in ManagedOOM settings */ + Varlink *managed_oom_varlink_request; +-- +2.33.0 +
View file
_service:tar_scm:backport-core-slice-make-slice_freezer_action-return-0-if-fre.patch
Added
@@ -0,0 +1,47 @@ +From 4617bad0a3b5d8026243cb4e72a5cae25ca106f0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 6 May 2022 14:01:22 +0900 +Subject: PATCH core/slice: make slice_freezer_action() return 0 if freezing + state is unchanged + +Fixes #23278. + +(cherry picked from commit d171e72e7afa11b238ba20758384d223b0c76e39) +--- + src/core/slice.c | 6 +----- + src/core/unit.c | 2 ++ + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/core/slice.c b/src/core/slice.c +index 2e43c00119..c453aa033e 100644 +--- a/src/core/slice.c ++++ b/src/core/slice.c +@@ -389,11 +389,7 @@ static int slice_freezer_action(Unit *s, FreezerAction action) { + return r; + } + +- r = unit_cgroup_freezer_action(s, action); +- if (r < 0) +- return r; +- +- return 1; ++ return unit_cgroup_freezer_action(s, action); + } + + static int slice_freeze(Unit *s) { +diff --git a/src/core/unit.c b/src/core/unit.c +index b233aca28c..3bceba1317 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5831,6 +5831,8 @@ static int unit_freezer_action(Unit *u, FreezerAction action) { + if (r <= 0) + return r; + ++ assert(IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING)); ++ + return 1; + } + +-- +2.33.0 +
View file
_service:tar_scm:backport-core-timer-fix-memleak.patch
Added
@@ -0,0 +1,61 @@ +From 82362b16ac842fc38340d21ebf39b259c5edaed3 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 10 May 2022 14:09:24 +0900 +Subject: PATCH core/timer: fix memleak + +Fixes #23326. + +(cherry picked from commit d3ab7b8078944db28bc621f43dd942a3c878fffb) +--- + src/core/timer.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index a13b864741..0dc49dd46b 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -135,6 +135,7 @@ static int timer_add_trigger_dependencies(Timer *t) { + } + + static int timer_setup_persistent(Timer *t) { ++ _cleanup_free_ char *stamp_path = NULL; + int r; + + assert(t); +@@ -148,13 +149,13 @@ static int timer_setup_persistent(Timer *t) { + if (r < 0) + return r; + +- t->stamp_path = strjoin("/var/lib/systemd/timers/stamp-", UNIT(t)->id); ++ stamp_path = strjoin("/var/lib/systemd/timers/stamp-", UNIT(t)->id); + } else { + const char *e; + + e = getenv("XDG_DATA_HOME"); + if (e) +- t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id); ++ stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id); + else { + + _cleanup_free_ char *h = NULL; +@@ -163,14 +164,14 @@ static int timer_setup_persistent(Timer *t) { + if (r < 0) + return log_unit_error_errno(UNIT(t), r, "Failed to determine home directory: %m"); + +- t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id); ++ stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id); + } + } + +- if (!t->stamp_path) ++ if (!stamp_path) + return log_oom(); + +- return 0; ++ return free_and_replace(t->stamp_path, stamp_path); + } + + static uint64_t timer_get_fixed_delay_hash(Timer *t) { +-- +2.33.0 +
View file
_service:tar_scm:backport-core-timer-fix-potential-use-after-free.patch
Added
@@ -0,0 +1,26 @@ +From 38410e13ec9b1b67364f2f0af3b27d9e934bcd96 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 10 May 2022 14:10:17 +0900 +Subject: PATCH core/timer: fix potential use-after-free + +(cherry picked from commit 756491af392a99c4286d876b0041535e50df80ad) +--- + src/core/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index 0dc49dd46b..b439802bc2 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -68,7 +68,7 @@ static void timer_done(Unit *u) { + t->monotonic_event_source = sd_event_source_disable_unref(t->monotonic_event_source); + t->realtime_event_source = sd_event_source_disable_unref(t->realtime_event_source); + +- free(t->stamp_path); ++ t->stamp_path = mfree(t->stamp_path); + } + + static int timer_verify(Timer *t) { +-- +2.33.0 +
View file
_service:tar_scm:backport-core-unit-fix-use-after-free.patch
Added
@@ -0,0 +1,30 @@ +From 3daae8785764304a65892ddcd548b6aae16c9463 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 9 May 2022 00:56:05 +0900 +Subject: PATCH core/unit: fix use-after-free + +Fixes #23312. + +(cherry picked from commit 734582830b58e000a26e18807ea277c18778573c) +--- + src/core/unit.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index af6cf097fc..b233aca28c 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -671,8 +671,8 @@ Unit* unit_free(Unit *u) { + + unit_dequeue_rewatch_pids(u); + +- sd_bus_slot_unref(u->match_bus_slot); +- sd_bus_track_unref(u->bus_track); ++ u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); ++ u->bus_track = sd_bus_track_unref(u->bus_track); + u->deserialized_refs = strv_free(u->deserialized_refs); + u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); + +-- +2.33.0 +
View file
_service:tar_scm:backport-errno-util-add-ERRNO_IS_DEVICE_ABSENT-macro.patch
Added
@@ -0,0 +1,75 @@ +From 3f2ada89f3a277625390bf6789ccd4e7aba08743 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering <lennart@poettering.net> +Date: Thu, 24 Mar 2022 13:50:50 +0100 +Subject: PATCH errno-util: add ERRNO_IS_DEVICE_ABSENT() macro + +Inspired by: https://github.com/systemd/systemd/pull/22717#discussion_r834254495 + +Reference:https://github.com/systemd/systemd/commit/3f2ada89f3a277625390bf6789ccd4e7aba08743 +Conflict:discard change on homework-luks.c + +--- + src/basic/errno-util.h | 10 +++++++++- + src/rfkill/rfkill.c | 2 +- + src/udev/udev-builtin-btrfs.c | 3 ++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h +index 09abf0b7512d..648de50eb497 100644 +--- a/src/basic/errno-util.h ++++ b/src/basic/errno-util.h +@@ -138,10 +138,18 @@ static inline bool ERRNO_IS_PRIVILEGE(int r) { + EPERM); + } + +-/* Three difference errors for "not enough disk space" */ ++/* Three different errors for "not enough disk space" */ + static inline bool ERRNO_IS_DISK_SPACE(int r) { + return IN_SET(abs(r), + ENOSPC, + EDQUOT, + EFBIG); + } ++ ++/* Three different errors for "this device does not quite exist" */ ++static inline bool ERRNO_IS_DEVICE_ABSENT(int r) { ++ return IN_SET(abs(r), ++ ENODEV, ++ ENXIO, ++ ENOENT); ++} +diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c +index 656afa06ac8b..a833771d97f2 100644 +--- a/src/rfkill/rfkill.c ++++ b/src/rfkill/rfkill.c +@@ -80,7 +80,7 @@ static int find_device( + + r = sd_device_new_from_subsystem_sysname(&device, "rfkill", sysname); + if (r < 0) +- return log_full_errno(IN_SET(r, -ENOENT, -ENXIO, -ENODEV) ? LOG_DEBUG : LOG_ERR, r, ++ return log_full_errno(ERRNO_IS_DEVICE_ABSENT(r) ? LOG_DEBUG : LOG_ERR, r, + "Failed to open device '%s': %m", sysname); + + r = sd_device_get_sysattr_value(device, "name", &name); +diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c +index a0093cb42347..f9d4f1dd4ef4 100644 +--- a/src/udev/udev-builtin-btrfs.c ++++ b/src/udev/udev-builtin-btrfs.c +@@ -6,6 +6,7 @@ + #include <sys/ioctl.h> + + #include "device-util.h" ++#include "errno-util.h" + #include "fd-util.h" + #include "string-util.h" + #include "strxcpyx.h" +@@ -22,7 +23,7 @@ static int builtin_btrfs(sd_device *dev, sd_netlink **rtnl, int argc, char *argv + + fd = open("/dev/btrfs-control", O_RDWR|O_CLOEXEC); + if (fd < 0) { +- if (IN_SET(errno, ENOENT, ENXIO, ENODEV)) { ++ if (ERRNO_IS_DEVICE_ABSENT(errno)) { + /* Driver not installed? Then we aren't ready. This is useful in initrds that lack + * btrfs.ko. After the host transition (where btrfs.ko will hopefully become + * available) the device can be retriggered and will then be considered ready. */ +
View file
_service:tar_scm:backport-event-util-introduce-event_reset_time_relative.patch
Added
@@ -0,0 +1,87 @@ +From 52c3bc708fb6a3eb68a3cac780b49192818bd409 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 13 Nov 2021 10:33:08 +0900 +Subject: PATCH event-util: introduce event_reset_time_relative() + +Reference:https://github.com/systemd/systemd/commit/52c3bc708fb6a3eb68a3cac780b49192818bd409 +Conflict:NA + +--- + src/libsystemd/sd-event/event-util.c | 24 ++++++++++++++++++++++++ + src/libsystemd/sd-event/event-util.h | 26 ++++++++++++++++++++++---- + 2 files changed, 46 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/event-util.c b/src/libsystemd/sd-event/event-util.c +index 132796f..0e53406 100644 +--- a/src/libsystemd/sd-event/event-util.c ++++ b/src/libsystemd/sd-event/event-util.c +@@ -84,6 +84,30 @@ int event_reset_time( + return created; + } + ++int event_reset_time_relative( ++ sd_event *e, ++ sd_event_source **s, ++ clockid_t clock, ++ uint64_t usec, ++ uint64_t accuracy, ++ sd_event_time_handler_t callback, ++ void *userdata, ++ int64_t priority, ++ const char *description, ++ bool force_reset) { ++ ++ usec_t usec_now; ++ int r; ++ ++ assert(e); ++ ++ r = sd_event_now(e, clock, &usec_now); ++ if (r < 0) ++ return log_debug_errno(r, "sd-event: Failed to get the current time: %m"); ++ ++ return event_reset_time(e, s, clock, usec_add(usec_now, usec), accuracy, callback, userdata, priority, description, force_reset); ++} ++ + int event_source_disable(sd_event_source *s) { + if (!s) + return 0; +diff --git a/src/libsystemd/sd-event/event-util.h b/src/libsystemd/sd-event/event-util.h +index c8f97bc..64a4199 100644 +--- a/src/libsystemd/sd-event/event-util.h ++++ b/src/libsystemd/sd-event/event-util.h +@@ -5,9 +5,27 @@ + + #include "sd-event.h" + +-int event_reset_time(sd_event *e, sd_event_source **s, +- clockid_t clock, uint64_t usec, uint64_t accuracy, +- sd_event_time_handler_t callback, void *userdata, +- int64_t priority, const char *description, bool force_reset); ++int event_reset_time( ++ sd_event *e, ++ sd_event_source **s, ++ clockid_t clock, ++ uint64_t usec, ++ uint64_t accuracy, ++ sd_event_time_handler_t callback, ++ void *userdata, ++ int64_t priority, ++ const char *description, ++ bool force_reset); ++int event_reset_time_relative( ++ sd_event *e, ++ sd_event_source **s, ++ clockid_t clock, ++ uint64_t usec, ++ uint64_t accuracy, ++ sd_event_time_handler_t callback, ++ void *userdata, ++ int64_t priority, ++ const char *description, ++ bool force_reset); + int event_source_disable(sd_event_source *s); + int event_source_is_enabled(sd_event_source *s); +-- +2.33.0 +
View file
_service:tar_scm:backport-list-introduce-LIST_FOREACH_BACKWARDS-macro-and-drop.patch
Added
@@ -0,0 +1,102 @@ +From bd335c961fed6982e5ad8c2322414ff33a46e92e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 16:12:06 +0900 +Subject: PATCH list: introduce LIST_FOREACH_BACKWARDS() macro and drop + LIST_FOREACH_AFTER/BEFORE() + +Reference:https://github.com/systemd/systemd/commit/bd335c961fed6982e5ad8c2322414ff33a46e92e +Conflict:NA + +--- + src/basic/list.h | 7 ++----- + src/core/device.c | 8 ++++---- + src/core/swap.c | 4 ++-- + src/udev/udev-rules.c | 2 +- + 4 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/src/basic/list.h b/src/basic/list.h +index 256b718..e488fff 100644 +--- a/src/basic/list.h ++++ b/src/basic/list.h +@@ -142,11 +142,8 @@ + #define LIST_FOREACH_SAFE(name,i,n,head) \ + for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) + +-#define LIST_FOREACH_BEFORE(name,i,p) \ +- for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev) +- +-#define LIST_FOREACH_AFTER(name,i,p) \ +- for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) ++#define LIST_FOREACH_BACKWARDS(name,i,p) \ ++ for ((i) = (p); (i); (i) = (i)->name##_prev) + + /* Iterate through all the members of the list p is included in, but skip over p */ + #define LIST_FOREACH_OTHERS(name,i,p) \ +diff --git a/src/core/device.c b/src/core/device.c +index c24bc12..06270e7 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -785,11 +785,11 @@ static Unit *device_following(Unit *u) { + return NULL; + + /* Make everybody follow the unit that's named after the sysfs path */ +- LIST_FOREACH_AFTER(same_sysfs, other, d) ++ LIST_FOREACH(same_sysfs, other, d->same_sysfs_next) + if (startswith(UNIT(other)->id, "sys-")) + return UNIT(other); + +- LIST_FOREACH_BEFORE(same_sysfs, other, d) { ++ LIST_FOREACH_BACKWARDS(same_sysfs, other, d->same_sysfs_prev) { + if (startswith(UNIT(other)->id, "sys-")) + return UNIT(other); + +@@ -816,13 +816,13 @@ static int device_following_set(Unit *u, Set **_set) { + if (!set) + return -ENOMEM; + +- LIST_FOREACH_AFTER(same_sysfs, other, d) { ++ LIST_FOREACH(same_sysfs, other, d->same_sysfs_next) { + r = set_put(set, other); + if (r < 0) + return r; + } + +- LIST_FOREACH_BEFORE(same_sysfs, other, d) { ++ LIST_FOREACH_BACKWARDS(same_sysfs, other, d->same_sysfs_prev) { + r = set_put(set, other); + if (r < 0) + return r; +diff --git a/src/core/swap.c b/src/core/swap.c +index 83e77d2..7a9628e 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -1323,11 +1323,11 @@ static Unit *swap_following(Unit *u) { + if (streq_ptr(s->what, s->devnode)) + return NULL; + +- LIST_FOREACH_AFTER(same_devnode, other, s) ++ LIST_FOREACH(same_devnode, other, s->same_devnode_next) + if (streq_ptr(other->what, other->devnode)) + return UNIT(other); + +- LIST_FOREACH_BEFORE(same_devnode, other, s) { ++ LIST_FOREACH_BACKWARDS(same_devnode, other, s->same_devnode_prev) { + if (streq_ptr(other->what, other->devnode)) + return UNIT(other); + +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index bf997fc..5e8dad2 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -1154,7 +1154,7 @@ static void rule_resolve_goto(UdevRuleFile *rule_file) { + if (!FLAGS_SET(line->type, LINE_HAS_GOTO)) + continue; + +- LIST_FOREACH_AFTER(rule_lines, i, line) ++ LIST_FOREACH(rule_lines, i, line->rule_lines_next) + if (streq_ptr(i->label, line->goto_label)) { + line->goto_line = i; + break; +-- +2.33.0 +
View file
_service:tar_scm:backport-manager-allow-transient-units-to-have-drop-ins.patch
Added
@@ -0,0 +1,89 @@ +From 1a09fb995e0e84c2a5f40945248644b174863c6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Fri, 14 Oct 2022 15:02:20 +0200 +Subject: PATCH manager: allow transient units to have drop-ins + +In https://github.com/containers/podman/issues/16107, starting of a transient +slice unit fails because there's a "global" drop-in +/usr/lib/systemd/user/slice.d/10-oomd-per-slice-defaults.conf (provided by +systemd-oomd-defaults package to install some default oomd policy). This means +that the unit_is_pristine() check fails and starting of the unit is forbidden. + +It seems pretty clear to me that dropins at any other level then the unit +should be ignored in this check: we now have multiple layers of drop-ins +(for each level of the cgroup path, and also "global" ones for a specific +unit type). If we install a "global" drop-in, we wouldn't be able to start +any transient units of that type, which seems undesired. + +In principle we could reject dropins at the unit level, but I don't think that +is useful. The whole reason for drop-ins is that they are "add ons", and there +isn't any particular reason to disallow them for transient units. It would also +make things harder to implement and describe: one place for drop-ins is good, +but another is bad. (And as a corner case: for instanciated units, a drop-in +in the template would be acceptable, but a instance-specific drop-in bad?) + +Thus, $subject. + +While at it, adjust the message. All the conditions in unit_is_pristine() +essentially mean that it wasn't loaded (e.g. it might be in an error state), +and that it doesn't have a fragment path (now that drop-ins are acceptable). +If there's a job for it, it necessarilly must have been loaded. If it is +merged into another unit, it also was loaded and found to be an alias. +Based on the discussion in the bugs, it seems that the current message +is far from obvious ;) + +Fixes https://github.com/containers/podman/issues/16107, +https://bugzilla.redhat.com/show_bug.cgi?id=2133792. + +(cherry picked from commit 1f83244641f13a9cb28fdac7e3c17c5446242dfb) +(cherry picked from commit 98a45608c4bf5aa1ba9b603ac2e5730f13659d88) +--- + src/core/dbus-manager.c | 2 +- + src/core/unit.c | 14 ++++++++------ + 2 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 1a3098ceb1..9a2a5531c6 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -901,7 +901,7 @@ static int transient_unit_from_message( + + if (!unit_is_pristine(u)) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, +- "Unit %s already exists.", name); ++ "Unit %s was already loaded or has a fragment file.", name); + + /* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +diff --git a/src/core/unit.c b/src/core/unit.c +index a7b3208432..60e4e42d2f 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4806,16 +4806,18 @@ int unit_fail_if_noncanonical(Unit *u, const char* where) { + bool unit_is_pristine(Unit *u) { + assert(u); + +- /* Check if the unit already exists or is already around, +- * in a number of different ways. Note that to cater for unit +- * types such as slice, we are generally fine with units that +- * are marked UNIT_LOADED even though nothing was actually +- * loaded, as those unit types don't require a file on disk. */ ++ /* Check if the unit already exists or is already around, in a number of different ways. Note that to ++ * cater for unit types such as slice, we are generally fine with units that are marked UNIT_LOADED ++ * even though nothing was actually loaded, as those unit types don't require a file on disk. ++ * ++ * Note that we don't check for drop-ins here, because we allow drop-ins for transient units ++ * identically to non-transient units, both unit-specific and hierarchical. E.g. for a-b-c.service: ++ * service.d/….conf, a-.service.d/….conf, a-b-.service.d/….conf, a-b-c.service.d/….conf. ++ */ + + return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && + !u->fragment_path && + !u->source_path && +- strv_isempty(u->dropin_paths) && + !u->job && + !u->merged_into; + } +-- +2.33.0 +
View file
_service:tar_scm:backport-manager-reformat-boolean-expression-in-unit_is_prist.patch
Added
@@ -0,0 +1,40 @@ +From b146a7345b69de16e88347acadb3783ffeeaad9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Fri, 14 Oct 2022 14:40:24 +0200 +Subject: PATCH manager: reformat boolean expression in unit_is_pristine() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Not not IN_SET(…) is just too much for my poor brain. Let's invert +the expression to make it easier to undertand. +--- + src/core/unit.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index d6bea2080f..5016114cb4 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4850,12 +4850,12 @@ bool unit_is_pristine(Unit *u) { + * are marked UNIT_LOADED even though nothing was actually + * loaded, as those unit types don't require a file on disk. */ + +- return !(!IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) || +- u->fragment_path || +- u->source_path || +- !strv_isempty(u->dropin_paths) || +- u->job || +- u->merged_into); ++ return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && ++ !u->fragment_path && ++ !u->source_path && ++ strv_isempty(u->dropin_paths) && ++ !u->job && ++ !u->merged_into; + } + + pid_t unit_control_pid(Unit *u) { +-- +2.33.0 +
View file
_service:tar_scm:backport-sd-event-always-initialize-sd_event.perturb.patch
Added
@@ -0,0 +1,59 @@ +From f1a8b69808777aff37c036fd94a0275873d12407 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 23 Feb 2023 07:31:01 +0900 +Subject: PATCH sd-event: always initialize sd_event.perturb + +If the boot ID cannot be obtained, let's first fallback to the machine +ID, and if still cannot, then let's use 0. +Otherwise, no timer event source cannot be triggered. + +Fixes #26549. + +(cherry picked from commit 6d2326e036ceed30f9ccdb0266713c10a44dcf6c) +(cherry picked from commit 58c821af607b61738b7b72ad1452e70f648689a6) +(cherry picked from commit 78976199b2e016600c3f7cf8f39747c9ef6c853b) +(cherry picked from commit ac04d804c30f519918866fb4eeb3bc4a9cbadd43) +--- + src/libsystemd/sd-event/sd-event.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 89accdce00..37565b17be 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1126,22 +1126,21 @@ _public_ int sd_event_add_io( + } + + static void initialize_perturb(sd_event *e) { +- sd_id128_t bootid = {}; ++ sd_id128_t id = {}; + +- /* When we sleep for longer, we try to realign the wakeup to +- the same time within each minute/second/250ms, so that +- events all across the system can be coalesced into a single +- CPU wakeup. However, let's take some system-specific +- randomness for this value, so that in a network of systems +- with synced clocks timer events are distributed a +- bit. Here, we calculate a perturbation usec offset from the +- boot ID. */ ++ /* When we sleep for longer, we try to realign the wakeup to the same time within each ++ * minute/second/250ms, so that events all across the system can be coalesced into a single CPU ++ * wakeup. However, let's take some system-specific randomness for this value, so that in a network ++ * of systems with synced clocks timer events are distributed a bit. Here, we calculate a ++ * perturbation usec offset from the boot ID (or machine ID if failed, e.g. /proc is not mounted). */ + + if (_likely_(e->perturb != USEC_INFINITY)) + return; + +- if (sd_id128_get_boot(&bootid) >= 0) +- e->perturb = (bootid.qwords0 ^ bootid.qwords1) % USEC_PER_MINUTE; ++ if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) > 0) ++ e->perturb = (id.qwords0 ^ id.qwords1) % USEC_PER_MINUTE; ++ else ++ e->perturb = 0; /* This is a super early process without /proc and /etc ?? */ + } + + static int event_setup_timer_fd( +-- +2.33.0 +
View file
_service:tar_scm:backport-sd-event-fix-error-handling.patch
Added
@@ -0,0 +1,31 @@ +From 056fbe84ef67168adcaf41baa37de1b712f6fb74 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 23 Feb 2023 07:31:01 +0900 +Subject: PATCH sd-event: fix error handling + +Follow-up for 6d2326e036ceed30f9ccdb0266713c10a44dcf6c. + +(cherry picked from commit 1912f790fee9e0182acd77b77496f500094a140d) +(cherry picked from commit a719c2ec2f410f8b979cec04dcdac9af470ee52b) +(cherry picked from commit dd6561ff3e12314d41954b7ea8e3627101931a18) +(cherry picked from commit 8be4af42044969bc268b32ffe9570cee733fecf6) +--- + src/libsystemd/sd-event/sd-event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 37565b17be..df4d9037ac 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1137,7 +1137,7 @@ static void initialize_perturb(sd_event *e) { + if (_likely_(e->perturb != USEC_INFINITY)) + return; + +- if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) > 0) ++ if (sd_id128_get_boot(&id) >= 0 || sd_id128_get_machine(&id) >= 0) + e->perturb = (id.qwords0 ^ id.qwords1) % USEC_PER_MINUTE; + else + e->perturb = 0; /* This is a super early process without /proc and /etc ?? */ +-- +2.33.0 +
View file
_service:tar_scm:backport-sd-lldp-use-memcpy_safe-as-the-buffer-size-may-be-ze.patch
Added
@@ -0,0 +1,27 @@ +From 5e069e405a73ff5a406598436fe21d6dabbb281c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Wed, 4 May 2022 16:05:04 +0900 +Subject: PATCH sd-lldp: use memcpy_safe() as the buffer size may be zero + +(cherry picked from commit 87bd4b79e692f384c2190c9b3824df4853333018) +--- + src/libsystemd-network/lldp-neighbor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c +index 372bc2ef93..bc98235ce1 100644 +--- a/src/libsystemd-network/lldp-neighbor.c ++++ b/src/libsystemd-network/lldp-neighbor.c +@@ -652,7 +652,8 @@ int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t ra + if (!n) + return -ENOMEM; + +- memcpy(LLDP_NEIGHBOR_RAW(n), raw, raw_size); ++ memcpy_safe(LLDP_NEIGHBOR_RAW(n), raw, raw_size); ++ + r = lldp_neighbor_parse(n); + if (r < 0) + return r; +-- +2.33.0 +
View file
_service:tar_scm:backport-shared-bootspec-avoid-crashing-on-config-without-a-v.patch
Added
@@ -0,0 +1,31 @@ +From 412b89a6e8055f2c8c9db4b6b847f081e00461ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Fri, 6 May 2022 17:36:47 +0200 +Subject: PATCH shared/bootspec: avoid crashing on config without a value + +(cherry picked from commit b6bd2562ebb01b48cdb55a970d9daa1799b59876) +--- + src/shared/bootspec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c +index 0076092c2a..9e2b2899bd 100644 +--- a/src/shared/bootspec.c ++++ b/src/shared/bootspec.c +@@ -124,6 +124,13 @@ static int boot_entry_load( + continue; + } + ++ if (isempty(p)) { ++ /* Some fields can reasonably have an empty value. In other cases warn. */ ++ if (!STR_IN_SET(field, "options", "devicetree-overlay")) ++ log_warning("%s:%u: Field %s without value", tmp.path, line, field); ++ continue; ++ } ++ + if (streq(field, "title")) + r = free_and_strdup(&tmp.title, p); + else if (streq(field, "version")) +-- +2.33.0 +
View file
_service:tar_scm:backport-shared-json-fix-memory-leak-on-failed-normalization.patch
Added
@@ -0,0 +1,34 @@ +From c1dbf637d7f5588a19b5d9ea812fee2e68a6dcfa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Mon, 9 May 2022 14:28:36 +0200 +Subject: PATCH shared/json: fix memory leak on failed normalization + +We need to increase the counter immediately after taking the ref, +otherwise we may not unref it properly if we fail before incrementing. + +(cherry picked from commit 7e4be6a5845f983a299932d4ccb2c4349cf8dd52) +--- + src/shared/json.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/shared/json.c b/src/shared/json.c +index dff95eda26..711aa36c87 100644 +--- a/src/shared/json.c ++++ b/src/shared/json.c +@@ -4680,10 +4680,11 @@ int json_variant_normalize(JsonVariant **v) { + if (!a) + return -ENOMEM; + +- for (i = 0; i < m; i++) { ++ for (i = 0; i < m; ) { + ai = json_variant_ref(json_variant_by_index(*v, i)); ++ i++; + +- r = json_variant_normalize(a + i); ++ r = json_variant_normalize(&ai-1); + if (r < 0) + goto finish; + } +-- +2.33.0 +
View file
_service:tar_scm:backport-sysext-refuse-empty-release-ID-to-avoid-triggering-a.patch
Added
@@ -0,0 +1,31 @@ +From 6100e1dded709f681aca0cf913095e2591a54e33 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 21 May 2022 03:03:21 +0900 +Subject: PATCH sysext: refuse empty release ID to avoid triggering assertion + +Otherwise, the assertion in extension_release_validate() will be +triggered. + +(cherry picked from commit 30e29edf4c0bb025aa7dc03c415b727fddf996ac) +--- + src/sysext/sysext.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c +index 60789e0f2c..4245bf1760 100644 +--- a/src/sysext/sysext.c ++++ b/src/sysext/sysext.c +@@ -483,6 +483,10 @@ static int merge_subprocess(Hashmap *images, const char *workspace) { + "SYSEXT_LEVEL", &host_os_release_sysext_level); + if (r < 0) + return log_error_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(arg_root)); ++ if (isempty(host_os_release_id)) ++ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), ++ "'ID' field not found or empty in 'os-release' data of OS tree '%s': %m", ++ empty_to_root(arg_root)); + + /* Let's now mount all images */ + HASHMAP_FOREACH(img, images) { +-- +2.33.0 +
View file
_service:tar_scm:backport-test-cover-initrd-sysroot-transition-in-TEST-24.patch
Added
@@ -0,0 +1,113 @@ +From 1fb7f8e15e19fbe61230b70203b0c35fca54f0a0 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal <frantisek@sumsal.cz> +Date: Wed, 25 May 2022 17:39:14 +0200 +Subject: PATCH test: cover initrd->sysroot transition in TEST-24 + +This should cover cases regarding devices with `OPTIONS+="db_persist"` +during initrd->sysroot transition. + +See: + * https://github.com/systemd/systemd/issues/23429 + * https://github.com/systemd/systemd/pull/23218 + * https://github.com/systemd/systemd/pull/23489 + * https://bugzilla.redhat.com/show_bug.cgi?id=2087225 +--- + test/TEST-24-CRYPTSETUP/test.sh | 61 ++++++++++++++++----------------- + 1 file changed, 29 insertions(+), 32 deletions(-) + +diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh +index 2c13126..a52848b 100755 +--- a/test/TEST-24-CRYPTSETUP/test.sh ++++ b/test/TEST-24-CRYPTSETUP/test.sh +@@ -9,6 +9,13 @@ TEST_FORCE_NEWIMAGE=1 + # shellcheck source=test/test-functions + . "${TEST_BASE_DIR:?}/test-functions" + ++PART_UUID="deadbeef-dead-dead-beef-000000000000" ++DM_NAME="test24_varcrypt" ++# Mount the keyfile only in initrd (hence rd.luks.key), since it resides on ++# the rootfs and we would get a (harmless) error when trying to mount it after ++# switching root (since rootfs is already mounted) ++KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME rd.luks.key=$PART_UUID=/etc/varkey:LABEL=systemd_boot" ++ + check_result_qemu() { + local ret=1 + +@@ -16,12 +23,12 @@ check_result_qemu() { + -e "${initdir:?}/testok" && ret=0 + -f "$initdir/failed" && cp -a "$initdir/failed" "${TESTDIR:?}" + +- cryptsetup luksOpen "${LOOPDEV:?}p2" varcrypt <"$TESTDIR/keyfile" +- mount /dev/mapper/varcrypt "$initdir/var" ++ cryptsetup luksOpen "${LOOPDEV:?}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile" ++ mount "/dev/mapper/$DM_NAME" "$initdir/var" + save_journal "$initdir/var/log/journal" + _umount_dir "$initdir/var" + _umount_dir "$initdir" +- cryptsetup luksClose /dev/mapper/varcrypt ++ cryptsetup luksClose "/dev/mapper/$DM_NAME" + + -f "$TESTDIR/failed" && cat "$TESTDIR/failed" + echo "${JOURNAL_LIST:-No journals were saved}" +@@ -34,39 +41,29 @@ test_create_image() { + create_empty_image_rootdir + + echo -n test >"${TESTDIR:?}/keyfile" +- cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile" +- cryptsetup luksOpen "${LOOPDEV}p2" varcrypt <"$TESTDIR/keyfile" +- mkfs.ext4 -L var /dev/mapper/varcrypt ++ cryptsetup -q luksFormat --uuid="$PART_UUID" --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile" ++ cryptsetup luksOpen "${LOOPDEV}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile" ++ mkfs.ext4 -L var "/dev/mapper/$DM_NAME" + mkdir -p "${initdir:?}/var" +- mount /dev/mapper/varcrypt "$initdir/var" +- +- # Create what will eventually be our root filesystem onto an overlay +- ( +- LOG_LEVEL=5 +- # shellcheck source=/dev/null +- source <(udevadm info --export --query=env --name=/dev/mapper/varcrypt) +- # shellcheck source=/dev/null +- source <(udevadm info --export --query=env --name="${LOOPDEV}p2") +- +- setup_basic_environment +- mask_supporting_services +- +- install_dmevent +- generate_module_dependencies +- cat >"$initdir/etc/crypttab" <<EOF +-$DM_NAME UUID=$ID_FS_UUID /etc/varkey +-EOF +- echo -n test >"$initdir/etc/varkey" +- ddebug <"$initdir/etc/crypttab" ++ mount "/dev/mapper/$DM_NAME" "$initdir/var" ++ ++ LOG_LEVEL=5 ++ ++ setup_basic_environment ++ mask_supporting_services ++ ++ install_dmevent ++ generate_module_dependencies ++ ++ echo -n test >"$initdir/etc/varkey" + +- cat >>"$initdir/etc/fstab" <<EOF +-/dev/mapper/varcrypt /var ext4 defaults 0 1 ++ cat >>"$initdir/etc/fstab" <<EOF ++/dev/mapper/$DM_NAME /var ext4 defaults 0 1 + EOF + +- # Forward journal messages to the console, so we have something +- # to investigate even if we fail to mount the encrypted /var +- echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf" +- ) ++ # Forward journal messages to the console, so we have something ++ # to investigate even if we fail to mount the encrypted /var ++ echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf" + } + + cleanup_root_var() { +-- +2.33.0 +
View file
_service:tar_scm:backport-test-generate-a-custom-initrd-for-TEST-24-if-INITRD-.patch
Added
@@ -0,0 +1,66 @@ +From b22d90e59438481b421b1eb2449e6efdfb7f2118 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal <frantisek@sumsal.cz> +Date: Thu, 26 May 2022 13:19:11 +0200 +Subject: PATCH test: generate a custom initrd for TEST-24 if $INITRD is + unset + +Co-Authored-By: Yu Watanabe <watanabe.yu+github@gmail.com> +--- + test/TEST-24-CRYPTSETUP/test.sh | 24 ++++++++++++++++++++++++ + test/test-functions | 5 +++++ + 2 files changed, 29 insertions(+) + +diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh +index a52848b..c18f4aa 100755 +--- a/test/TEST-24-CRYPTSETUP/test.sh ++++ b/test/TEST-24-CRYPTSETUP/test.sh +@@ -64,6 +64,30 @@ EOF + # Forward journal messages to the console, so we have something + # to investigate even if we fail to mount the encrypted /var + echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf" ++ ++ # If $INITRD wasn't provided explicitly, generate a custom one with dm-crypt ++ # support ++ if -z "$INITRD" ; then ++ INITRD="${TESTDIR:?}/initrd.img" ++ dinfo "Generating a custom initrd with dm-crypt support in '${INITRD:?}'" ++ ++ if command -v dracut >/dev/null; then ++ dracut --force --verbose --add crypt "$INITRD" ++ elif command -v mkinitcpio >/dev/null; then ++ mkinitcpio --addhooks sd-encrypt --generate "$INITRD" ++ elif command -v mkinitramfs >/dev/null; then ++ # The cryptroot hook is provided by the cryptsetup-initramfs package ++ if ! dpkg-query -s cryptsetup-initramfs; then ++ derror "Missing 'cryptsetup-initramfs' package for dm-crypt support in initrd" ++ return 1 ++ fi ++ ++ mkinitramfs -o "$INITRD" ++ else ++ dfatal "Unrecognized initrd generator, can't continue" ++ return 1 ++ fi ++ fi + } + + cleanup_root_var() { +diff --git a/test/test-functions b/test/test-functions +index bef87ca..0239bbc 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -325,6 +325,11 @@ qemu_min_version() { + # Return 0 if QEMU did run (then you must check the result state/logs for actual + # success), or 1 if QEMU is not available. + run_qemu() { ++ # If the test provided its own initrd, use it (e.g. TEST-24) ++ if -z "$INITRD" && -f "${TESTDIR:?}/initrd.img" ; then ++ INITRD="$TESTDIR/initrd.img" ++ fi ++ + if -f /etc/machine-id ; then + read -r MACHINE_ID </etc/machine-id + -z "$INITRD" && -e "$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/initrd" \ +-- +2.33.0 +
View file
_service:tar_scm:backport-test-store-the-key-on-a-separate-device.patch
Added
@@ -0,0 +1,44 @@ +From 6b70d3cf81088ee9226cd691bbccc4ebf4764065 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal <frantisek@sumsal.cz> +Date: Thu, 26 May 2022 14:52:52 +0200 +Subject: PATCH test: store the key on a separate device + +--- + test/TEST-24-CRYPTSETUP/test.sh | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh +index bdf630d912..b81b811654 100755 +--- a/test/TEST-24-CRYPTSETUP/test.sh ++++ b/test/TEST-24-CRYPTSETUP/test.sh +@@ -12,10 +12,8 @@ TEST_FORCE_NEWIMAGE=1 + + PART_UUID="deadbeef-dead-dead-beef-000000000000" + DM_NAME="test24_varcrypt" +-# Mount the keyfile only in initrd (hence rd.luks.key), since it resides on +-# the rootfs and we would get a (harmless) error when trying to mount it after +-# switching root (since rootfs is already mounted) +-KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME rd.luks.key=$PART_UUID=/etc/varkey:LABEL=systemd_boot" ++KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME luks.key=$PART_UUID=/keyfile:LABEL=varcrypt_keydev" ++QEMU_OPTIONS+=" -drive format=raw,cache=unsafe,file=${STATEDIR:?}/keydev.img" + + check_result_qemu() { + local ret=1 +@@ -57,7 +55,13 @@ test_create_image() { + install_dmevent + generate_module_dependencies + +- echo -n test >"$initdir/etc/varkey" ++ # Create a keydev ++ dd if=/dev/zero of="${STATEDIR:?}/keydev.img" bs=1M count=16 ++ mkfs.ext4 -L varcrypt_keydev "$STATEDIR/keydev.img" ++ mkdir -p "$STATEDIR/keydev" ++ mount "$STATEDIR/keydev.img" "$STATEDIR/keydev" ++ echo -n test >"$STATEDIR/keydev/keyfile" ++ umount "$STATEDIR/keydev" + + cat >>"$initdir/etc/fstab" <<EOF + /dev/mapper/$DM_NAME /var ext4 defaults 0 1 +-- +2.33.0 +
View file
_service:tar_scm:backport-timedatectl-fix-a-memory-leak.patch
Added
@@ -0,0 +1,46 @@ +From 71d2356edffafe8c40797c64f6fb82a8885d1da9 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin <evvers@ya.ru> +Date: Wed, 4 May 2022 11:35:19 +0000 +Subject: PATCH timedatectl: fix a memory leak + +``` +timedatectl list-timezones --no-pager +... +==164329==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 8192 byte(s) in 1 object(s) allocated from: + #0 0x7fe8a74b6f8c in reallocarray (/lib64/libasan.so.6+0xaef8c) + #1 0x7fe8a63485dc in strv_push ../src/basic/strv.c:419 + #2 0x7fe8a6349419 in strv_consume ../src/basic/strv.c:490 + #3 0x7fe8a634958d in strv_extend ../src/basic/strv.c:542 + #4 0x7fe8a643d787 in bus_message_read_strv_extend ../src/libsystemd/sd-bus/bus-message.c:5606 + #5 0x7fe8a643db9d in sd_bus_message_read_strv ../src/libsystemd/sd-bus/bus-message.c:5628 + #6 0x4085fb in list_timezones ../src/timedate/timedatectl.c:314 + #7 0x7fe8a61ef3e1 in dispatch_verb ../src/shared/verbs.c:103 + #8 0x410f91 in timedatectl_main ../src/timedate/timedatectl.c:1025 + #9 0x41111c in run ../src/timedate/timedatectl.c:1043 + #10 0x411242 in main ../src/timedate/timedatectl.c:1046 + #11 0x7fe8a489df1f in __libc_start_call_main (/lib64/libc.so.6+0x40f1f) +``` + +(cherry picked from commit a2e37d52312806b1847800df2358e61276cda052) +--- + src/timedate/timedatectl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c +index 75ca6195da..31909064cf 100644 +--- a/src/timedate/timedatectl.c ++++ b/src/timedate/timedatectl.c +@@ -304,7 +304,7 @@ static int list_timezones(int argc, char **argv, void *userdata) { + sd_bus *bus = userdata; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + int r; +- char** zones; ++ _cleanup_strv_free_ char **zones = NULL; + + r = bus_call_method(bus, bus_timedate, "ListTimezones", &error, &reply, NULL); + if (r < 0) +-- +2.33.0 +
View file
_service:tar_scm:backport-udev-add-usec_add-at-one-more-place.patch
Added
@@ -0,0 +1,28 @@ +From 92fd70addf25d4f301ba43ca3e6ede96d9564295 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 15:41:20 +0900 +Subject: PATCH udev: add usec_add() at one more place + +Reference:https://github.com/systemd/systemd/commit/92fd70addf25d4f301ba43ca3e6ede96d9564295 +Conflict:NA + +--- + src/udev/udevd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 279b409..2179825 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -893,7 +893,7 @@ static int event_queue_start(Manager *manager) { + assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0); + /* check for changed config, every 3 seconds at most */ + if (manager->last_usec == 0 || +- usec - manager->last_usec > 3 * USEC_PER_SEC) { ++ usec > usec_add(manager->last_usec, 3 * USEC_PER_SEC)) { + if (udev_rules_check_timestamp(manager->rules) || + udev_builtin_validate()) + manager_reload(manager); +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-also-rename-struct-udev_ctrl-UdevCtrl.patch
Added
@@ -0,0 +1,350 @@ +From e0d61dac3324abc90f61014a98b1bc5a9a1f60ae Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Wed, 16 Jun 2021 19:18:56 +0900 +Subject: PATCH udev: also rename struct udev_ctrl -> UdevCtrl + +Reference:https://github.com/systemd/systemd/commit/e0d61dac3324abc90f61014a98b1bc5a9a1f60ae +Conflict:NA + +--- + src/udev/udev-ctrl.c | 52 ++++++++++++++++++------------------ + src/udev/udev-ctrl.h | 54 +++++++++++++++++++------------------- + src/udev/udevadm-control.c | 2 +- + src/udev/udevadm-settle.c | 2 +- + src/udev/udevadm-trigger.c | 2 +- + src/udev/udevd.c | 4 +-- + 6 files changed, 58 insertions(+), 58 deletions(-) + +diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c +index 3d563547190c..00279ba3d87d 100644 +--- a/src/udev/udev-ctrl.c ++++ b/src/udev/udev-ctrl.c +@@ -23,14 +23,14 @@ + /* wire protocol magic must match */ + #define UDEV_CTRL_MAGIC 0xdead1dea + +-struct udev_ctrl_msg_wire { ++typedef struct UdevCtrlMessageWire { + char version16; + unsigned magic; +- enum udev_ctrl_msg_type type; +- union udev_ctrl_msg_value value; +-}; ++ UdevCtrlMessageType type; ++ UdevCtrlMessageValue value; ++} UdevCtrlMessageWire; + +-struct udev_ctrl { ++struct UdevCtrl { + unsigned n_ref; + int sock; + int sock_connect; +@@ -47,9 +47,9 @@ struct udev_ctrl { + void *userdata; + }; + +-int udev_ctrl_new_from_fd(struct udev_ctrl **ret, int fd) { ++int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd) { + _cleanup_close_ int sock = -1; +- struct udev_ctrl *uctrl; ++ UdevCtrl *uctrl; + + assert(ret); + +@@ -59,11 +59,11 @@ int udev_ctrl_new_from_fd(struct udev_ctrl **ret, int fd) { + return log_error_errno(errno, "Failed to create socket: %m"); + } + +- uctrl = new(struct udev_ctrl, 1); ++ uctrl = new(UdevCtrl, 1); + if (!uctrl) + return -ENOMEM; + +- *uctrl = (struct udev_ctrl) { ++ *uctrl = (UdevCtrl) { + .n_ref = 1, + .sock = fd >= 0 ? fd : TAKE_FD(sock), + .sock_connect = -1, +@@ -81,7 +81,7 @@ int udev_ctrl_new_from_fd(struct udev_ctrl **ret, int fd) { + return 0; + } + +-int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) { ++int udev_ctrl_enable_receiving(UdevCtrl *uctrl) { + int r; + + assert(uctrl); +@@ -107,7 +107,7 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) { + return 0; + } + +-static void udev_ctrl_disconnect(struct udev_ctrl *uctrl) { ++static void udev_ctrl_disconnect(UdevCtrl *uctrl) { + if (!uctrl) + return; + +@@ -115,7 +115,7 @@ static void udev_ctrl_disconnect(struct udev_ctrl *uctrl) { + uctrl->sock_connect = safe_close(uctrl->sock_connect); + } + +-static struct udev_ctrl *udev_ctrl_free(struct udev_ctrl *uctrl) { ++static UdevCtrl *udev_ctrl_free(UdevCtrl *uctrl) { + assert(uctrl); + + udev_ctrl_disconnect(uctrl); +@@ -127,9 +127,9 @@ static struct udev_ctrl *udev_ctrl_free(struct udev_ctrl *uctrl) { + return mfree(uctrl); + } + +-DEFINE_TRIVIAL_REF_UNREF_FUNC(struct udev_ctrl, udev_ctrl, udev_ctrl_free); ++DEFINE_TRIVIAL_REF_UNREF_FUNC(UdevCtrl, udev_ctrl, udev_ctrl_free); + +-int udev_ctrl_cleanup(struct udev_ctrl *uctrl) { ++int udev_ctrl_cleanup(UdevCtrl *uctrl) { + if (!uctrl) + return 0; + if (uctrl->cleanup_socket) +@@ -137,7 +137,7 @@ int udev_ctrl_cleanup(struct udev_ctrl *uctrl) { + return 0; + } + +-int udev_ctrl_attach_event(struct udev_ctrl *uctrl, sd_event *event) { ++int udev_ctrl_attach_event(UdevCtrl *uctrl, sd_event *event) { + int r; + + assert_return(uctrl, -EINVAL); +@@ -154,25 +154,25 @@ int udev_ctrl_attach_event(struct udev_ctrl *uctrl, sd_event *event) { + return 0; + } + +-sd_event_source *udev_ctrl_get_event_source(struct udev_ctrl *uctrl) { ++sd_event_source *udev_ctrl_get_event_source(UdevCtrl *uctrl) { + assert(uctrl); + + return uctrl->event_source; + } + +-static void udev_ctrl_disconnect_and_listen_again(struct udev_ctrl *uctrl) { ++static void udev_ctrl_disconnect_and_listen_again(UdevCtrl *uctrl) { + udev_ctrl_disconnect(uctrl); + udev_ctrl_unref(uctrl); + (void) sd_event_source_set_enabled(uctrl->event_source, SD_EVENT_ON); + /* We don't return NULL here because uctrl is not freed */ + } + +-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct udev_ctrl*, udev_ctrl_disconnect_and_listen_again, NULL); ++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(UdevCtrl*, udev_ctrl_disconnect_and_listen_again, NULL); + + static int udev_ctrl_connection_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +- _cleanup_(udev_ctrl_disconnect_and_listen_againp) struct udev_ctrl *uctrl = NULL; +- struct udev_ctrl_msg_wire msg_wire; +- struct iovec iov = IOVEC_MAKE(&msg_wire, sizeof(struct udev_ctrl_msg_wire)); ++ _cleanup_(udev_ctrl_disconnect_and_listen_againp) UdevCtrl *uctrl = NULL; ++ UdevCtrlMessageWire msg_wire; ++ struct iovec iov = IOVEC_MAKE(&msg_wire, sizeof(UdevCtrlMessageWire)); + CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; + struct msghdr smsg = { + .msg_iov = &iov, +@@ -235,7 +235,7 @@ static int udev_ctrl_connection_event_handler(sd_event_source *s, int fd, uint32 + } + + static int udev_ctrl_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +- struct udev_ctrl *uctrl = userdata; ++ UdevCtrl *uctrl = userdata; + _cleanup_close_ int sock = -1; + struct ucred ucred; + int r; +@@ -282,7 +282,7 @@ static int udev_ctrl_event_handler(sd_event_source *s, int fd, uint32_t revents, + return 0; + } + +-int udev_ctrl_start(struct udev_ctrl *uctrl, udev_ctrl_handler_t callback, void *userdata) { ++int udev_ctrl_start(UdevCtrl *uctrl, udev_ctrl_handler_t callback, void *userdata) { + int r; + + assert(uctrl); +@@ -309,8 +309,8 @@ int udev_ctrl_start(struct udev_ctrl *uctrl, udev_ctrl_handler_t callback, void + return 0; + } + +-int udev_ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf) { +- struct udev_ctrl_msg_wire ctrl_msg_wire = { ++int udev_ctrl_send(UdevCtrl *uctrl, UdevCtrlMessageType type, int intval, const char *buf) { ++ UdevCtrlMessageWire ctrl_msg_wire = { + .version = "udev-" STRINGIFY(PROJECT_VERSION), + .magic = UDEV_CTRL_MAGIC, + .type = type, +@@ -339,7 +339,7 @@ int udev_ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int in + return 0; + } + +-int udev_ctrl_wait(struct udev_ctrl *uctrl, usec_t timeout) { ++int udev_ctrl_wait(UdevCtrl *uctrl, usec_t timeout) { + _cleanup_(sd_event_source_unrefp) sd_event_source *source_io = NULL, *source_timeout = NULL; + int r; + +diff --git a/src/udev/udev-ctrl.h b/src/udev/udev-ctrl.h +index 680fbf7bff1d..ca80c2aa4e0d 100644 +--- a/src/udev/udev-ctrl.h ++++ b/src/udev/udev-ctrl.h +@@ -6,9 +6,9 @@ + #include "macro.h" + #include "time-util.h" + +-struct udev_ctrl; ++typedef struct UdevCtrl UdevCtrl; + +-enum udev_ctrl_msg_type { ++typedef enum UdevCtrlMessageType { + _UDEV_CTRL_END_MESSAGES, + UDEV_CTRL_SET_LOG_LEVEL, + UDEV_CTRL_STOP_EXEC_QUEUE, +@@ -18,62 +18,62 @@ enum udev_ctrl_msg_type { + UDEV_CTRL_SET_CHILDREN_MAX, + UDEV_CTRL_PING, + UDEV_CTRL_EXIT, +-}; ++} UdevCtrlMessageType; + +-union udev_ctrl_msg_value { ++typedef union UdevCtrlMessageValue { + int intval; + char buf256; +-}; ++} UdevCtrlMessageValue; + +-typedef int (*udev_ctrl_handler_t)(struct udev_ctrl *udev_ctrl, enum udev_ctrl_msg_type type, +- const union udev_ctrl_msg_value *value, void *userdata); ++typedef int (*udev_ctrl_handler_t)(UdevCtrl *udev_ctrl, UdevCtrlMessageType type, ++ const UdevCtrlMessageValue *value, void *userdata); + +-int udev_ctrl_new_from_fd(struct udev_ctrl **ret, int fd); +-static inline int udev_ctrl_new(struct udev_ctrl **ret) { ++int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd); ++static inline int udev_ctrl_new(UdevCtrl **ret) { + return udev_ctrl_new_from_fd(ret, -1); + } + +-int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl); +-struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl); +-struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl); +-int udev_ctrl_cleanup(struct udev_ctrl *uctrl); +-int udev_ctrl_attach_event(struct udev_ctrl *uctrl, sd_event *event); +-int udev_ctrl_start(struct udev_ctrl *uctrl, udev_ctrl_handler_t callback, void *userdata); +-sd_event_source *udev_ctrl_get_event_source(struct udev_ctrl *uctrl); ++int udev_ctrl_enable_receiving(UdevCtrl *uctrl); ++UdevCtrl *udev_ctrl_ref(UdevCtrl *uctrl); ++UdevCtrl *udev_ctrl_unref(UdevCtrl *uctrl); ++int udev_ctrl_cleanup(UdevCtrl *uctrl); ++int udev_ctrl_attach_event(UdevCtrl *uctrl, sd_event *event); ++int udev_ctrl_start(UdevCtrl *uctrl, udev_ctrl_handler_t callback, void *userdata); ++sd_event_source *udev_ctrl_get_event_source(UdevCtrl *uctrl); + +-int udev_ctrl_wait(struct udev_ctrl *uctrl, usec_t timeout); ++int udev_ctrl_wait(UdevCtrl *uctrl, usec_t timeout); + +-int udev_ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf); +-static inline int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority) { ++int udev_ctrl_send(UdevCtrl *uctrl, UdevCtrlMessageType type, int intval, const char *buf); ++static inline int udev_ctrl_send_set_log_level(UdevCtrl *uctrl, int priority) { + return udev_ctrl_send(uctrl, UDEV_CTRL_SET_LOG_LEVEL, priority, NULL); + } + +-static inline int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl) { ++static inline int udev_ctrl_send_stop_exec_queue(UdevCtrl *uctrl) { + return udev_ctrl_send(uctrl, UDEV_CTRL_STOP_EXEC_QUEUE, 0, NULL); + } + +-static inline int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl) { ++static inline int udev_ctrl_send_start_exec_queue(UdevCtrl *uctrl) { + return udev_ctrl_send(uctrl, UDEV_CTRL_START_EXEC_QUEUE, 0, NULL); + } + +-static inline int udev_ctrl_send_reload(struct udev_ctrl *uctrl) { ++static inline int udev_ctrl_send_reload(UdevCtrl *uctrl) { + return udev_ctrl_send(uctrl, UDEV_CTRL_RELOAD, 0, NULL); + } + +-static inline int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key) { ++static inline int udev_ctrl_send_set_env(UdevCtrl *uctrl, const char *key) { + return udev_ctrl_send(uctrl, UDEV_CTRL_SET_ENV, 0, key); + } + +-static inline int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count) { ++static inline int udev_ctrl_send_set_children_max(UdevCtrl *uctrl, int count) { + return udev_ctrl_send(uctrl, UDEV_CTRL_SET_CHILDREN_MAX, count, NULL); + } + +-static inline int udev_ctrl_send_ping(struct udev_ctrl *uctrl) { ++static inline int udev_ctrl_send_ping(UdevCtrl *uctrl) { + return udev_ctrl_send(uctrl, UDEV_CTRL_PING, 0, NULL); + } + +-static inline int udev_ctrl_send_exit(struct udev_ctrl *uctrl) { ++static inline int udev_ctrl_send_exit(UdevCtrl *uctrl) { + return udev_ctrl_send(uctrl, UDEV_CTRL_EXIT, 0, NULL); + } + +-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref); ++DEFINE_TRIVIAL_CLEANUP_FUNC(UdevCtrl*, udev_ctrl_unref); +diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c +index 20820dd64723..06c61e5c07c6 100644 +--- a/src/udev/udevadm-control.c ++++ b/src/udev/udevadm-control.c +@@ -48,7 +48,7 @@ static int help(void) { + } + + int control_main(int argc, char *argv, void *userdata) { +- _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *uctrl = NULL; ++ _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL; + usec_t timeout = 60 * USEC_PER_SEC; + int c, r; + +diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c +index 84b4f9ca4588..6da9439bd28a 100644 +--- a/src/udev/udevadm-settle.c ++++ b/src/udev/udevadm-settle.c +@@ -176,7 +176,7 @@ int settle_main(int argc, char *argv, void *userdata) { + + /* guarantee that the udev daemon isn't pre-processing */ + if (getuid() == 0) { +- _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *uctrl = NULL; ++ _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL; + + if (udev_ctrl_new(&uctrl) >= 0) { + r = udev_ctrl_send_ping(uctrl); +diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c +index 8acf3d9b1189..a24073fb7341 100644 +--- a/src/udev/udevadm-trigger.c ++++ b/src/udev/udevadm-trigger.c +@@ -421,7 +421,7 @@ int trigger_main(int argc, char *argv, void *userdata) { + } + + if (ping) { +- _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *uctrl = NULL; ++ _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL; + + r = udev_ctrl_new(&uctrl); + if (r < 0) +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 6baedd2f2e69..a35b095dd141 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -94,7 +94,7 @@ typedef struct Manager { + sd_netlink *rtnl; + + sd_device_monitor *monitor; +- struct udev_ctrl *ctrl; ++ UdevCtrl *ctrl; + int worker_watch2; + + /* used by udev-watch */ +@@ -1067,7 +1067,7 @@ static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata) + } + + /* receive the udevd message from userspace */ +-static int on_ctrl_msg(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, const union udev_ctrl_msg_value *value, void *userdata) { ++static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) { + Manager *manager = userdata; + int r; +
View file
_service:tar_scm:backport-udev-assume-block-device-is-not-locked-when-a-new-event-is-queued.patch
Added
@@ -0,0 +1,81 @@ +From 82a5de9fd289e1d9b109528bcdddb74534e1a4bf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 25 Mar 2022 02:56:58 +0900 +Subject: PATCH udev: assume block device is not locked when a new event is + queued + +Then, hopefully, previously requeued events are processed earlier. + +Reference:https://github.com/systemd/systemd/commit/82a5de9fd289e1d9b109528bcdddb74534e1a4bf +Conflict:adaption + +--- + src/udev/udevd.c | 40 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index eebb2f8..e0f70cc 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -1033,6 +1033,40 @@ static int event_requeue(Event *event) { + return 0; + } + ++static int event_queue_assume_block_device_unlocked(Manager *manager, sd_device *dev) { ++ const char *devname; ++ Event * event; ++ int r; ++ ++ /* When a new event for a block device is queued or we get an inotify event, assume that the ++ * device is not locked anymore. The assumption may not be true, but that should not cause any ++ * issues, as in that case events will be requeued soon. */ ++ ++ r = device_get_block_device(dev, &devname); ++ if (r <= 0) ++ return r; ++ ++ LIST_FOREACH(event, event, manager->events) { ++ const char *event_devname; ++ ++ if (event->state != EVENT_QUEUED) ++ continue; ++ ++ if (event->retry_again_next_usec == 0) ++ continue; ++ ++ if (device_get_block_device(event->dev, &event_devname) <= 0) ++ continue; ++ ++ if (!streq(devname, event_devname)) ++ continue; ++ ++ event->retry_again_next_usec = 0; ++ } ++ ++ return 0; ++} ++ + static int event_queue_insert(Manager *manager, sd_device *dev) { + sd_device_action_t action; + uint64_t seqnum; +@@ -1095,6 +1129,8 @@ static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata) + return 1; + } + ++ (void) event_queue_assume_block_device_unlocked(manager, dev); ++ + /* we have fresh events, try to schedule them */ + event_queue_start(manager); + +@@ -1426,8 +1462,10 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda + continue; + + log_device_debug(dev, "Inotify event: %x for %s", e->mask, devnode); +- if (e->mask & IN_CLOSE_WRITE) ++ if (e->mask & IN_CLOSE_WRITE) { ++ (void) event_queue_assume_block_device_unlocked(manager, dev); + (void) synthesize_change(dev); ++ } + + /* Do not handle IN_IGNORED here. It should be handled by worker in 'remove' uevent; + * udev_event_execute_rules() -> event_execute_rules_on_remove() -> udev_watch_end(). */
View file
_service:tar_scm:backport-udev-assume-there-is-no-blocker-when-failed-to-check-event.patch
Added
@@ -0,0 +1,54 @@ +From 2d40f02ee4317233365f53c85234be3af6b000a6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 12 Mar 2022 20:57:15 +0900 +Subject: PATCH udev: assume there is no blocker when failed to check event + dependencies + +Previously, if udevd failed to resolve event dependency, the event is +ignored and libudev listeners did not receive the event. This is +inconsistent with the case when a worker failed to process a event, +in that case, the original uevent sent by the kernel is broadcasted to +listeners. + +Reference:https://github.com/systemd/systemd/commit/2d40f02ee4317233365f53c85234be3af6b000a6 +Conflict:NA + +--- + src/udev/udevd.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index f1f864a4610c..8c690357b8d3 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -951,24 +951,21 @@ static int event_queue_start(Manager *manager) { + + /* do not start event if parent or child event is still running or queued */ + r = event_is_blocked(event); ++ if (r > 0) ++ continue; + if (r < 0) { + sd_device_action_t a = _SD_DEVICE_ACTION_INVALID; + + (void) sd_device_get_action(event->dev, &a); + log_device_warning_errno(event->dev, r, +- "Failed to check event dependency, " +- "skipping event (SEQNUM=%"PRIu64", ACTION=%s)", ++ "Failed to check dependencies for event (SEQNUM=%"PRIu64", ACTION=%s), " ++ "assuming there is no blocking event, ignoring: %m", + event->seqnum, + strna(device_action_to_string(a))); +- +- event_free(event); +- return r; + } +- if (r > 0) +- continue; + + r = event_run(event); +- if (r <= 0) ++ if (r <= 0) /* 0 means there are no idle workers. Let's escape from the loop. */ + return r; + } + + \ No newline at end of file
View file
_service:tar_scm:backport-udev-cdrom_id-check-last-track-info.patch
Added
@@ -0,0 +1,31 @@ +From c3fcff52912b0323e11f535fce151dc758f111e6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 14 Aug 2022 06:00:10 +0900 +Subject: PATCH udev/cdrom_id: check last track info + +Fixes off-by-one issue. + +Fixes #24306. + +(cherry picked from commit 628998ecfa0d39b38874e1aecdb28022f80f3269) +(cherry picked from commit c67a388aeffcdc27ff280f01b7939005f7a9c8e9) +--- + src/udev/cdrom_id/cdrom_id.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c +index cdb66bb3b7..964eb6988e 100644 +--- a/src/udev/cdrom_id/cdrom_id.c ++++ b/src/udev/cdrom_id/cdrom_id.c +@@ -704,7 +704,7 @@ static int cd_media_toc(Context *c) { + /* Take care to not iterate beyond the last valid track as specified in + * the TOC, but also avoid going beyond the TOC length, just in case + * the last track number is invalidly large */ +- for (size_t i = 4; i + 8 < len && num_tracks > 0; i += 8, --num_tracks) { ++ for (size_t i = 4; i + 8 <= len && num_tracks > 0; i += 8, --num_tracks) { + bool is_data_track; + uint32_t block; + +-- +2.33.0 +
View file
_service:tar_scm:backport-udev-certainly-restart-event-for-previously-locked-device.patch
Added
@@ -0,0 +1,86 @@ +From 4f294ffdf18ab9f187400dbbab593a980e60be89 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 26 Aug 2022 00:16:17 +0900 +Subject: PATCH udev: certainly restart event for previously locked device + +If udevd receives a uevent for a locked block device, then the event +is requeued. However, the queued event will be processed only when at +least one sd_event_source is processed. Hence, if udevd has no event +under processing, or receives no new uevent, etc., then the requeued +event will be never processed. + +Follow-up for 400e3d21f8cae53a8ba9f9567f244fbf6f3e076c. + +Fixes #24439. + +Reference:https://github.com/systemd/systemd/commit/4f294ffdf18ab9f187400dbbab593a980e60be89 +Conflict:adaption because previous commits in https://github.com/systemd/systemd/pull/23088 are not introduced + +--- + src/udev/udevd.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index a979d43..b15a9d4 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -129,8 +129,11 @@ typedef struct Event { + sd_device_action_t action; + uint64_t seqnum; + uint64_t blocker_seqnum; ++ ++ /* Used when the device is locked by another program. */ + usec_t retry_again_next_usec; + usec_t retry_again_timeout_usec; ++ sd_event_source *retry_event_source; + + sd_event_source *timeout_warning_event; + sd_event_source *timeout_event; +@@ -172,6 +175,7 @@ static Event *event_free(Event *event) { + LIST_REMOVE(event, event->manager->events, event); + sd_device_unref(event->dev); + ++ sd_event_source_unref(event->retry_event_source); + sd_event_source_unref(event->timeout_warning_event); + sd_event_source_unref(event->timeout_event); + +@@ -749,6 +753,8 @@ static int event_run(Event *event) { + + log_device_uevent(event->dev, "Device ready for processing"); + ++ (void) event_source_disable(event->retry_event_source); ++ + manager = event->manager; + HASHMAP_FOREACH(worker, manager->workers) { + if (worker->state != WORKER_IDLE) +@@ -995,6 +1001,11 @@ static int event_queue_start(Manager *manager) { + return 0; + } + ++static int on_event_retry(sd_event_source *s, uint64_t usec, void *userdata) { ++ /* This does nothing. The on_post() callback will start the event if there exists an idle worker. */ ++ return 1; ++} ++ + static int event_requeue(Event *event) { + usec_t now_usec; + int r; +@@ -1025,6 +1036,15 @@ static int event_requeue(Event *event) { + if (event->retry_again_timeout_usec == 0) + event->retry_again_timeout_usec = usec_add(now_usec, EVENT_RETRY_TIMEOUT_USEC); + ++ r = event_reset_time_relative(event->manager->event, &event->retry_event_source, ++ CLOCK_MONOTONIC, EVENT_RETRY_INTERVAL_USEC, 0, ++ on_event_retry, NULL, ++ 0, "retry-event", true); ++ if (r < 0) ++ return log_device_warning_errno(event->dev, r, "Failed to reset timer event source for retrying event, " ++ "skipping event (SEQNUM=%"PRIu64", ACTION=%s): %m", ++ event->seqnum, strna(device_action_to_string(event->action))); ++ + if (event->worker && event->worker->event == event) + event->worker->event = NULL; + event->worker = NULL; +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-do-not-try-to-find-blocker-again-when-no-blocker-found.patch
Added
@@ -0,0 +1,91 @@ +From 044ac33c35ab1aeb35fc8b84462a9549cbbac294 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 16:57:32 +0900 +Subject: PATCH udev: do not try to find blocker again when no blocker found + previously + +Reference:https://github.com/systemd/systemd/commit/044ac33c35ab1aeb35fc8b84462a9549cbbac294 +Conflict:NA + +--- + src/udev/udevd.c | 45 +++++++++++++++++++++++++++++++++++---------- + 1 file changed, 35 insertions(+), 10 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 20bd556..be2c3ee 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -783,6 +783,35 @@ static int event_is_blocked(Event *event) { + + /* lookup event for identical, parent, child device */ + ++ assert(event); ++ assert(event->manager); ++ assert(event->blocker_seqnum <= event->seqnum); ++ ++ if (event->blocker_seqnum == event->seqnum) ++ /* we have checked previously and no blocker found */ ++ return false; ++ ++ LIST_FOREACH(event, loop_event, event->manager->events) { ++ /* we already found a later event, earlier cannot block us, no need to check again */ ++ if (loop_event->seqnum < event->blocker_seqnum) ++ continue; ++ ++ /* event we checked earlier still exists, no need to check again */ ++ if (loop_event->seqnum == event->blocker_seqnum) ++ return true; ++ ++ /* found ourself, no later event can block us */ ++ if (loop_event->seqnum >= event->seqnum) ++ goto no_blocker; ++ ++ /* found event we have not checked */ ++ break; ++ } ++ ++ assert(loop_event); ++ assert(loop_event->seqnum > event->blocker_seqnum && ++ loop_event->seqnum < event->seqnum); ++ + r = sd_device_get_subsystem(event->dev, &subsystem); + if (r < 0) + return r; +@@ -808,21 +837,13 @@ static int event_is_blocked(Event *event) { + return r; + + /* check if queue contains events we depend on */ +- LIST_FOREACH(event, loop_event, event->manager->events) { ++ LIST_FOREACH(event, loop_event, loop_event) { + size_t loop_devpath_len, common; + const char *loop_devpath; + +- /* we already found a later event, earlier cannot block us, no need to check again */ +- if (loop_event->seqnum < event->blocker_seqnum) +- continue; +- +- /* event we checked earlier still exists, no need to check again */ +- if (loop_event->seqnum == event->blocker_seqnum) +- return true; +- + /* found ourself, no later event can block us */ + if (loop_event->seqnum >= event->seqnum) +- return false; ++ goto no_blocker; + + /* check major/minor */ + if (major(devnum) != 0) { +@@ -882,6 +903,10 @@ static int event_is_blocked(Event *event) { + + event->blocker_seqnum = loop_event->seqnum; + return true; ++ ++no_blocker: ++ event->blocker_seqnum = event->seqnum; ++ return false; + } + + static int event_queue_start(Manager *manager) { +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-do-not-try-to-process-events-if-there-is-no-free-worker.patch
Added
@@ -0,0 +1,28 @@ +From 5f4bca9dccdd9e9a888587c6224b08ae5fbe3bdb Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 15:51:34 +0900 +Subject: PATCH udev: do not try to process events if there is no free worker + +Reference:https://github.com/systemd/systemd/commit/5f4bca9dccdd9e9a888587c6224b08ae5fbe3bdb +Conflict:NA + +--- + src/udev/udevd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 7f41336..e99c2c0 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -927,7 +927,7 @@ static int event_queue_start(Manager *manager) { + continue; + + r = event_run(event); +- if (r < 0) ++ if (r <= 0) + return r; + } + +-- +2.33.0 +
View file
_service:tar_scm:backport-udev-drop-unnecessary-calls-of-event_queue_start.patch
Added
@@ -0,0 +1,80 @@ +From 5fab6b7b18d0158c005a5bcf096face23377af72 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 26 Aug 2022 00:34:15 +0900 +Subject: PATCH udev: drop unnecessary calls of event_queue_start() + +As the subsequent call of on_post() will call it if necessary. + +This also drop unnecessary call of event_source_disable() for killing +idle workers, as the event source is disabled in event_queue_start(). + +Reference:https://github.com/systemd/systemd/commit/5fab6b7b18d0158c005a5bcf096face23377af72 +Conflict:adaption + +--- + src/udev/udevd.c | 21 --------------------- + 1 file changed, 21 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index b15a9d4..75e2086 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -1151,9 +1151,6 @@ static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata) + + (void) event_queue_assume_block_device_unlocked(manager, dev); + +- /* we have fresh events, try to schedule them */ +- event_queue_start(manager); +- + return 1; + } + +@@ -1220,9 +1217,6 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat + event_free(worker->event); + } + +- /* we have free workers, try to schedule events */ +- event_queue_start(manager); +- + return 1; + } + +@@ -1456,10 +1450,6 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda + + assert(manager); + +- r = event_source_disable(manager->kill_workers_event); +- if (r < 0) +- log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); +- + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { + if (IN_SET(errno, EAGAIN, EINTR)) +@@ -1516,7 +1506,6 @@ static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void + + static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { + Manager *manager = userdata; +- int r; + + assert(manager); + +@@ -1565,16 +1554,6 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi + worker_free(worker); + } + +- /* we can start new workers, try to schedule events */ +- event_queue_start(manager); +- +- /* Disable unnecessary cleanup event */ +- if (hashmap_isempty(manager->workers)) { +- r = event_source_disable(manager->kill_workers_event); +- if (r < 0) +- log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); +- } +- + return 1; + } + +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-drop-unnecessary-clone-of-received-sd-device-object.patch
Added
@@ -0,0 +1,85 @@ +From c9473aaa5b69c47edab365b46abee6e9ab5b18dc Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 25 Mar 2022 01:13:39 +0900 +Subject: PATCH udev: drop unnecessary clone of received sd-device object + +As the sd-device object received through sd-device-monitor is sealed, +so the corresponding udev database or uevent file will not be read. + +Reference:https://github.com/systemd/systemd/commit/c9473aaa5b69c47edab365b46abee6e9ab5b18dc +Conflict:adaption + +--- + src/udev/udevd.c | 21 ++++----------------- + 1 file changed, 4 insertions(+), 17 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 108142e9c619..05397df7a429 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -124,7 +124,6 @@ typedef struct Event { + EventState state; + + sd_device *dev; +- sd_device *dev_kernel; /* clone of originally received device */ + + uint64_t seqnum; + uint64_t blocker_seqnum; +@@ -163,7 +162,6 @@ static Event *event_free(Event *event) { + + LIST_REMOVE(event, event->manager->events, event); + sd_device_unref(event->dev); +- sd_device_unref(event->dev_kernel); + + sd_event_source_unref(event->timeout_warning_event); + sd_event_source_unref(event->timeout_event); +@@ -973,9 +971,8 @@ static int event_queue_start(Manager *manager) { + } + + static int event_queue_insert(Manager *manager, sd_device *dev) { +- _cleanup_(sd_device_unrefp) sd_device *clone = NULL; +- Event *event; + uint64_t seqnum; ++ Event *event; + int r; + + assert(manager); +@@ -989,15 +986,6 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { + if (r < 0) + return r; + +- /* Save original device to restore the state on failures. */ +- r = device_shallow_clone(dev, &clone); +- if (r < 0) +- return r; +- +- r = device_copy_properties(clone, dev); +- if (r < 0) +- return r; +- + event = new(Event, 1); + if (!event) + return -ENOMEM; +@@ -1005,7 +993,6 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { + *event = (Event) { + .manager = manager, + .dev = sd_device_ref(dev), +- .dev_kernel = TAKE_PTR(clone), + .seqnum = seqnum, + .state = EVENT_QUEUED, + }; +@@ -1440,10 +1427,10 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi + device_tag_index(worker->event->dev, NULL, false); + + if (manager->monitor) { +- /* Forward kernel event unchanged */ +- r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel); ++ /* Forward kernel event to libudev listeners */ ++ r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev); + if (r < 0) +- log_device_warning_errno(worker->event->dev_kernel, r, ++ log_device_warning_errno(worker->event->dev, r, + "Failed to broadcast failed event to libudev listeners, ignoring: %m"); + } + } + \ No newline at end of file
View file
_service:tar_scm:backport-udev-fix-inversed-inequality-for-timeout-of-retrying-event.patch
Added
@@ -0,0 +1,27 @@ +From 400e3d21f8cae53a8ba9f9567f244fbf6f3e076c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 19 Aug 2022 21:25:03 +0900 +Subject: PATCH udev: fix inversed inequality for timeout of retrying event + +Follow-up for 5d354e525a56955ae7f68062e283dda85ab07794. + +Reference:https://github.com/systemd/systemd/commit/400e3d21f8cae53a8ba9f9567f244fbf6f3e076c +Conflict:NA + +--- + src/udev/udevd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index a6926bbfb71d..01162bc7b601 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -898,7 +898,7 @@ static int event_is_blocked(Event *event) { + if (r < 0) + return r; + +- if (event->retry_again_next_usec <= now_usec) ++ if (event->retry_again_next_usec > now_usec) + return true; + } +
View file
_service:tar_scm:backport-udev-introduce-device_broadcast_helper_function.patch
Added
@@ -0,0 +1,66 @@ +From c17ab900cbb47f0c136b141bb83557f112501707 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 25 Mar 2022 02:33:55 +0900 +Subject: PATCH udev: introduce device_broadcast() helper function + +Reference:https://github.com/systemd/systemd/commit/c17ab900cbb47f0c136b141bb83557f112501707 +Conflict:NA + +--- + src/udev/udevd.c | 28 ++++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 05397df7a429..53728c9f7971 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -344,6 +344,21 @@ static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userda + return 1; + } + ++static void device_broadcast(sd_device_monitor *monitor, sd_device *dev) { ++ int r; ++ ++ assert(dev); ++ ++ /* On exit, manager->monitor is already NULL. */ ++ if (!monitor) ++ return; ++ ++ r = device_monitor_send_device(monitor, NULL, dev); ++ if (r < 0) ++ log_device_warning_errno(dev, r, ++ "Failed to broadcast event to libudev listeners, ignoring: %m"); ++} ++ + static int worker_send_message(int fd) { + WorkerMessage message = {}; + +@@ -558,9 +573,7 @@ static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device * + log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m"); + + /* send processed event back to libudev listeners */ +- r = device_monitor_send_device(monitor, NULL, dev); +- if (r < 0) +- log_device_warning_errno(dev, r, "Failed to send device, ignoring: %m"); ++ device_broadcast(monitor, dev); + } + + /* send udevd the result of the event execution */ +@@ -1426,13 +1439,8 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi + device_delete_db(worker->event->dev); + device_tag_index(worker->event->dev, NULL, false); + +- if (manager->monitor) { +- /* Forward kernel event to libudev listeners */ +- r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev); +- if (r < 0) +- log_device_warning_errno(worker->event->dev, r, +- "Failed to broadcast failed event to libudev listeners, ignoring: %m"); +- } ++ /* Forward kernel event to libudev listeners */ ++ device_broadcast(manager->monitor, worker->event->dev); + } + + worker_free(worker); + \ No newline at end of file
View file
_service:tar_scm:backport-udev-make-event_free-return-NULL.patch
Added
@@ -0,0 +1,36 @@ +From 5393c52897ff5b57686c867fcab77f9740f4af24 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 15:21:27 +0900 +Subject: PATCH udev: make event_free() return NULL + +Reference:https://github.com/systemd/systemd/commit/5393c52897ff5b57686c867fcab77f9740f4af24.patch +Conflict:NA +--- + src/udev/udevd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 34a5c9d5d8ee..bb7c0eabe420 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -152,9 +152,9 @@ typedef struct Worker { + typedef struct WorkerMessage { + } WorkerMessage; + +-static void event_free(Event *event) { ++static Event *event_free(Event *event) { + if (!event) +- return; ++ return NULL; + + assert(event->manager); + +@@ -174,7 +174,7 @@ static void event_free(Event *event) { + if (unlink("/run/udev/queue") < 0 && errno != ENOENT) + log_warning_errno(errno, "Failed to unlink /run/udev/queue, ignoring: %m"); + +- free(event); ++ return mfree(event); + } + + static void event_queue_cleanup(Manager *manager, EventState match_state) {
View file
_service:tar_scm:backport-udev-make-event_queue_start-return-negative-errno-on-error.patch
Added
@@ -0,0 +1,59 @@ +From 0744e74c526814e28f2fbcea128f40ed36341fcd Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 15:29:02 +0900 +Subject: PATCH udev: make event_queue_start() return negative errno on error + +Reference:https://github.com/systemd/systemd/commit/0744e74c526814e28f2fbcea128f40ed36341fcd +Conflict:NA + +--- + src/udev/udevd.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 1b1b126..279b409 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -879,7 +879,7 @@ set_delaying_seqnum: + return true; + } + +-static void event_queue_start(Manager *manager) { ++static int event_queue_start(Manager *manager) { + Event *event; + usec_t usec; + int r; +@@ -888,7 +888,7 @@ static void event_queue_start(Manager *manager) { + + if (LIST_IS_EMPTY(manager->events) || + manager->exit || manager->stop_exec_queue) +- return; ++ return 0; + + assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0); + /* check for changed config, every 3 seconds at most */ +@@ -909,10 +909,8 @@ static void event_queue_start(Manager *manager) { + + if (!manager->rules) { + r = udev_rules_load(&manager->rules, arg_resolve_name_timing); +- if (r < 0) { +- log_warning_errno(r, "Failed to read udev rules: %m"); +- return; +- } ++ if (r < 0) ++ return log_warning_errno(r, "Failed to read udev rules: %m"); + } + + LIST_FOREACH(event, event, manager->events) { +@@ -925,6 +923,8 @@ static void event_queue_start(Manager *manager) { + + event_run(manager, event); + } ++ ++ return 0; + } + + static int event_queue_insert(Manager *manager, sd_device *dev) { +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-move-several-functions.patch
Added
@@ -0,0 +1,544 @@ +From 419ec631358c8bf7013db01ae42763e6971d8765 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 15:14:59 +0900 +Subject: PATCH udev: move several functions + +No functional chage. + +Reference:https://github.com/systemd/systemd/commit/419ec631358c8bf7013db01ae42763e6971d8765 +Conflict:adaption + +--- + src/udev/udevd.c | 434 +++++++++++++++++++++++------------------------ + 1 file changed, 216 insertions(+), 218 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 9c9487f..018809e 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -134,8 +134,6 @@ typedef struct Event { + LIST_FIELDS(Event, event); + } Event; + +-static void event_queue_cleanup(Manager *manager, EventState match_state); +- + typedef enum WorkerState { + WORKER_UNDEF, + WORKER_RUNNING, +@@ -181,6 +179,17 @@ static void event_free(Event *event) { + free(event); + } + ++static void event_queue_cleanup(Manager *manager, EventState match_state) { ++ Event *event, *tmp; ++ ++ LIST_FOREACH_SAFE(event, event, tmp, manager->events) { ++ if (match_state != EVENT_UNDEF && match_state != event->state) ++ continue; ++ ++ event_free(event); ++ } ++} ++ + static Worker *worker_free(Worker *worker) { + if (!worker) + return NULL; +@@ -197,6 +206,48 @@ static Worker *worker_free(Worker *worker) { + DEFINE_TRIVIAL_CLEANUP_FUNC(Worker*, worker_free); + DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(worker_hash_op, void, trivial_hash_func, trivial_compare_func, Worker, worker_free); + ++static void manager_clear_for_worker(Manager *manager) { ++ assert(manager); ++ ++ manager->inotify_event = sd_event_source_unref(manager->inotify_event); ++ manager->kill_workers_event = sd_event_source_unref(manager->kill_workers_event); ++ ++ manager->event = sd_event_unref(manager->event); ++ ++ manager->workers = hashmap_free(manager->workers); ++ event_queue_cleanup(manager, EVENT_UNDEF); ++ ++ manager->monitor = sd_device_monitor_unref(manager->monitor); ++ manager->ctrl = udev_ctrl_unref(manager->ctrl); ++ ++ manager->worker_watchREAD_END = safe_close(manager->worker_watchREAD_END); ++} ++ ++static Manager* manager_free(Manager *manager) { ++ if (!manager) ++ return NULL; ++ ++ udev_builtin_exit(); ++ ++ if (manager->pid == getpid_cached()) ++ udev_ctrl_cleanup(manager->ctrl); ++ ++ manager_clear_for_worker(manager); ++ ++ sd_netlink_unref(manager->rtnl); ++ ++ hashmap_free_free_free(manager->properties); ++ udev_rules_free(manager->rules); ++ ++ safe_close(manager->inotify_fd); ++ safe_close_pair(manager->worker_watch); ++ ++ free(manager->cgroup); ++ return mfree(manager); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); ++ + static int worker_new(Worker **ret, Manager *manager, sd_device_monitor *worker_monitor, pid_t pid) { + _cleanup_(worker_freep) Worker *worker = NULL; + int r; +@@ -228,97 +279,75 @@ static int worker_new(Worker **ret, Manager *manager, sd_device_monitor *worker_ + return 0; + } + +-static int on_event_timeout(sd_event_source *s, uint64_t usec, void *userdata) { +- Event *event = userdata; +- +- assert(event); +- assert(event->worker); +- +- kill_and_sigcont(event->worker->pid, arg_timeout_signal); +- event->worker->state = WORKER_KILLED; +- +- log_device_error(event->dev, "Worker "PID_FMT" processing SEQNUM=%"PRIu64" killed", event->worker->pid, event->seqnum); +- +- return 1; +-} ++static void manager_kill_workers(Manager *manager, bool force) { ++ Worker *worker; + +-static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) { +- Event *event = userdata; ++ assert(manager); + +- assert(event); +- assert(event->worker); ++ HASHMAP_FOREACH(worker, manager->workers) { ++ if (worker->state == WORKER_KILLED) ++ continue; + +- log_device_warning(event->dev, "Worker "PID_FMT" processing SEQNUM=%"PRIu64" is taking a long time", event->worker->pid, event->seqnum); ++ if (worker->state == WORKER_RUNNING && !force) { ++ worker->state = WORKER_KILLING; ++ continue; ++ } + +- return 1; ++ worker->state = WORKER_KILLED; ++ (void) kill(worker->pid, SIGTERM); ++ } + } + +-static void worker_attach_event(Worker *worker, Event *event) { +- sd_event *e; +- +- assert(worker); +- assert(worker->manager); +- assert(event); +- assert(!event->worker); +- assert(!worker->event); +- +- worker->state = WORKER_RUNNING; +- worker->event = event; +- event->state = EVENT_RUNNING; +- event->worker = worker; +- +- e = worker->manager->event; ++static void manager_exit(Manager *manager) { ++ assert(manager); + +- (void) sd_event_add_time_relative(e, &event->timeout_warning_event, CLOCK_MONOTONIC, +- udev_warn_timeout(arg_event_timeout_usec), USEC_PER_SEC, +- on_event_timeout_warning, event); ++ manager->exit = true; + +- (void) sd_event_add_time_relative(e, &event->timeout_event, CLOCK_MONOTONIC, +- arg_event_timeout_usec, USEC_PER_SEC, +- on_event_timeout, event); +-} ++ sd_notify(false, ++ "STOPPING=1\n" ++ "STATUS=Starting shutdown..."); + +-static void manager_clear_for_worker(Manager *manager) { +- assert(manager); ++ /* close sources of new events and discard buffered events */ ++ manager->ctrl = udev_ctrl_unref(manager->ctrl); + + manager->inotify_event = sd_event_source_unref(manager->inotify_event); +- manager->kill_workers_event = sd_event_source_unref(manager->kill_workers_event); +- +- manager->event = sd_event_unref(manager->event); +- +- manager->workers = hashmap_free(manager->workers); +- event_queue_cleanup(manager, EVENT_UNDEF); ++ manager->inotify_fd = safe_close(manager->inotify_fd); + + manager->monitor = sd_device_monitor_unref(manager->monitor); +- manager->ctrl = udev_ctrl_unref(manager->ctrl); + +- manager->worker_watchREAD_END = safe_close(manager->worker_watchREAD_END); ++ /* discard queued events and kill workers */ ++ event_queue_cleanup(manager, EVENT_QUEUED); ++ manager_kill_workers(manager, true); + } + +-static Manager* manager_free(Manager *manager) { +- if (!manager) +- return NULL; ++/* reload requested, HUP signal received, rules changed, builtin changed */ ++static void manager_reload(Manager *manager) { + +- udev_builtin_exit(); ++ assert(manager); + +- if (manager->pid == getpid_cached()) +- udev_ctrl_cleanup(manager->ctrl); ++ sd_notify(false, ++ "RELOADING=1\n" ++ "STATUS=Flushing configuration..."); + +- manager_clear_for_worker(manager); ++ manager_kill_workers(manager, false); ++ manager->rules = udev_rules_free(manager->rules); ++ udev_builtin_exit(); + +- sd_netlink_unref(manager->rtnl); ++ sd_notifyf(false, ++ "READY=1\n" ++ "STATUS=Processing with %u children at max", arg_children_max); ++} + +- hashmap_free_free_free(manager->properties); +- udev_rules_free(manager->rules); ++static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userdata) { ++ Manager *manager = userdata; + +- safe_close(manager->inotify_fd); +- safe_close_pair(manager->worker_watch); ++ assert(manager); + +- free(manager->cgroup); +- return mfree(manager); +-} ++ log_debug("Cleanup idle workers"); ++ manager_kill_workers(manager, false); + +-DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); ++ return 1; ++} + + static int worker_send_message(int fd) { + WorkerMessage message = {}; +@@ -597,6 +626,56 @@ static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device + return 0; + } + ++static int on_event_timeout(sd_event_source *s, uint64_t usec, void *userdata) { ++ Event *event = userdata; ++ ++ assert(event); ++ assert(event->worker); ++ ++ kill_and_sigcont(event->worker->pid, arg_timeout_signal); ++ event->worker->state = WORKER_KILLED; ++ ++ log_device_error(event->dev, "Worker "PID_FMT" processing SEQNUM=%"PRIu64" killed", event->worker->pid, event->seqnum); ++ ++ return 1; ++} ++ ++static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) { ++ Event *event = userdata; ++ ++ assert(event); ++ assert(event->worker); ++ ++ log_device_warning(event->dev, "Worker "PID_FMT" processing SEQNUM=%"PRIu64" is taking a long time", event->worker->pid, event->seqnum); ++ ++ return 1; ++} ++ ++static void worker_attach_event(Worker *worker, Event *event) { ++ sd_event *e; ++ ++ assert(worker); ++ assert(worker->manager); ++ assert(event); ++ assert(!event->worker); ++ assert(!worker->event); ++ ++ worker->state = WORKER_RUNNING; ++ worker->event = event; ++ event->state = EVENT_RUNNING; ++ event->worker = worker; ++ ++ e = worker->manager->event; ++ ++ (void) sd_event_add_time_relative(e, &event->timeout_warning_event, CLOCK_MONOTONIC, ++ udev_warn_timeout(arg_event_timeout_usec), USEC_PER_SEC, ++ on_event_timeout_warning, event); ++ ++ (void) sd_event_add_time_relative(e, &event->timeout_event, CLOCK_MONOTONIC, ++ arg_event_timeout_usec, USEC_PER_SEC, ++ on_event_timeout, event); ++} ++ + static int worker_spawn(Manager *manager, Event *event) { + _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *worker_monitor = NULL; + Worker *worker; +@@ -689,76 +768,6 @@ static void event_run(Manager *manager, Event *event) { + worker_spawn(manager, event); + } + +-static int event_queue_insert(Manager *manager, sd_device *dev) { +- _cleanup_(sd_device_unrefp) sd_device *clone = NULL; +- Event *event; +- uint64_t seqnum; +- int r; +- +- assert(manager); +- assert(dev); +- +- /* only one process can add events to the queue */ +- assert(manager->pid == getpid_cached()); +- +- /* We only accepts devices received by device monitor. */ +- r = sd_device_get_seqnum(dev, &seqnum); +- if (r < 0) +- return r; +- +- /* Save original device to restore the state on failures. */ +- r = device_shallow_clone(dev, &clone); +- if (r < 0) +- return r; +- +- r = device_copy_properties(clone, dev); +- if (r < 0) +- return r; +- +- event = new(Event, 1); +- if (!event) +- return -ENOMEM; +- +- *event = (Event) { +- .manager = manager, +- .dev = sd_device_ref(dev), +- .dev_kernel = TAKE_PTR(clone), +- .seqnum = seqnum, +- .state = EVENT_QUEUED, +- }; +- +- if (LIST_IS_EMPTY(manager->events)) { +- r = touch("/run/udev/queue"); +- if (r < 0) +- log_warning_errno(r, "Failed to touch /run/udev/queue: %m"); +- } +- +- LIST_APPEND(event, manager->events, event); +- +- log_device_uevent(dev, "Device is queued"); +- +- return 0; +-} +- +-static void manager_kill_workers(Manager *manager, bool force) { +- Worker *worker; +- +- assert(manager); +- +- HASHMAP_FOREACH(worker, manager->workers) { +- if (worker->state == WORKER_KILLED) +- continue; +- +- if (worker->state == WORKER_RUNNING && !force) { +- worker->state = WORKER_KILLING; +- continue; +- } +- +- worker->state = WORKER_KILLED; +- (void) kill(worker->pid, SIGTERM); +- } +-} +- + /* lookup event for identical, parent, child device */ + static int is_device_busy(Manager *manager, Event *event) { + const char *subsystem, *devpath, *devpath_old = NULL; +@@ -870,57 +879,6 @@ set_delaying_seqnum: + return true; + } + +-static void manager_exit(Manager *manager) { +- assert(manager); +- +- manager->exit = true; +- +- sd_notify(false, +- "STOPPING=1\n" +- "STATUS=Starting shutdown..."); +- +- /* close sources of new events and discard buffered events */ +- manager->ctrl = udev_ctrl_unref(manager->ctrl); +- +- manager->inotify_event = sd_event_source_unref(manager->inotify_event); +- manager->inotify_fd = safe_close(manager->inotify_fd); +- +- manager->monitor = sd_device_monitor_unref(manager->monitor); +- +- /* discard queued events and kill workers */ +- event_queue_cleanup(manager, EVENT_QUEUED); +- manager_kill_workers(manager, true); +-} +- +-/* reload requested, HUP signal received, rules changed, builtin changed */ +-static void manager_reload(Manager *manager) { +- +- assert(manager); +- +- sd_notify(false, +- "RELOADING=1\n" +- "STATUS=Flushing configuration..."); +- +- manager_kill_workers(manager, false); +- manager->rules = udev_rules_free(manager->rules); +- udev_builtin_exit(); +- +- sd_notifyf(false, +- "READY=1\n" +- "STATUS=Processing with %u children at max", arg_children_max); +-} +- +-static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userdata) { +- Manager *manager = userdata; +- +- assert(manager); +- +- log_debug("Cleanup idle workers"); +- manager_kill_workers(manager, false); +- +- return 1; +-} +- + static void event_queue_start(Manager *manager) { + Event *event; + usec_t usec; +@@ -969,15 +927,77 @@ static void event_queue_start(Manager *manager) { + } + } + +-static void event_queue_cleanup(Manager *manager, EventState match_state) { +- Event *event, *tmp; ++static int event_queue_insert(Manager *manager, sd_device *dev) { ++ _cleanup_(sd_device_unrefp) sd_device *clone = NULL; ++ Event *event; ++ uint64_t seqnum; ++ int r; + +- LIST_FOREACH_SAFE(event, event, tmp, manager->events) { +- if (match_state != EVENT_UNDEF && match_state != event->state) +- continue; ++ assert(manager); ++ assert(dev); + +- event_free(event); ++ /* only one process can add events to the queue */ ++ assert(manager->pid == getpid_cached()); ++ ++ /* We only accepts devices received by device monitor. */ ++ r = sd_device_get_seqnum(dev, &seqnum); ++ if (r < 0) ++ return r; ++ ++ /* Save original device to restore the state on failures. */ ++ r = device_shallow_clone(dev, &clone); ++ if (r < 0) ++ return r; ++ ++ r = device_copy_properties(clone, dev); ++ if (r < 0) ++ return r; ++ ++ event = new(Event, 1); ++ if (!event) ++ return -ENOMEM; ++ ++ *event = (Event) { ++ .manager = manager, ++ .dev = sd_device_ref(dev), ++ .dev_kernel = TAKE_PTR(clone), ++ .seqnum = seqnum, ++ .state = EVENT_QUEUED, ++ }; ++ ++ if (LIST_IS_EMPTY(manager->events)) { ++ r = touch("/run/udev/queue"); ++ if (r < 0) ++ log_warning_errno(r, "Failed to touch /run/udev/queue: %m"); ++ } ++ ++ LIST_APPEND(event, manager->events, event); ++ ++ log_device_uevent(dev, "Device is queued"); ++ ++ return 0; ++} ++ ++static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata) { ++ Manager *manager = userdata; ++ int r; ++ ++ assert(manager); ++ ++ DEVICE_TRACE_POINT(kernel_uevent_received, dev); ++ ++ device_ensure_usec_initialized(dev, NULL); ++ ++ r = event_queue_insert(manager, dev); ++ if (r < 0) { ++ log_device_error_errno(dev, r, "Failed to insert device into event queue: %m"); ++ return 1; + } ++ ++ /* we have fresh events, try to schedule them */ ++ event_queue_start(manager); ++ ++ return 1; + } + + static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +@@ -1047,28 +1067,6 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat + return 1; + } + +-static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata) { +- Manager *manager = userdata; +- int r; +- +- assert(manager); +- +- DEVICE_TRACE_POINT(kernel_uevent_received, dev); +- +- device_ensure_usec_initialized(dev, NULL); +- +- r = event_queue_insert(manager, dev); +- if (r < 0) { +- log_device_error_errno(dev, r, "Failed to insert device into event queue: %m"); +- return 1; +- } +- +- /* we have fresh events, try to schedule them */ +- event_queue_start(manager); +- +- return 1; +-} +- + /* receive the udevd message from userspace */ + static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) { + Manager *manager = userdata; +-- +2.33.0
View file
_service:tar_scm:backport-udev-only-ignore-ENOENT-or-friends-which-suggest-the-block.patch
Added
@@ -0,0 +1,36 @@ +From ef400c3878ad23aa02bd5bb47f089bdef49e9d8c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 12 Mar 2022 20:40:58 +0900 +Subject: PATCH udev: only ignore ENOENT or friends which suggest the block + device is not exist + +The ENOENT, ENXIO, and ENODEV error can happen easily when a block +device appears and soon removed. So, it is reasonable to ignore the +error. But other errors should not occur here, and hence let's handle +them as critical. + +Reference:https://github.com/systemd/systemd/commit/ef400c3878ad23aa02bd5bb47f089bdef49e9d8c +Conflict:NA + +--- + src/udev/udevd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 8389c39f652f..f1f864a4610c 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -399,8 +399,10 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) { + + fd = open(val, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK); + if (fd < 0) { +- log_device_debug_errno(dev, errno, "Failed to open '%s', ignoring: %m", val); +- return 0; ++ bool ignore = ERRNO_IS_DEVICE_ABSENT(errno); ++ ++ log_device_debug_errno(dev, errno, "Failed to open '%s'%s: %m", val, ignore ? ", ignoring" : ""); ++ return ignore ? 0 : -errno; + } + + if (flock(fd, LOCK_SH|LOCK_NB) < 0) + \ No newline at end of file
View file
_service:tar_scm:backport-udev-propagate-error-on-spawning-a-worker.patch
Added
@@ -0,0 +1,89 @@ +From f2a5412bf286cabc047dc96395c2dae978e722b4 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 15:47:34 +0900 +Subject: PATCH udev: propagate error on spawning a worker + +Reference:https://github.com/systemd/systemd/commit/f2a5412bf286cabc047dc96395c2dae978e722b4 +Conflict:NA + +--- + src/udev/udevd.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 2179825..7f41336 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -720,16 +720,18 @@ static int worker_spawn(Manager *manager, Event *event) { + return 0; + } + +-static void event_run(Manager *manager, Event *event) { ++static int event_run(Event *event) { + static bool log_children_max_reached = true; ++ Manager *manager; + Worker *worker; + int r; + +- assert(manager); + assert(event); ++ assert(event->manager); + + log_device_uevent(event->dev, "Device ready for processing"); + ++ manager = event->manager; + HASHMAP_FOREACH(worker, manager->workers) { + if (worker->state != WORKER_IDLE) + continue; +@@ -743,29 +745,32 @@ static void event_run(Manager *manager, Event *event) { + continue; + } + worker_attach_event(worker, event); +- return; ++ return 1; /* event is now processing. */ + } + + if (hashmap_size(manager->workers) >= arg_children_max) { +- + /* Avoid spamming the debug logs if the limit is already reached and + * many events still need to be processed */ + if (log_children_max_reached && arg_children_max > 1) { + log_debug("Maximum number (%u) of children reached.", hashmap_size(manager->workers)); + log_children_max_reached = false; + } +- return; ++ return 0; /* no free worker */ + } + + /* Re-enable the debug message for the next batch of events */ + log_children_max_reached = true; + + /* fork with up-to-date SELinux label database, so the child inherits the up-to-date db +- and, until the next SELinux policy changes, we safe further reloads in future children */ ++ * and, until the next SELinux policy changes, we safe further reloads in future children */ + mac_selinux_maybe_reload(); + + /* start new worker and pass initial device */ +- worker_spawn(manager, event); ++ r = worker_spawn(manager, event); ++ if (r < 0) ++ return r; ++ ++ return 1; /* event is now processing. */ + } + + /* lookup event for identical, parent, child device */ +@@ -921,7 +926,9 @@ static int event_queue_start(Manager *manager) { + if (is_device_busy(manager, event) != 0) + continue; + +- event_run(manager, event); ++ r = event_run(event); ++ if (r < 0) ++ return r; + } + + return 0; +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-remove-run-udev-queue-in-on_post.patch
Added
@@ -0,0 +1,53 @@ +From 4029328014be9350ca9fc0774ad936c8b5e50ff2 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sun, 13 Mar 2022 21:22:57 +0900 +Subject: PATCH udev: remove /run/udev/queue in on_post() + +When the last queued event is processed, information about subsequent +events may be already queued in the netlink socket of sd-device-monitor. +In that case, previously we once removed /run/udev/queue and touch the +file soon later, and `udevadm settle` mistakenly considered all events +are processed. + +To mitigate such situation, this makes /run/udev/queue removed in on_post(). + +Reference:https://github.com/systemd/systemd/commit/4029328014be9350ca9fc0774ad936c8b5e50ff2 +Conflict:NA + +--- + src/udev/udevd.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 6bb9eeb4bb37..8389c39f652f 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -171,12 +171,6 @@ static Event *event_free(Event *event) { + if (event->worker) + event->worker->event = NULL; + +- /* only clean up the queue from the process that created it */ +- if (LIST_IS_EMPTY(event->manager->events) && +- event->manager->pid == getpid_cached()) +- if (unlink("/run/udev/queue") < 0 && errno != ENOENT) +- log_warning_errno(errno, "Failed to unlink /run/udev/queue, ignoring: %m"); +- + return mfree(event); + } + +@@ -1480,7 +1474,13 @@ static int on_post(sd_event_source *s, void *userdata) { + if (!LIST_IS_EMPTY(manager->events)) + return 1; + +- /* There are no pending events. Let's cleanup idle process. */ ++ /* There are no queued events. Let's remove /run/udev/queue and clean up the idle processes. */ ++ ++ if (unlink("/run/udev/queue") < 0) { ++ if (errno != ENOENT) ++ log_warning_errno(errno, "Failed to unlink /run/udev/queue, ignoring: %m"); ++ } else ++ log_debug("No events are queued, removing /run/udev/queue."); + + if (!hashmap_isempty(manager->workers)) { + /* There are idle workers */ + \ No newline at end of file
View file
_service:tar_scm:backport-udev-rename-is_device_busy-event_is_blocked.patch
Added
@@ -0,0 +1,141 @@ +From a1fa99d84124cdcd4a306113ebe4febc1251c41c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 16:14:01 +0900 +Subject: PATCH udev: rename is_device_busy() -> event_is_blocked() + +Also this rename delaying_seqnum -> blocker_seqnum. + +Reference:https://github.com/systemd/systemd/commit/a1fa99d84124cdcd4a306113ebe4febc1251c41c +Conflict:NA + +--- + src/udev/udevd.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index e99c2c0..20bd556 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -126,7 +126,7 @@ typedef struct Event { + sd_device *dev_kernel; /* clone of originally received device */ + + uint64_t seqnum; +- uint64_t delaying_seqnum; ++ uint64_t blocker_seqnum; + + sd_event_source *timeout_warning_event; + sd_event_source *timeout_event; +@@ -773,8 +773,7 @@ static int event_run(Event *event) { + return 1; /* event is now processing. */ + } + +-/* lookup event for identical, parent, child device */ +-static int is_device_busy(Manager *manager, Event *event) { ++static int event_is_blocked(Event *event) { + const char *subsystem, *devpath, *devpath_old = NULL; + dev_t devnum = makedev(0, 0); + Event *loop_event; +@@ -782,6 +781,8 @@ static int is_device_busy(Manager *manager, Event *event) { + int r, ifindex = 0; + bool is_block; + ++ /* lookup event for identical, parent, child device */ ++ + r = sd_device_get_subsystem(event->dev, &subsystem); + if (r < 0) + return r; +@@ -807,21 +808,21 @@ static int is_device_busy(Manager *manager, Event *event) { + return r; + + /* check if queue contains events we depend on */ +- LIST_FOREACH(event, loop_event, manager->events) { ++ LIST_FOREACH(event, loop_event, event->manager->events) { + size_t loop_devpath_len, common; + const char *loop_devpath; + + /* we already found a later event, earlier cannot block us, no need to check again */ +- if (loop_event->seqnum < event->delaying_seqnum) ++ if (loop_event->seqnum < event->blocker_seqnum) + continue; + + /* event we checked earlier still exists, no need to check again */ +- if (loop_event->seqnum == event->delaying_seqnum) ++ if (loop_event->seqnum == event->blocker_seqnum) + return true; + + /* found ourself, no later event can block us */ + if (loop_event->seqnum >= event->seqnum) +- break; ++ return false; + + /* check major/minor */ + if (major(devnum) != 0) { +@@ -833,7 +834,7 @@ static int is_device_busy(Manager *manager, Event *event) { + + if (sd_device_get_devnum(loop_event->dev, &d) >= 0 && + devnum == d && is_block == streq(s, "block")) +- goto set_delaying_seqnum; ++ break; + } + + /* check network device ifindex */ +@@ -842,7 +843,7 @@ static int is_device_busy(Manager *manager, Event *event) { + + if (sd_device_get_ifindex(loop_event->dev, &i) >= 0 && + ifindex == i) +- goto set_delaying_seqnum; ++ break; + } + + if (sd_device_get_devpath(loop_event->dev, &loop_devpath) < 0) +@@ -850,7 +851,7 @@ static int is_device_busy(Manager *manager, Event *event) { + + /* check our old name */ + if (devpath_old && streq(devpath_old, loop_devpath)) +- goto set_delaying_seqnum; ++ break; + + loop_devpath_len = strlen(loop_devpath); + +@@ -863,24 +864,23 @@ static int is_device_busy(Manager *manager, Event *event) { + + /* identical device event found */ + if (devpath_len == loop_devpath_len) +- goto set_delaying_seqnum; ++ break; + + /* parent device event found */ + if (devpathcommon == '/') +- goto set_delaying_seqnum; ++ break; + + /* child device event found */ + if (loop_devpathcommon == '/') +- goto set_delaying_seqnum; ++ break; + } + +- return false; ++ assert(loop_event); + +-set_delaying_seqnum: + log_device_debug(event->dev, "SEQNUM=%" PRIu64 " blocked by SEQNUM=%" PRIu64, + event->seqnum, loop_event->seqnum); + +- event->delaying_seqnum = loop_event->seqnum; ++ event->blocker_seqnum = loop_event->seqnum; + return true; + } + +@@ -923,7 +923,7 @@ static int event_queue_start(Manager *manager) { + continue; + + /* do not start event if parent or child event is still running */ +- if (is_device_busy(manager, event) != 0) ++ if (event_is_blocked(event) != 0) + continue; + + r = event_run(event); +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-requeue-event-when-the-corresponding-block-device-is.patch
Added
@@ -0,0 +1,288 @@ +From 5d354e525a56955ae7f68062e283dda85ab07794 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Tue, 15 Mar 2022 13:50:06 +0900 +Subject: PATCH udev: requeue event when the corresponding block device is + locked by another process + +Previously, if a block device is locked by another process, then the +corresponding worker skip to process the corresponding event, and does +not broadcast the uevent to libudev listners. This causes several issues: + +- During a period of a device being locked by a process, if a user trigger + an event with `udevadm trigger --settle`, then it never returned. + +- When there is a delay between close and unlock in a process, then the + synthesized events triggered by inotify may not be processed. This can + happens easily by wrapping mkfs with flock. This causes severe issues + e.g. new devlinks are not created, or old devlinks are not removed. + +This commit makes events are requeued with a tiny delay when the corresponding +block devices are locked by other processes. With this way, the triggered +uevent may be delayed but is always processed by udevd. Hence, the above +issues can be solved. Also, it is not necessary to watch a block device +unconditionally when it is already locked. Hence, the logic is dropped. + +Reference:https://github.com/systemd/systemd/commit/5d354e525a56955ae7f68062e283dda85ab07794 +Conflict:adaption + +--- + src/udev/udevd.c | 154 +++++++++++++++++++++++++++++------------------ + 1 file changed, 97 insertions(+), 57 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index d153b03a38e1..973727375b67 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -70,6 +70,8 @@ + #include "version.h" + + #define WORKER_NUM_MAX 2048U ++#define EVENT_RETRY_INTERVAL_USEC (200 * USEC_PER_MSEC) ++#define EVENT_RETRY_TIMEOUT_USEC (3 * USEC_PER_MINUTE) + + static bool arg_debug = false; + static int arg_daemonize = false; +@@ -128,6 +130,8 @@ typedef struct Event { + sd_device_action_t action; + uint64_t seqnum; + uint64_t blocker_seqnum; ++ usec_t retry_again_next_usec; ++ usec_t retry_again_timeout_usec; + + sd_event_source *timeout_warning_event; + sd_event_source *timeout_event; +@@ -152,8 +156,13 @@ typedef struct Worker { + } Worker; + + /* passed from worker to main process */ +-typedef struct WorkerMessage { +-} WorkerMessage; ++typedef enum EventResult { ++ EVENT_RESULT_SUCCESS, ++ EVENT_RESULT_FAILED, ++ EVENT_RESULT_TRY_AGAIN, /* when the block device is locked by another process. */ ++ _EVENT_RESULT_MAX, ++ _EVENT_RESULT_INVALID = -EINVAL, ++} EventResult; + + static Event *event_free(Event *event) { + if (!event) +@@ -360,10 +369,11 @@ static void device_broadcast(sd_device_monitor *monitor, sd_device *dev) { + "Failed to broadcast event to libudev listeners, ignoring: %m"); + } + +-static int worker_send_message(int fd) { +- WorkerMessage message = {}; ++static int worker_send_result(Manager *manager, EventResult result) { ++ assert(manager); ++ assert(manager->worker_watchWRITE_END >= 0); + +- return loop_write(fd, &message, sizeof(message), false); ++ return loop_write(manager->worker_watchWRITE_END, &result, sizeof(result), false); + } + + static int worker_lock_block_device(sd_device *dev, int *ret_fd) { +@@ -490,44 +500,12 @@ static int worker_process_device(Manager *manager, sd_device *dev) { + if (!udev_event) + return -ENOMEM; + ++ /* If this is a block device and the device is locked currently via the BSD advisory locks, ++ * someone else is using it exclusively. We don't run our udev rules now to not interfere. ++ * Instead of processing the event, we requeue the event and will try again after a delay. ++ * ++ * The user-facing side of this: https://systemd.io/BLOCK_DEVICE_LOCKING */ + r = worker_lock_block_device(dev, &fd_lock); +- if (r == -EAGAIN) { +- /* So this is a block device and the device is locked currently via the BSD advisory locks — +- * someone else is exclusively using it. This means we don't run our udev rules now, to not +- * interfere. However we want to know when the device is unlocked again, and retrigger the +- * device again then, so that the rules are run eventually. For that we use IN_CLOSE_WRITE +- * inotify watches (which isn't exactly the same as waiting for the BSD locks to release, but +- * not totally off, as long as unlock+close() is done together, as it usually is). +- * +- * (The user-facing side of this: https://systemd.io/BLOCK_DEVICE_LOCKING) +- * +- * There's a bit of a chicken and egg problem here for this however: inotify watching is +- * supposed to be enabled via an option set via udev rules (OPTIONS+="watch"). If we skip the +- * udev rules here however (as we just said we do), we would thus never see that specific +- * udev rule, and thus never turn on inotify watching. But in order to catch up eventually +- * and run them we we need the inotify watching: hence a classic chicken and egg problem. +- * +- * Our way out here: if we see the block device locked, unconditionally watch the device via +- * inotify, regardless of any explicit request via OPTIONS+="watch". Thus, a device that is +- * currently locked via the BSD file locks will be treated as if we ran a single udev rule +- * only for it: the one that turns on inotify watching for it. If we eventually see the +- * inotify IN_CLOSE_WRITE event, and then run the rules after all and we then realize that +- * this wasn't actually requested (i.e. no OPTIONS+="watch" set) we'll simply turn off the +- * watching again (see below). Effectively this means: inotify watching is now enabled either +- * a) when the udev rules say so, or b) while the device is locked. +- * +- * Worst case scenario hence: in the (unlikely) case someone locked the device and we clash +- * with that we might do inotify watching for a brief moment for a device where we actually +- * weren't supposed to. But that shouldn't be too bad, in particular as BSD locks being taken +- * on a block device is kinda an indication that the inotify logic is desired too, to some +- * degree — they go hand-in-hand after all. */ +- +- log_device_debug(dev, "Block device is currently locked, installing watch to wait until the lock is released."); +- (void) udev_watch_begin(manager->inotify_fd, dev); +- +- /* Now the watch is installed, let's lock the device again, maybe in the meantime things changed */ +- r = worker_lock_block_device(dev, &fd_lock); +- } + if (r < 0) + return r; + +@@ -560,25 +538,29 @@ static int worker_process_device(Manager *manager, sd_device *dev) { + + static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *dev, void *userdata) { + Manager *manager = userdata; ++ EventResult result; + int r; + + assert(dev); + assert(manager); + + r = worker_process_device(manager, dev); +- if (r == -EAGAIN) +- /* if we couldn't acquire the flock(), then proceed quietly */ +- log_device_debug_errno(dev, r, "Device currently locked, not processing."); +- else { +- if (r < 0) +- log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m"); ++ if (r == -EAGAIN) { ++ /* if we couldn't acquire the flock(), then requeue the event */ ++ result = EVENT_RESULT_TRY_AGAIN; ++ log_device_debug_errno(dev, r, "Block device is currently locked, requeueing the event."); ++ } else if (r < 0) { ++ result = EVENT_RESULT_FAILED; ++ log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m"); ++ } else ++ result = EVENT_RESULT_SUCCESS; + ++ if (result != EVENT_RESULT_TRY_AGAIN) + /* send processed event back to libudev listeners */ + device_broadcast(monitor, dev); +- } + + /* send udevd the result of the event execution */ +- r = worker_send_message(manager->worker_watchWRITE_END); ++ r = worker_send_result(manager, result); + if (r < 0) + log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m"); + +@@ -794,6 +776,17 @@ static int event_is_blocked(Event *event) { + assert(event->manager); + assert(event->blocker_seqnum <= event->seqnum); + ++ if (event->retry_again_next_usec > 0) { ++ usec_t now_usec; ++ ++ r = sd_event_now(event->manager->event, clock_boottime_or_monotonic(), &now_usec); ++ if (r < 0) ++ return r; ++ ++ if (event->retry_again_next_usec <= now_usec) ++ return true; ++ } ++ + if (event->blocker_seqnum == event->seqnum) + /* we have checked previously and no blocker found */ + return false; +@@ -980,6 +973,44 @@ static int event_queue_start(Manager *manager) { + return 0; + } + ++static int event_requeue(Event *event) { ++ usec_t now_usec; ++ int r; ++ ++ assert(event); ++ assert(event->manager); ++ assert(event->manager->event); ++ ++ event->timeout_warning_event = sd_event_source_disable_unref(event->timeout_warning_event); ++ event->timeout_event = sd_event_source_disable_unref(event->timeout_event); ++ ++ /* add a short delay to suppress busy loop */ ++ r = sd_event_now(event->manager->event, clock_boottime_or_monotonic(), &now_usec); ++ if (r < 0) ++ return log_device_warning_errno(event->dev, r, ++ "Failed to get current time, " ++ "skipping event (SEQNUM=%"PRIu64", ACTION=%s): %m", ++ event->seqnum, strna(device_action_to_string(event->action))); ++ ++ if (event->retry_again_timeout_usec > 0 && event->retry_again_timeout_usec <= now_usec) ++ return log_device_warning_errno(event->dev, SYNTHETIC_ERRNO(ETIMEDOUT), ++ "The underlying block device is locked by a process more than %s, " ++ "skipping event (SEQNUM=%"PRIu64", ACTION=%s).", ++ format_timespan((charFORMAT_TIMESPAN_MAX){}, FORMAT_TIMESPAN_MAX, EVENT_RETRY_TIMEOUT_USEC, USEC_PER_MINUTE), ++ event->seqnum, strna(device_action_to_string(event->action))); ++ ++ event->retry_again_next_usec = usec_add(now_usec, EVENT_RETRY_INTERVAL_USEC); ++ if (event->retry_again_timeout_usec == 0) ++ event->retry_again_timeout_usec = usec_add(now_usec, EVENT_RETRY_TIMEOUT_USEC); ++ ++ if (event->worker && event->worker->event == event) ++ event->worker->event = NULL; ++ event->worker = NULL; ++ ++ event->state = EVENT_QUEUED; ++ return 0; ++} ++ + static int event_queue_insert(Manager *manager, sd_device *dev) { + sd_device_action_t action; + uint64_t seqnum; +@@ -1054,11 +1085,8 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat + assert(manager); + + for (;;) { +- WorkerMessage msg; +- struct iovec iovec = { +- .iov_base = &msg, +- .iov_len = sizeof(msg), +- }; ++ EventResult result; ++ struct iovec iovec = IOVEC_MAKE(&result, sizeof(result)); + CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; + struct msghdr msghdr = { + .msg_iov = &iovec, +@@ -1081,7 +1109,7 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat + + cmsg_close_all(&msghdr); + +- if (size != sizeof(WorkerMessage)) { ++ if (size != sizeof(EventResult)) { + log_warning("Ignoring worker message with invalid size %zi bytes", size); + continue; + } +@@ -1106,6 +1134,11 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat + worker->state = WORKER_IDLE; + + /* worker returned */ ++ if (result == EVENT_RESULT_TRY_AGAIN && ++ event_requeue(worker->event) < 0) ++ device_broadcast(manager->monitor, worker->event->dev); ++ ++ /* When event_requeue() succeeds, worker->event is NULL, and event_free() handles NULL gracefully. */ + event_free(worker->event); + } + +@@ -1467,8 +1500,15 @@ static int on_post(sd_event_source *s, void *userdata) { + + assert(manager); + +- if (!LIST_IS_EMPTY(manager->events)) ++ if (!LIST_IS_EMPTY(manager->events)) { ++ /* Try to process pending events if idle workers exist. Why is this necessary? ++ * When a worker finished an event and became idle, even if there was a pending event, ++ * the corresponding device might have been locked and the processing of the event ++ * delayed for a while, preventing the worker from processing the event immediately. ++ * Now, the device may be unlocked. Let's try again! */ ++ event_queue_start(manager); + return 1; ++ } + + /* There are no queued events. Let's remove /run/udev/queue and clean up the idle processes. */ + + \ No newline at end of file
View file
_service:tar_scm:backport-udev-skip-event-when-its-dependency-cannot-be-checked.patch
Added
@@ -0,0 +1,58 @@ +From c6f78234d1d1c6065ecc56240f217d1fdbeb1771 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 17 Jun 2021 17:14:10 +0900 +Subject: PATCH udev: skip event when its dependency cannot be checked + +Reference:https://github.com/systemd/systemd/commit/c6f78234d1d1c6065ecc56240f217d1fdbeb1771 +Conflict:NA + +--- + src/udev/udevd.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index be2c3ee..683938d 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -910,7 +910,7 @@ no_blocker: + } + + static int event_queue_start(Manager *manager) { +- Event *event; ++ Event *event, *event_next; + usec_t usec; + int r; + +@@ -943,12 +943,26 @@ static int event_queue_start(Manager *manager) { + return log_warning_errno(r, "Failed to read udev rules: %m"); + } + +- LIST_FOREACH(event, event, manager->events) { ++ LIST_FOREACH_SAFE(event, event, event_next, manager->events) { + if (event->state != EVENT_QUEUED) + continue; + +- /* do not start event if parent or child event is still running */ +- if (event_is_blocked(event) != 0) ++ /* do not start event if parent or child event is still running or queued */ ++ r = event_is_blocked(event); ++ if (r < 0) { ++ sd_device_action_t a = _SD_DEVICE_ACTION_INVALID; ++ ++ (void) sd_device_get_action(event->dev, &a); ++ log_device_warning_errno(event->dev, r, ++ "Failed to check event dependency, " ++ "skipping event (SEQNUM=%"PRIu64", ACTION=%s)", ++ event->seqnum, ++ strna(device_action_to_string(a))); ++ ++ event_free(event); ++ return r; ++ } ++ if (r > 0) + continue; + + r = event_run(event); +-- +2.33.0 + \ No newline at end of file
View file
_service:tar_scm:backport-udev-split-worker_lock_block_device-into-two.patch
Added
@@ -0,0 +1,123 @@ +From 7b7959fba52ba4bb6b5f7001971917760df40fee Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 25 Mar 2022 02:55:25 +0900 +Subject: PATCH udev: split worker_lock_block_device() into two + +This also makes return value initialized when these function return 0 to +follow our coding style. + +Just a preparation for later commits. + +Reference:https://github.com/systemd/systemd/commit/7b7959fba52ba4bb6b5f7001971917760df40fee +Conflict:NA + +--- + src/udev/udevd.c | 54 ++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 41 insertions(+), 13 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 973727375b67..0b620cb7dcac 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -376,35 +376,29 @@ static int worker_send_result(Manager *manager, EventResult result) { + return loop_write(manager->worker_watchWRITE_END, &result, sizeof(result), false); + } + +-static int worker_lock_block_device(sd_device *dev, int *ret_fd) { +- _cleanup_close_ int fd = -1; ++static int device_get_block_device(sd_device *dev, const char **ret) { + const char *val; + int r; + + assert(dev); +- assert(ret_fd); +- +- /* Take a shared lock on the device node; this establishes a concept of device "ownership" to +- * serialize device access. External processes holding an exclusive lock will cause udev to skip the +- * event handling; in the case udev acquired the lock, the external process can block until udev has +- * finished its event handling. */ ++ assert(ret); + + if (device_for_action(dev, SD_DEVICE_REMOVE)) +- return 0; ++ goto irrelevant; + + r = sd_device_get_subsystem(dev, &val); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to get subsystem: %m"); + + if (!streq(val, "block")) +- return 0; ++ goto irrelevant; + + r = sd_device_get_sysname(dev, &val); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to get sysname: %m"); + + if (STARTSWITH_SET(val, "dm-", "md", "drbd")) +- return 0; ++ goto irrelevant; + + r = sd_device_get_devtype(dev, &val); + if (r < 0 && r != -ENOENT) +@@ -417,16 +411,46 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) { + + r = sd_device_get_devname(dev, &val); + if (r == -ENOENT) +- return 0; ++ goto irrelevant; + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to get devname: %m"); + ++ *ret = val; ++ return 1; ++ ++irrelevant: ++ *ret = NULL; ++ return 0; ++} ++ ++static int worker_lock_block_device(sd_device *dev, int *ret_fd) { ++ _cleanup_close_ int fd = -1; ++ const char *val; ++ int r; ++ ++ assert(dev); ++ assert(ret_fd); ++ ++ /* Take a shared lock on the device node; this establishes a concept of device "ownership" to ++ * serialize device access. External processes holding an exclusive lock will cause udev to skip the ++ * event handling; in the case udev acquired the lock, the external process can block until udev has ++ * finished its event handling. */ ++ ++ r = device_get_block_device(dev, &val); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ goto nolock; ++ + fd = open(val, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK); + if (fd < 0) { + bool ignore = ERRNO_IS_DEVICE_ABSENT(errno); + + log_device_debug_errno(dev, errno, "Failed to open '%s'%s: %m", val, ignore ? ", ignoring" : ""); +- return ignore ? 0 : -errno; ++ if (!ignore) ++ return -errno; ++ ++ goto nolock; + } + + if (flock(fd, LOCK_SH|LOCK_NB) < 0) +@@ -434,6 +458,10 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) { + + *ret_fd = TAKE_FD(fd); + return 1; ++ ++nolock: ++ *ret_fd = -1; ++ return 0; + } + + static int worker_mark_block_device_read_only(sd_device *dev) { + \ No newline at end of file
View file
_service:tar_scm:backport-udev-store-action-in-struct-Event.patch
Added
@@ -0,0 +1,71 @@ +From 0c3d8182c997c979c7a0ccce88d9fc48638261a5 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 25 Mar 2022 02:39:55 +0900 +Subject: PATCH udev: store action in struct Event + +Reference:https://github.com/systemd/systemd/commit/0c3d8182c997c979c7a0ccce88d9fc48638261a5 +Conflict:NA + +--- + src/udev/udevd.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 53728c9f7971..d153b03a38e1 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -125,6 +125,7 @@ typedef struct Event { + + sd_device *dev; + ++ sd_device_action_t action; + uint64_t seqnum; + uint64_t blocker_seqnum; + +@@ -964,16 +965,12 @@ static int event_queue_start(Manager *manager) { + r = event_is_blocked(event); + if (r > 0) + continue; +- if (r < 0) { +- sd_device_action_t a = _SD_DEVICE_ACTION_INVALID; +- +- (void) sd_device_get_action(event->dev, &a); ++ if (r < 0) + log_device_warning_errno(event->dev, r, + "Failed to check dependencies for event (SEQNUM=%"PRIu64", ACTION=%s), " + "assuming there is no blocking event, ignoring: %m", + event->seqnum, +- strna(device_action_to_string(a))); +- } ++ strna(device_action_to_string(event->action))); + + r = event_run(event); + if (r <= 0) /* 0 means there are no idle workers. Let's escape from the loop. */ +@@ -984,6 +981,7 @@ static int event_queue_start(Manager *manager) { + } + + static int event_queue_insert(Manager *manager, sd_device *dev) { ++ sd_device_action_t action; + uint64_t seqnum; + Event *event; + int r; +@@ -999,6 +997,10 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { + if (r < 0) + return r; + ++ r = sd_device_get_action(dev, &action); ++ if (r < 0) ++ return r; ++ + event = new(Event, 1); + if (!event) + return -ENOMEM; +@@ -1007,6 +1009,7 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { + .manager = manager, + .dev = sd_device_ref(dev), + .seqnum = seqnum, ++ .action = action, + .state = EVENT_QUEUED, + }; + +
View file
_service:tar_scm:backport-udev-update-comment-and-log-messages.patch
Added
@@ -0,0 +1,31 @@ +From 87afc766d199642c6da956657b05690a39542856 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Sat, 12 Mar 2022 20:48:36 +0900 +Subject: PATCH udev: update comment and log message + +Reference:https://github.com/systemd/systemd/commit/87afc766d199642c6da956657b05690a39542856 +Conflict:NA + +--- + src/udev/udevd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 41d0ec1e137c..0407068d5112 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -1448,10 +1448,11 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi + device_tag_index(worker->event->dev, NULL, false); + + if (manager->monitor) { +- /* forward kernel event without amending it */ ++ /* Forward kernel event unchanged */ + r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel); + if (r < 0) +- log_device_error_errno(worker->event->dev_kernel, r, "Failed to send back device to kernel: %m"); ++ log_device_warning_errno(worker->event->dev_kernel, r, ++ "Failed to broadcast failed event to libudev listeners, ignoring: %m"); + } + } + + \ No newline at end of file
View file
_service:tar_scm:backport-udev-update-log-message-to-clarify-that-the-error-is-ignored.patch
Added
@@ -0,0 +1,36 @@ +From 6be97d67c82ef5f45360c4323616739816b8f833 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Wed, 16 Jun 2021 21:02:01 +0900 +Subject: PATCH udev: update log message to clarify that the error is ignored + +Reference:https://github.com/systemd/systemd/commit/6be97d67c82ef5f45360c4323616739816b8f833 +Conflict:NA + +--- + src/udev/udevd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 546bfe039e1d..34a5c9d5d8ee 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -171,8 +171,8 @@ static void event_free(Event *event) { + /* only clean up the queue from the process that created it */ + if (LIST_IS_EMPTY(event->manager->events) && + event->manager->pid == getpid_cached()) +- if (unlink("/run/udev/queue") < 0) +- log_warning_errno(errno, "Failed to unlink /run/udev/queue: %m"); ++ if (unlink("/run/udev/queue") < 0 && errno != ENOENT) ++ log_warning_errno(errno, "Failed to unlink /run/udev/queue, ignoring: %m"); + + free(event); + } +@@ -965,7 +965,7 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { + if (LIST_IS_EMPTY(manager->events)) { + r = touch("/run/udev/queue"); + if (r < 0) +- log_warning_errno(r, "Failed to touch /run/udev/queue: %m"); ++ log_warning_errno(r, "Failed to touch /run/udev/queue, ignoring: %m"); + } + + LIST_APPEND(event, manager->events, event);
View file
_service:tar_scm:backport-units-remove-the-restart-limit-on-the-modprobe-.serv.patch
Added
@@ -0,0 +1,36 @@ +From 639423416c18c3a41a8f326618e340c25585a40a Mon Sep 17 00:00:00 2001 +From: Alban Bedel <alban.bedel@aerq.com> +Date: Wed, 15 Jun 2022 13:12:46 +0200 +Subject: PATCH units: remove the restart limit on the modprobe@.service + +They are various cases where the same module might be repeatedly +loaded in a short time frame, for example if a service depending on a +module keep restarting, or if many instances of such service get +started at the same time. If this happend the modprobe@.service +instance will be marked as failed because it hit the restart limit. + +Overall it doesn't seems to make much sense to have a restart limit on +the modprobe service so just disable it. + +Fixes: #23742 +(cherry picked from commit 9625350e5381a68c1179ae4581e7586c206663e1) +(cherry picked from commit 8539a62207c9d0cc1656458eb53ffc9177b2c7c8) +--- + units/modprobe@.service | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/modprobe@.service b/units/modprobe@.service +index cf8baf6084..85a2c08dee 100644 +--- a/units/modprobe@.service ++++ b/units/modprobe@.service +@@ -13,6 +13,7 @@ DefaultDependencies=no + Before=sysinit.target + Documentation=man:modprobe(8) + ConditionCapability=CAP_SYS_MODULE ++StartLimitIntervalSec=0 + + Service + Type=oneshot +-- +2.33.0 +
View file
_service:tar_scm:core-cgroup-support-default-slice-for-all-uni.patch
Changed
@@ -71,9 +71,9 @@ typedef struct Manager Manager; @@ -445,6 +446,7 @@ struct Manager { + unsigned sigchldgen; unsigned notifygen; - bool honor_device_enumeration; + char *default_unit_slice; bool in_manager_catchup;
View file
_service:tar_scm:core-skip-change-device-to-dead-in-manager_catchup-d.patch
Changed
@@ -15,16 +15,16 @@ daemon-reload, if boot time is more than 10min, just ensure fs will not unmounted during 10min after booting. --- - src/core/device.c | 16 ++++++++++++++++- + src/core/device.c | 16 +++++++++++++++- src/core/manager.c | 5 +++++ - src/core/manager.h | 1 + - 3 files changed, 21 insertions(+), 1 deletion(-) + src/core/manager.h | 2 ++ + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/device.c b/src/core/device.c -index 8f30c4e..71cb2a1 100644 +index 58007cc..7be59bd 100644 --- a/src/core/device.c +++ b/src/core/device.c -@@ -646,7 +647,10 @@ static int device_process_new(Manager *m, sd_device *dev) { +@@ -728,7 +728,10 @@ static void device_process_new(Manager *m, sd_device *dev) { } static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) { @@ -35,7 +35,7 @@ /* Didn't exist before, but does now? if so, generate a new invocation ID for it */ if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND) -@@ -659,10 +663,21 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no +@@ -741,10 +744,21 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no /* If the device has not been seen by udev yet, but is now referenced by the kernel, then we assume the * kernel knows it now, and udev might soon too. */ device_set_state(d, DEVICE_TENTATIVE); @@ -59,10 +59,10 @@ static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) { diff --git a/src/core/manager.c b/src/core/manager.c -index 41b7cf7..b948ac6 100644 +index 5becd30..c5dd041 100644 --- a/src/core/manager.c +++ b/src/core/manager.c -@@ -788,6 +788,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager +@@ -811,6 +811,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager .test_run_flags = test_run_flags, .default_oom_policy = OOM_STOP, @@ -70,7 +70,7 @@ }; #if ENABLE_EFI -@@ -1475,6 +1476,8 @@ static void manager_catchup(Manager *m) { +@@ -1579,6 +1580,8 @@ static void manager_catchup(Manager *m) { log_debug("Invoking unit catchup() handlers…"); @@ -79,7 +79,7 @@ /* Let's catch up on any state changes that happened while we were reloading/reexecing */ HASHMAP_FOREACH_KEY(u, k, m->units) { -@@ -1484,6 +1487,8 @@ static void manager_catchup(Manager *m) { +@@ -1588,6 +1591,8 @@ static void manager_catchup(Manager *m) { unit_catchup(u); } @@ -89,17 +89,18 @@ static void manager_distribute_fds(Manager *m, FDSet *fds) { diff --git a/src/core/manager.h b/src/core/manager.h -index d1e540a..73c149f 100644 +index 67c204f..d298dce 100644 --- a/src/core/manager.h +++ b/src/core/manager.h -@@ -423,6 +423,7 @@ struct Manager { +@@ -442,6 +442,8 @@ struct Manager { + unsigned sigchldgen; unsigned notifygen; - bool honor_device_enumeration; + bool in_manager_catchup; - ++ VarlinkServer *varlink_server; /* Only systemd-oomd should be using this to subscribe to changes in ManagedOOM settings */ + Varlink *managed_oom_varlink_request; -- -2.23.0 +2.33.0
View file
_service:tar_scm:fix-mount-failed-while-daemon-reexec.patch
Changed
@@ -2,30 +2,30 @@ From: licunlong <licunlong1@huawei.com> Date: Tue, 28 Jun 2022 21:56:26 +0800 Subject: PATCH fix mount failed while daemon-reexec - + --- src/core/manager.c | 1 + src/core/manager.h | 1 + src/core/mount.c | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) - + diff --git a/src/core/manager.c b/src/core/manager.c -index 5dff366..45c4ae0 100644 +index 55adcd1..74f8304 100644 --- a/src/core/manager.c +++ b/src/core/manager.c -@@ -1762,6 +1762,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { +@@ -1808,6 +1808,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { } manager_ready(m); + m->mountinfo_uptodate = false; - return 0; - } + manager_set_switching_root(m, false); + diff --git a/src/core/manager.h b/src/core/manager.h -index cf6cd64..663fe8d 100644 +index 31b4670..df74200 100644 --- a/src/core/manager.h +++ b/src/core/manager.h -@@ -238,6 +238,7 @@ struct Manager { +@@ -259,6 +259,7 @@ struct Manager { /* Data specific to the mount subsystem */ struct libmnt_monitor *mount_monitor; sd_event_source *mount_event_source; @@ -34,10 +34,10 @@ /* Data specific to the swap filesystem */ FILE *proc_swaps; diff --git a/src/core/mount.c b/src/core/mount.c -index 6e514d5..25b0460 100644 +index 8fed04c..00482e9 100644 --- a/src/core/mount.c +++ b/src/core/mount.c -@@ -1684,6 +1684,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { +@@ -1785,6 +1785,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { (void) mount_setup_unit(m, device, path, options, fstype, set_flags); } @@ -45,7 +45,7 @@ return 0; } -@@ -1842,8 +1843,10 @@ static int mount_process_proc_self_mountinfo(Manager *m) { +@@ -1948,8 +1949,10 @@ static int mount_process_proc_self_mountinfo(Manager *m) { assert(m); r = drain_libmount(m); @@ -59,3 +59,4 @@ if (r < 0) { -- 2.33.0 +
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2