backport upstream patches to fix event loss when the whole disk is locked
This commit is contained in:
parent
d426c1fb9f
commit
1d68f589fa
@ -5,32 +5,32 @@ Subject: [PATCH] Retry to handle the uevent when worker is terminated abnormal
|
||||
|
||||
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 @@ index eb94ed3..5b743ad 100644
|
||||
+ 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
|
||||
|
||||
|
||||
75
backport-errno-util-add-ERRNO_IS_DEVICE_ABSENT-macro.patch
Normal file
75
backport-errno-util-add-ERRNO_IS_DEVICE_ABSENT-macro.patch
Normal file
@ -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. */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
28
backport-udev-add-usec_add-at-one-more-place.patch
Normal file
28
backport-udev-add-usec_add-at-one-more-place.patch
Normal file
@ -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
|
||||
|
||||
350
backport-udev-also-rename-struct-udev_ctrl-UdevCtrl.patch
Normal file
350
backport-udev-also-rename-struct-udev_ctrl-UdevCtrl.patch
Normal file
@ -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 version[16];
|
||||
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 buf[256];
|
||||
-};
|
||||
+} 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_watch[2];
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -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(). */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
36
backport-udev-make-event_free-return-NULL.patch
Normal file
36
backport-udev-make-event_free-return-NULL.patch
Normal file
@ -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) {
|
||||
@ -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
|
||||
|
||||
544
backport-udev-move-several-functions.patch
Normal file
544
backport-udev-move-several-functions.patch
Normal file
@ -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_watch[READ_END] = safe_close(manager->worker_watch[READ_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_watch[READ_END] = safe_close(manager->worker_watch[READ_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
|
||||
@ -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)
|
||||
|
||||
89
backport-udev-propagate-error-on-spawning-a-worker.patch
Normal file
89
backport-udev-propagate-error-on-spawning-a-worker.patch
Normal file
@ -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
|
||||
|
||||
53
backport-udev-remove-run-udev-queue-in-on_post.patch
Normal file
53
backport-udev-remove-run-udev-queue-in-on_post.patch
Normal file
@ -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 */
|
||||
|
||||
141
backport-udev-rename-is_device_busy-event_is_blocked.patch
Normal file
141
backport-udev-rename-is_device_busy-event_is_blocked.patch
Normal file
@ -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 (devpath[common] == '/')
|
||||
- goto set_delaying_seqnum;
|
||||
+ break;
|
||||
|
||||
/* child device event found */
|
||||
if (loop_devpath[common] == '/')
|
||||
- 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
|
||||
|
||||
@ -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_watch[WRITE_END] >= 0);
|
||||
|
||||
- return loop_write(fd, &message, sizeof(message), false);
|
||||
+ return loop_write(manager->worker_watch[WRITE_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_watch[WRITE_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((char[FORMAT_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. */
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
123
backport-udev-split-worker_lock_block_device-into-two.patch
Normal file
123
backport-udev-split-worker_lock_block_device-into-two.patch
Normal file
@ -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_watch[WRITE_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) {
|
||||
|
||||
71
backport-udev-store-action-in-struct-Event.patch
Normal file
71
backport-udev-store-action-in-struct-Event.patch
Normal file
@ -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,
|
||||
};
|
||||
|
||||
|
||||
31
backport-udev-update-comment-and-log-messages.patch
Normal file
31
backport-udev-update-comment-and-log-messages.patch
Normal file
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
32
systemd.spec
32
systemd.spec
@ -21,7 +21,7 @@
|
||||
Name: systemd
|
||||
Url: https://www.freedesktop.org/wiki/Software/systemd
|
||||
Version: 249
|
||||
Release: 50
|
||||
Release: 51
|
||||
License: MIT and LGPLv2+ and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
|
||||
@ -451,6 +451,33 @@ Patch6403: backport-core-unit-merge-two-loops-into-one.patch
|
||||
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
|
||||
|
||||
Patch9001: update-rtc-with-system-clock-when-shutdown.patch
|
||||
Patch9002: udev-add-actions-while-rename-netif-failed.patch
|
||||
@ -1922,6 +1949,9 @@ fi
|
||||
%{_libdir}/security/pam_systemd.so
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user