Message ID | 20240511040811.336618-1-ranjitsinhrathod1991@gmail.com |
---|---|
State | Rejected |
Delegated to: | Steve Sakoman |
Headers | show |
Series | [kirkstone] systemd: Add patches to fix systemd-udev delay during initialization | expand |
Perhaps it’s better to provide a newer systemd including these patches via a mixin layer? It’s an invasive backport and not really suitable for lts. Alex On Sat 11. May 2024 at 6.08, Ranjitsinh Rathod via lists.openembedded.org <ranjitsinhrathod1991=gmail.com@lists.openembedded.org> wrote: > From: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > > Below upstream systemd PR fixes overall delay in systemd-udev in > initialization by removing multiple for loops along with delays in those > loops > By applying these patches from the PR improves almost 800 - 900 ms in > the initialization > By this system boots up fasts and also avoids some issues related to > this delay > > PR link: https://github.com/systemd/systemd/pull/23043 > > Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > Signed-off-by: Ranjitsinh Rathod <ranjitsinhrathod1991@gmail.com> > --- > ...0001-udev-move-udev_node_escape_path.patch | 120 ++++++++ > ...update-and-introduce-stack_directory.patch | 90 ++++++ > ...ve-stack-directory-even-if-it-is-emp.patch | 267 +++++++++++++++++ > ...-introduce-path_make_relative_parent.patch | 99 +++++++ > .../0005-udev-use-readlinkat_malloc.patch | 74 +++++ > ...-link_find_prioritized-and-variables.patch | 190 ++++++++++++ > ...7-udev-use-path_make_relative_parent.patch | 43 +++ > ...ake-node_symlink-accept-NULL-devname.patch | 75 +++++ > ...k-when-updating-device-node-symlinks.patch | 277 ++++++++++++++++++ > ...ck-directory-run-udev-links-when-all.patch | 130 ++++++++ > meta/recipes-core/systemd/systemd_250.5.bb | 10 + > 11 files changed, 1375 insertions(+) > create mode 100644 > meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch > create mode 100644 > meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch > > diff --git > a/meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch > b/meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch > new file mode 100644 > index 0000000000..900ca81170 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch > @@ -0,0 +1,120 @@ > +From b9168275c39a190441fee73ba1c8a64515fd3b0e Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 11:25:37 +0900 > +Subject: [PATCH 01/10] udev: move udev_node_escape_path() > + > +No functionality is changed. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/b9168275c39a190441fee73ba1c8a64515fd3b0e > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 84 ++++++++++++++++++++++---------------------- > + 1 file changed, 42 insertions(+), 42 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index bb34977d97..79d050cce6 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -222,48 +222,6 @@ static int link_find_prioritized(sd_device *dev, > bool add, const char *stackdir, > + return !!*ret; > + } > + > +-size_t udev_node_escape_path(const char *src, char *dest, size_t size) { > +- size_t i, j; > +- uint64_t h; > +- > +- assert(src); > +- assert(dest); > +- assert(size >= 12); > +- > +- for (i = 0, j = 0; src[i] != '\0'; i++) { > +- if (src[i] == '/') { > +- if (j+4 >= size - 12 + 1) > +- goto toolong; > +- memcpy(&dest[j], "\\x2f", 4); > +- j += 4; > +- } else if (src[i] == '\\') { > +- if (j+4 >= size - 12 + 1) > +- goto toolong; > +- memcpy(&dest[j], "\\x5c", 4); > +- j += 4; > +- } else { > +- if (j+1 >= size - 12 + 1) > +- goto toolong; > +- dest[j] = src[i]; > +- j++; > +- } > +- } > +- dest[j] = '\0'; > +- return j; > +- > +-toolong: > +- /* If the input path is too long to encode as a filename, then > let's suffix with a string > +- * generated from the hash of the path. */ > +- > +- h = siphash24_string(src, UDEV_NODE_HASH_KEY.bytes); > +- > +- for (unsigned k = 0; k <= 10; k++) > +- dest[size - k - 2] = urlsafe_base64char((h >> (k * 6)) & > 63); > +- > +- dest[size - 1] = '\0'; > +- return size - 1; > +-} > +- > + static int update_timestamp(sd_device *dev, const char *path, struct > stat *prev) { > + assert(path); > + assert(prev); > +@@ -414,6 +372,48 @@ static int update_stack_directory(sd_device *dev, > const char *dirname, bool add) > + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ELOOP), > "Failed to create symbolic link %s: %m", filename); > + } > + > ++size_t udev_node_escape_path(const char *src, char *dest, size_t size) { > ++ size_t i, j; > ++ uint64_t h; > ++ > ++ assert(src); > ++ assert(dest); > ++ assert(size >= 12); > ++ > ++ for (i = 0, j = 0; src[i] != '\0'; i++) { > ++ if (src[i] == '/') { > ++ if (j+4 >= size - 12 + 1) > ++ goto toolong; > ++ memcpy(&dest[j], "\\x2f", 4); > ++ j += 4; > ++ } else if (src[i] == '\\') { > ++ if (j+4 >= size - 12 + 1) > ++ goto toolong; > ++ memcpy(&dest[j], "\\x5c", 4); > ++ j += 4; > ++ } else { > ++ if (j+1 >= size - 12 + 1) > ++ goto toolong; > ++ dest[j] = src[i]; > ++ j++; > ++ } > ++ } > ++ dest[j] = '\0'; > ++ return j; > ++ > ++toolong: > ++ /* If the input path is too long to encode as a filename, then > let's suffix with a string > ++ * generated from the hash of the path. */ > ++ > ++ h = siphash24_string(src, UDEV_NODE_HASH_KEY.bytes); > ++ > ++ for (unsigned k = 0; k <= 10; k++) > ++ dest[size - k - 2] = urlsafe_base64char((h >> (k * 6)) & > 63); > ++ > ++ dest[size - 1] = '\0'; > ++ return size - 1; > ++} > ++ > + /* manage "stack of names" with possibly specified device priorities */ > + static int link_update(sd_device *dev, const char *slink_in, bool add) { > + _cleanup_free_ char *slink = NULL, *dirname = NULL; > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch > b/meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch > new file mode 100644 > index 0000000000..edc7ab5b38 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch > @@ -0,0 +1,90 @@ > +From 7e7c36fbbb396364c386bf1edbe9b25179a134c6 Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 11:26:08 +0900 > +Subject: [PATCH 02/10] udev: split link_update() and introduce > + stack_directory_get_name() > + > +No functionality is changed. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/7e7c36fbbb396364c386bf1edbe9b25179a134c6 > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 52 ++++++++++++++++++++++++++++---------------- > + 1 file changed, 33 insertions(+), 19 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index 79d050cce6..b4b865c021 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -414,33 +414,47 @@ toolong: > + return size - 1; > + } > + > +-/* manage "stack of names" with possibly specified device priorities */ > +-static int link_update(sd_device *dev, const char *slink_in, bool add) { > +- _cleanup_free_ char *slink = NULL, *dirname = NULL; > +- const char *slink_name; > ++static int stack_directory_get_name(const char *slink, char **ret) { > ++ _cleanup_free_ char *s = NULL, *dirname = NULL; > + char name_enc[NAME_MAX+1]; > +- int r; > ++ const char *name; > + > +- assert(dev); > +- assert(slink_in); > ++ assert(slink); > ++ assert(ret); > + > +- slink = strdup(slink_in); > +- if (!slink) > +- return log_oom_debug(); > ++ s = strdup(slink); > ++ if (!s) > ++ return -ENOMEM; > + > +- path_simplify(slink); > ++ path_simplify(s); > + > +- slink_name = path_startswith(slink, "/dev"); > +- if (!slink_name || > +- empty_or_root(slink_name) || > +- !path_is_normalized(slink_name)) > +- return log_device_debug_errno(dev, > SYNTHETIC_ERRNO(EINVAL), > +- "Invalid symbolic link of > device node: %s", slink); > ++ if (!path_is_normalized(s)) > ++ return -EINVAL; > ++ > ++ name = path_startswith(s, "/dev"); > ++ if (empty_or_root(name)) > ++ return -EINVAL; > ++ > ++ udev_node_escape_path(name, name_enc, sizeof(name_enc)); > + > +- (void) udev_node_escape_path(slink_name, name_enc, > sizeof(name_enc)); > + dirname = path_join("/run/udev/links", name_enc); > + if (!dirname) > +- return log_oom_debug(); > ++ return -ENOMEM; > ++ > ++ *ret = TAKE_PTR(dirname); > ++ return 0; > ++} > ++ > ++static int link_update(sd_device *dev, const char *slink, bool add) { > ++ _cleanup_free_ char *dirname = NULL; > ++ int r; > ++ > ++ assert(dev); > ++ assert(slink); > ++ > ++ r = stack_directory_get_name(slink, &dirname); > ++ if (r < 0) > ++ return log_device_debug_errno(dev, r, "Failed to build > stack directory name for '%s': %m", slink); > + > + r = update_stack_directory(dev, dirname, add); > + if (r < 0) > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch > b/meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch > new file mode 100644 > index 0000000000..6d2b178bd4 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch > @@ -0,0 +1,267 @@ > +From a28d67a90374a9d11bd5635f81961f72e5a8b33e Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 11:47:20 +0900 > +Subject: [PATCH 03/10] udev: do not remove stack directory even if it is > empty > + > +Then, we can always assume the directory exists, and the code become > +slightly simpler. > + > +Note, unused directories are removed by the main udevd process in a > +later commit. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/a28d67a90374a9d11bd5635f81961f72e5a8b33e > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 158 +++++++++++++++++-------------------------- > + 1 file changed, 61 insertions(+), 97 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index b4b865c021..6ead839a5f 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -35,7 +35,6 @@ > + > + #define CREATE_LINK_MAX_RETRIES 128 > + #define LINK_UPDATE_MAX_RETRIES 128 > +-#define CREATE_STACK_LINK_MAX_RETRIES 128 > + #define UPDATE_TIMESTAMP_MAX_RETRIES 128 > + #define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC) > + #define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC) > +@@ -140,15 +139,8 @@ static int link_find_prioritized(sd_device *dev, > bool add, const char *stackdir, > + } > + > + dir = opendir(stackdir); > +- if (!dir) { > +- if (add) /* The stack directory must exist. */ > +- return -errno; > +- if (errno != ENOENT) > +- return -errno; > +- > +- *ret = NULL; > +- return 0; > +- } > ++ if (!dir) > ++ return -errno; > + > + r = device_get_device_id(dev, &id); > + if (r < 0) > +@@ -222,8 +214,8 @@ static int link_find_prioritized(sd_device *dev, bool > add, const char *stackdir, > + return !!*ret; > + } > + > +-static int update_timestamp(sd_device *dev, const char *path, struct > stat *prev) { > +- assert(path); > ++static int update_timestamp(sd_device *dev, int fd, struct stat *prev) { > ++ assert(fd >= 0); > + assert(prev); > + > + /* Even if a symlink in the stack directory is created/removed, > the mtime of the directory may > +@@ -247,129 +239,96 @@ static int update_timestamp(sd_device *dev, const > char *path, struct stat *prev) > + * timestamp of the stack directory is always increased at least > in the above step 5, so A can > + * detect the update. */ > + > +- if ((prev->st_mode & S_IFMT) == 0) > +- return 0; /* Does not exist, or previous stat() failed. > */ > +- > + for (unsigned i = 0; i < UPDATE_TIMESTAMP_MAX_RETRIES; i++) { > + struct stat st; > + > +- if (stat(path, &st) < 0) > ++ if (fstat(fd, &st) < 0) > + return -errno; > + > + if (!stat_inode_unmodified(prev, &st)) > + return 0; > + > + log_device_debug(dev, > +- "%s is modified, but its timestamp is > not changed, " > +- "updating timestamp after 10ms.", > +- path); > ++ "Stack directory is modified, but its > timestamp is not changed, " > ++ "updating timestamp after 10ms."); > + > + (void) usleep(10 * USEC_PER_MSEC); > +- if (utimensat(AT_FDCWD, path, NULL, 0) < 0) > ++ if (futimens(fd, NULL) < 0) > + return -errno; > + } > + > + return -ELOOP; > + } > + > +-static int update_stack_directory(sd_device *dev, const char *dirname, > bool add) { > +- _cleanup_free_ char *filename = NULL, *data = NULL, *buf = NULL; > +- const char *devname, *id; > +- struct stat st = {}; > +- int priority, r; > ++static int stack_directory_update(sd_device *dev, int fd, bool add) { > ++ struct stat st; > ++ const char *id; > ++ int r; > + > + assert(dev); > +- assert(dirname); > ++ assert(fd >= 0); > + > + r = device_get_device_id(dev, &id); > + if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to get > device id: %m"); > +- > +- filename = path_join(dirname, id); > +- if (!filename) > +- return log_oom_debug(); > ++ return r; > + > +- if (!add) { > +- int unlink_error = 0, stat_error = 0; > ++ if (fstat(fd, &st) < 0) > ++ return -errno; > + > +- if (stat(dirname, &st) < 0) { > +- if (errno == ENOENT) > +- return 0; /* The stack directory is > already removed. That's OK. */ > +- stat_error = -errno; > +- } > ++ if (add) { > ++ _cleanup_free_ char *data = NULL, *buf = NULL; > ++ const char *devname; > ++ int priority; > + > +- if (unlink(filename) < 0) > +- unlink_error = -errno; > ++ r = sd_device_get_devname(dev, &devname); > ++ if (r < 0) > ++ return r; > + > +- if (rmdir(dirname) >= 0 || errno == ENOENT) > +- return 0; > ++ r = device_get_devlink_priority(dev, &priority); > ++ if (r < 0) > ++ return r; > + > +- if (unlink_error < 0) { > +- if (unlink_error == -ENOENT) > +- return 0; > ++ if (asprintf(&data, "%i:%s", priority, devname) < 0) > ++ return -ENOMEM; > + > +- /* If we failed to remove the symlink, then > there is almost nothing we can do. */ > +- return log_device_debug_errno(dev, unlink_error, > "Failed to remove %s: %m", filename); > +- } > ++ if (readlinkat_malloc(fd, id, &buf) >= 0 && streq(buf, > data)) > ++ return 0; /* Unchanged. */ > + > +- if (stat_error < 0) > +- return log_device_debug_errno(dev, stat_error, > "Failed to stat %s: %m", dirname); > ++ (void) unlinkat(fd, id, 0); > + > +- /* The symlink was removed. Check if the timestamp of > directory is changed. */ > +- r = update_timestamp(dev, dirname, &st); > +- if (r < 0 && r != -ENOENT) > +- return log_device_debug_errno(dev, r, "Failed to > update timestamp of %s: %m", dirname); > ++ if (symlinkat(data, fd, id) < 0) > ++ return -errno; > + > +- return 0; > ++ } else { > ++ if (unlinkat(fd, id, 0) < 0) { > ++ if (errno == ENOENT) > ++ return 0; /* Unchanged. */ > ++ return -errno; > ++ } > + } > + > +- r = sd_device_get_devname(dev, &devname); > ++ r = update_timestamp(dev, fd, &st); > + if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to get > device node: %m"); > +- > +- r = device_get_devlink_priority(dev, &priority); > +- if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to get > priority of device node symlink: %m"); > +- > +- if (asprintf(&data, "%i:%s", priority, devname) < 0) > +- return log_oom_debug(); > +- > +- if (readlink_malloc(filename, &buf) >= 0 && streq(buf, data)) > +- return 0; > +- > +- if (unlink(filename) < 0 && errno != ENOENT) > +- log_device_debug_errno(dev, errno, "Failed to remove %s, > ignoring: %m", filename); > ++ return r; > + > +- for (unsigned j = 0; j < CREATE_STACK_LINK_MAX_RETRIES; j++) { > +- /* This may fail with -ENOENT when the parent directory > is removed during > +- * creating the file by another udevd worker. */ > +- r = mkdir_p(dirname, 0755); > +- if (r == -ENOENT) > +- continue; > +- if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to > create directory %s: %m", dirname); > ++ return 0; > ++} > + > +- if (stat(dirname, &st) < 0) { > +- if (errno == ENOENT) > +- continue; > +- return log_device_debug_errno(dev, errno, > "Failed to stat %s: %m", dirname); > +- } > ++static int stack_directory_open(const char *dirname) { > ++ _cleanup_close_ int fd = -1; > ++ int r; > + > +- if (symlink(data, filename) < 0) { > +- if (errno == ENOENT) > +- continue; > +- return log_device_debug_errno(dev, errno, > "Failed to create symbolic link %s: %m", filename); > +- } > ++ assert(dirname); > + > +- /* The symlink was created. Check if the timestamp of > directory is changed. */ > +- r = update_timestamp(dev, dirname, &st); > +- if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to > update timestamp of %s: %m", dirname); > ++ r = mkdir_parents(dirname, 0755); > ++ if (r < 0) > ++ return r; > + > +- return 0; > +- } > ++ fd = open_mkdir_at(AT_FDCWD, dirname, O_CLOEXEC | O_DIRECTORY | > O_NOFOLLOW | O_RDONLY, 0755); > ++ if (fd < 0) > ++ return fd; > + > +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ELOOP), > "Failed to create symbolic link %s: %m", filename); > ++ return TAKE_FD(fd); > + } > + > + size_t udev_node_escape_path(const char *src, char *dest, size_t size) { > +@@ -447,6 +406,7 @@ static int stack_directory_get_name(const char > *slink, char **ret) { > + > + static int link_update(sd_device *dev, const char *slink, bool add) { > + _cleanup_free_ char *dirname = NULL; > ++ _cleanup_close_ int dirfd = -1; > + int r; > + > + assert(dev); > +@@ -456,9 +416,13 @@ static int link_update(sd_device *dev, const char > *slink, bool add) { > + if (r < 0) > + return log_device_debug_errno(dev, r, "Failed to build > stack directory name for '%s': %m", slink); > + > +- r = update_stack_directory(dev, dirname, add); > ++ dirfd = stack_directory_open(dirname); > ++ if (dirfd < 0) > ++ return log_device_debug_errno(dev, dirfd, "Failed to > open stack directory '%s': %m", dirname); > ++ > ++ r = stack_directory_update(dev, dirfd, add); > + if (r < 0) > +- return r; > ++ return log_device_debug_errno(dev, r, "Failed to update > stack directory '%s': %m", dirname); > + > + for (unsigned i = 0; i < LINK_UPDATE_MAX_RETRIES; i++) { > + _cleanup_free_ char *target = NULL; > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch > b/meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch > new file mode 100644 > index 0000000000..dfc9fc9886 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch > @@ -0,0 +1,99 @@ > +From d4f60bdc11d8e6275922ca5c7f80b130ebbb3d5f Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 07:01:59 +0900 > +Subject: [PATCH 04/10] path-util: introduce path_make_relative_parent() > + > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/d4f60bdc11d8e6275922ca5c7f80b130ebbb3d5f > ] > +Comments: Refreshed first two hunks to apply patch cleanly without > patch-fuzz > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/basic/path-util.c | 18 ++++++++++++++++++ > + src/basic/path-util.h | 1 + > + src/test/test-path-util.c | 27 +++++++++++++++++++++++++++ > + 3 files changed, 46 insertions(+) > + > +diff --git a/src/basic/path-util.c b/src/basic/path-util.c > +index 338377d918..41e0d4d753 100644 > +--- a/src/basic/path-util.c > ++++ b/src/basic/path-util.c > +@@ -201,6 +201,24 @@ int path_make_relative(const char *from, > + return 0; > + } > + > ++int path_make_relative_parent(const char *from_child, const char *to, > char **ret) { > ++ _cleanup_free_ char *from = NULL; > ++ int r; > ++ > ++ assert(from_child); > ++ assert(to); > ++ assert(ret); > ++ > ++ /* Similar to path_make_relative(), but provides the relative > path from the parent directory of > ++ * 'from_child'. This may be useful when creating relative > symlink. */ > ++ > ++ r = path_extract_directory(from_child, &from); > ++ if (r < 0) > ++ return r; > ++ > ++ return path_make_relative(from, to, ret); > ++} > ++ > + char* path_startswith_strv(const char *p, char **set) { > + char **s, *t; > + > +diff --git a/src/basic/path-util.h b/src/basic/path-util.h > +index 41bbc7bb86..8cd7f512a6 100644 > +--- a/src/basic/path-util.h > ++++ b/src/basic/path-util.h > +@@ -57,6 +57,7 @@ char* path_make_absolute(const char *p, > + int safe_getcwd(char **ret); > + int path_make_absolute_cwd(const char *p, char **ret); > + int path_make_relative(const char *from, const char *to, char **ret); > ++int path_make_relative_parent(const char *from_child, const char *to, > char **ret); > + char *path_startswith_full(const char *path, const char *prefix, bool > accept_dot_dot) _pure_; > + static inline char* path_startswith(const char *path, const char > *prefix) { > + return path_startswith_full(path, prefix, true); > +diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c > +index e0583cfbab..a26e351233 100644 > +--- a/src/test/test-path-util.c > ++++ b/src/test/test-path-util.c > +@@ -477,6 +477,33 @@ TEST(path_make_relative) { > + > test_path_make_relative_one("//extra.//.//./.slashes//./won't////fo.ol///anybody//", > "/././/extra././/.slashes////ar.e/.just/././.fine///", > "../../../ar.e/.just/.fine"); > + } > + > ++static void test_path_make_relative_parent_one(const char *from, const > char *to, const char *expected) { > ++ _cleanup_free_ char *z = NULL; > ++ int r; > ++ > ++ log_info("/* %s(%s, %s) */", __func__, from, to); > ++ > ++ r = path_make_relative_parent(from, to, &z); > ++ assert_se((r >= 0) == !!expected); > ++ assert_se(streq_ptr(z, expected)); > ++} > ++ > ++TEST(path_make_relative_parent) { > ++ test_path_make_relative_parent_one("some/relative/path/hoge", > "/some/path", NULL); > ++ test_path_make_relative_parent_one("/some/path/hoge", > "some/relative/path", NULL); > ++ test_path_make_relative_parent_one("/some/dotdot/../path/hoge", > "/some/path", NULL); > ++ test_path_make_relative_parent_one("/", "/aaa", NULL); > ++ > ++ test_path_make_relative_parent_one("/hoge", "/", "."); > ++ test_path_make_relative_parent_one("/hoge", "/some/path", > "some/path"); > ++ test_path_make_relative_parent_one("/some/path/hoge", > "/some/path", "."); > ++ test_path_make_relative_parent_one("/some/path/hoge", > "/some/path/in/subdir", "in/subdir"); > ++ test_path_make_relative_parent_one("/some/path/hoge", "/", > "../.."); > ++ test_path_make_relative_parent_one("/some/path/hoge", > "/some/other/path", "../other/path"); > ++ test_path_make_relative_parent_one("/some/path/./dot/hoge", > "/some/further/path", "../../further/path"); > ++ > test_path_make_relative_parent_one("//extra.//.//./.slashes//./won't////fo.ol///anybody//hoge", > "/././/extra././/.slashes////ar.e/.just/././.fine///", > "../../../ar.e/.just/.fine"); > ++} > ++ > + TEST(path_strv_resolve) { > + char tmp_dir[] = "/tmp/test-path-util-XXXXXX"; > + _cleanup_strv_free_ char **search_dirs = NULL; > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch > b/meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch > new file mode 100644 > index 0000000000..42179f2031 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch > @@ -0,0 +1,74 @@ > +From faadf97500dc8e76350a409c127f3f0fed116f9a Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 03:29:07 +0900 > +Subject: [PATCH 05/10] udev: use readlinkat_malloc() > + > +And try to read it only when the file is symlink. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/faadf97500dc8e76350a409c127f3f0fed116f9a > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 20 ++++++++++++-------- > + 1 file changed, 12 insertions(+), 8 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index 6ead839a5f..0320f2d041 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -147,7 +147,6 @@ static int link_find_prioritized(sd_device *dev, bool > add, const char *stackdir, > + return r; > + > + FOREACH_DIRENT_ALL(de, dir, break) { > +- _cleanup_free_ char *path = NULL, *buf = NULL; > + int tmp_prio; > + > + if (de->d_name[0] == '.') > +@@ -157,15 +156,18 @@ static int link_find_prioritized(sd_device *dev, > bool add, const char *stackdir, > + if (streq(de->d_name, id)) > + continue; > + > +- path = path_join(stackdir, de->d_name); > +- if (!path) > +- return -ENOMEM; > +- > +- if (readlink_malloc(path, &buf) >= 0) { > ++ if (de->d_type == DT_LNK) { > ++ _cleanup_free_ char *buf = NULL; > + char *devnode; > + > + /* New format. The devnode and priority can be > obtained from symlink. */ > + > ++ r = readlinkat_malloc(dirfd(dir), de->d_name, > &buf); > ++ if (r < 0) { > ++ log_device_debug_errno(dev, r, "Failed > to read symlink %s, ignoring: %m", de->d_name); > ++ continue; > ++ } > ++ > + devnode = strchr(buf, ':'); > + if (!devnode || devnode == buf) > + continue; > +@@ -183,7 +185,8 @@ static int link_find_prioritized(sd_device *dev, bool > add, const char *stackdir, > + r = free_and_strdup(&target, devnode); > + if (r < 0) > + return r; > +- } else { > ++ > ++ } else if (de->d_type == DT_REG) { > + _cleanup_(sd_device_unrefp) sd_device *tmp_dev = > NULL; > + const char *devnode; > + > +@@ -205,7 +208,8 @@ static int link_find_prioritized(sd_device *dev, bool > add, const char *stackdir, > + r = free_and_strdup(&target, devnode); > + if (r < 0) > + return r; > +- } > ++ } else > ++ continue; > + > + priority = tmp_prio; > + } > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch > b/meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch > new file mode 100644 > index 0000000000..8fe4c9281c > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch > @@ -0,0 +1,190 @@ > +From 6b01e2905c387002a20b0a38f4b7670c8eb82cb8 Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 11:56:52 +0900 > +Subject: [PATCH 06/10] udev: rename link_find_prioritized() and variables > + > +Also shorten code a bit. > + > +Just for consistency with other part and readability of the code. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/6b01e2905c387002a20b0a38f4b7670c8eb82cb8 > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 62 ++++++++++++++++++++++---------------------- > + 1 file changed, 31 insertions(+), 31 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index 0320f2d041..f358564b41 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -63,20 +63,21 @@ static int create_symlink(const char *target, const > char *slink) { > + return r; > + } > + > +-static int node_symlink(sd_device *dev, const char *node, const char > *slink) { > ++static int node_symlink(sd_device *dev, const char *devnode, const char > *slink) { > + _cleanup_free_ char *slink_dirname = NULL, *target = NULL; > + const char *id, *slink_tmp; > +- struct stat stats; > ++ struct stat st; > + int r; > + > + assert(dev); > +- assert(node); > ++ assert(devnode); > + assert(slink); > + > +- if (lstat(slink, &stats) >= 0) { > +- if (!S_ISLNK(stats.st_mode)) > ++ if (lstat(slink, &st) >= 0) { > ++ if (!S_ISLNK(st.st_mode)) > + return log_device_debug_errno(dev, > SYNTHETIC_ERRNO(EEXIST), > +- "Conflicting inode > '%s' found, link to '%s' will not be created.", slink, node); > ++ "Conflicting inode > '%s' found, link to '%s' will not be created.", > ++ slink, devnode); > + } else if (errno != ENOENT) > + return log_device_debug_errno(dev, errno, "Failed to > lstat() '%s': %m", slink); > + > +@@ -85,9 +86,9 @@ static int node_symlink(sd_device *dev, const char > *node, const char *slink) { > + return log_device_debug_errno(dev, r, "Failed to get > parent directory of '%s': %m", slink); > + > + /* use relative link */ > +- r = path_make_relative(slink_dirname, node, &target); > ++ r = path_make_relative(slink_dirname, devnode, &target); > + if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to get > relative path from '%s' to '%s': %m", slink, node); > ++ return log_device_debug_errno(dev, r, "Failed to get > relative path from '%s' to '%s': %m", slink, devnode); > + > + r = device_get_device_id(dev, &id); > + if (r < 0) > +@@ -109,36 +110,36 @@ static int node_symlink(sd_device *dev, const char > *node, const char *slink) { > + return 0; > + } > + > +-static int link_find_prioritized(sd_device *dev, bool add, const char > *stackdir, char **ret) { > ++static int stack_directory_find_prioritized_devnode(sd_device *dev, > const char *dirname, bool add, char **ret) { > + _cleanup_closedir_ DIR *dir = NULL; > +- _cleanup_free_ char *target = NULL; > ++ _cleanup_free_ char *devnode = NULL; > + int r, priority = 0; > + const char *id; > + > + assert(dev); > +- assert(stackdir); > ++ assert(dirname); > + assert(ret); > + > + /* Find device node of device with highest priority. This > returns 1 if a device found, 0 if no > +- * device found, or a negative errno. */ > ++ * device found, or a negative errno on error. */ > + > + if (add) { > +- const char *devnode; > ++ const char *n; > + > + r = device_get_devlink_priority(dev, &priority); > + if (r < 0) > + return r; > + > +- r = sd_device_get_devname(dev, &devnode); > ++ r = sd_device_get_devname(dev, &n); > + if (r < 0) > + return r; > + > +- target = strdup(devnode); > +- if (!target) > ++ devnode = strdup(n); > ++ if (!devnode) > + return -ENOMEM; > + } > + > +- dir = opendir(stackdir); > ++ dir = opendir(dirname); > + if (!dir) > + return -errno; > + > +@@ -158,7 +159,7 @@ static int link_find_prioritized(sd_device *dev, bool > add, const char *stackdir, > + > + if (de->d_type == DT_LNK) { > + _cleanup_free_ char *buf = NULL; > +- char *devnode; > ++ char *colon; > + > + /* New format. The devnode and priority can be > obtained from symlink. */ > + > +@@ -168,27 +169,25 @@ static int link_find_prioritized(sd_device *dev, > bool add, const char *stackdir, > + continue; > + } > + > +- devnode = strchr(buf, ':'); > +- if (!devnode || devnode == buf) > ++ colon = strchr(buf, ':'); > ++ if (!colon || colon == buf) > + continue; > + > +- *(devnode++) = '\0'; > +- if (!path_startswith(devnode, "/dev")) > +- continue; > ++ *colon = '\0'; > + > + if (safe_atoi(buf, &tmp_prio) < 0) > + continue; > + > +- if (target && tmp_prio <= priority) > ++ if (devnode && tmp_prio <= priority) > + continue; > + > +- r = free_and_strdup(&target, devnode); > ++ r = free_and_strdup(&devnode, colon + 1); > + if (r < 0) > + return r; > + > + } else if (de->d_type == DT_REG) { > + _cleanup_(sd_device_unrefp) sd_device *tmp_dev = > NULL; > +- const char *devnode; > ++ const char *val; > + > + /* Old format. The devnode and priority must be > obtained from uevent and > + * udev database files. */ > +@@ -199,22 +198,23 @@ static int link_find_prioritized(sd_device *dev, > bool add, const char *stackdir, > + if (device_get_devlink_priority(tmp_dev, > &tmp_prio) < 0) > + continue; > + > +- if (target && tmp_prio <= priority) > ++ if (devnode && tmp_prio <= priority) > + continue; > + > +- if (sd_device_get_devname(tmp_dev, &devnode) < 0) > ++ if (sd_device_get_devname(tmp_dev, &val) < 0) > + continue; > + > +- r = free_and_strdup(&target, devnode); > ++ r = free_and_strdup(&devnode, val); > + if (r < 0) > + return r; > ++ > + } else > + continue; > + > + priority = tmp_prio; > + } > + > +- *ret = TAKE_PTR(target); > ++ *ret = TAKE_PTR(devnode); > + return !!*ret; > + } > + > +@@ -443,7 +443,7 @@ static int link_update(sd_device *dev, const char > *slink, bool add) { > + if (stat(dirname, &st1) < 0 && errno != ENOENT) > + return log_device_debug_errno(dev, errno, > "Failed to stat %s: %m", dirname); > + > +- r = link_find_prioritized(dev, add, dirname, &target); > ++ r = stack_directory_find_prioritized_devnode(dev, > dirname, add, &target); > + if (r < 0) > + return log_device_debug_errno(dev, r, "Failed to > determine device node with the highest priority for '%s': %m", slink); > + if (r == 0) { > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch > b/meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch > new file mode 100644 > index 0000000000..6a0ea22672 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch > @@ -0,0 +1,43 @@ > +From d6595c5ced636d44dc40adfb0b7cfc929bcac7a3 Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 12:05:36 +0900 > +Subject: [PATCH 07/10] udev: use path_make_relative_parent() > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/d6595c5ced636d44dc40adfb0b7cfc929bcac7a3 > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 8 ++------ > + 1 file changed, 2 insertions(+), 6 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index f358564b41..5a011cf86b 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -64,7 +64,7 @@ static int create_symlink(const char *target, const > char *slink) { > + } > + > + static int node_symlink(sd_device *dev, const char *devnode, const char > *slink) { > +- _cleanup_free_ char *slink_dirname = NULL, *target = NULL; > ++ _cleanup_free_ char *target = NULL; > + const char *id, *slink_tmp; > + struct stat st; > + int r; > +@@ -81,12 +81,8 @@ static int node_symlink(sd_device *dev, const char > *devnode, const char *slink) > + } else if (errno != ENOENT) > + return log_device_debug_errno(dev, errno, "Failed to > lstat() '%s': %m", slink); > + > +- r = path_extract_directory(slink, &slink_dirname); > +- if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to get > parent directory of '%s': %m", slink); > +- > + /* use relative link */ > +- r = path_make_relative(slink_dirname, devnode, &target); > ++ r = path_make_relative_parent(slink, devnode, &target); > + if (r < 0) > + return log_device_debug_errno(dev, r, "Failed to get > relative path from '%s' to '%s': %m", slink, devnode); > + > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch > b/meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch > new file mode 100644 > index 0000000000..cb29367f4d > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch > @@ -0,0 +1,75 @@ > +From 541a463fd5aad912c07c88d84e5a1c597c810956 Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 12:08:06 +0900 > +Subject: [PATCH 08/10] udev: make node_symlink() accept NULL devname > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/541a463fd5aad912c07c88d84e5a1c597c810956 > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 24 +++++++++--------------- > + 1 file changed, 9 insertions(+), 15 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index 5a011cf86b..8e78546e18 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -70,13 +70,18 @@ static int node_symlink(sd_device *dev, const char > *devnode, const char *slink) > + int r; > + > + assert(dev); > +- assert(devnode); > + assert(slink); > + > ++ if (!devnode) { > ++ r = sd_device_get_devname(dev, &devnode); > ++ if (r < 0) > ++ return log_device_debug_errno(dev, r, "Failed to > get device node: %m"); > ++ } > ++ > + if (lstat(slink, &st) >= 0) { > + if (!S_ISLNK(st.st_mode)) > + return log_device_debug_errno(dev, > SYNTHETIC_ERRNO(EEXIST), > +- "Conflicting inode > '%s' found, link to '%s' will not be created.", > ++ "Conflicting inode > '%s' found, symlink to '%s' will not be created.", > + slink, devnode); > + } else if (errno != ENOENT) > + return log_device_debug_errno(dev, errno, "Failed to > lstat() '%s': %m", slink); > +@@ -488,23 +493,12 @@ static int device_get_devpath_by_devnum(sd_device > *dev, char **ret) { > + > + int udev_node_update(sd_device *dev, sd_device *dev_old) { > + _cleanup_free_ char *filename = NULL; > +- const char *devnode, *devlink; > ++ const char *devlink; > + int r; > + > + assert(dev); > + assert(dev_old); > + > +- r = sd_device_get_devname(dev, &devnode); > +- if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to get > devnode: %m"); > +- > +- if (DEBUG_LOGGING) { > +- const char *id = NULL; > +- > +- (void) device_get_device_id(dev, &id); > +- log_device_debug(dev, "Handling device node '%s', > devnum=%s", devnode, strna(id)); > +- } > +- > + /* update possible left-over symlinks */ > + FOREACH_DEVICE_DEVLINK(dev_old, devlink) { > + /* check if old link name still belongs to this device */ > +@@ -536,7 +530,7 @@ int udev_node_update(sd_device *dev, sd_device > *dev_old) { > + return log_device_debug_errno(dev, r, "Failed to get > device path: %m"); > + > + /* always add /dev/{block,char}/$major:$minor */ > +- r = node_symlink(dev, devnode, filename); > ++ r = node_symlink(dev, NULL, filename); > + if (r < 0) > + return log_device_warning_errno(dev, r, "Failed to > create device symlink '%s': %m", filename); > + > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch > b/meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch > new file mode 100644 > index 0000000000..96ce076378 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch > @@ -0,0 +1,277 @@ > +From 57a272902aa821f9598dd0d74eab98d287473a63 Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 12:17:23 +0900 > +Subject: [PATCH 09/10] udev: use flock() when updating device node > symlinks > + > +By locking the stack directory, we can safely determine the device node > +with the highest priority for a symlink. So, the multiple try-and-wait > +loops can be dropped, and the code becomes quite simple. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/57a272902aa821f9598dd0d74eab98d287473a63 > ] > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 173 ++++++++++--------------------------------- > + 1 file changed, 40 insertions(+), 133 deletions(-) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index 8e78546e18..42efaaa028 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -1,11 +1,6 @@ > + /* SPDX-License-Identifier: GPL-2.0-or-later */ > + > +-#include <errno.h> > +-#include <fcntl.h> > +-#include <stdbool.h> > +-#include <stddef.h> > +-#include <sys/stat.h> > +-#include <unistd.h> > ++#include <sys/file.h> > + > + #include "sd-id128.h" > + > +@@ -22,47 +17,15 @@ > + #include "mkdir-label.h" > + #include "parse-util.h" > + #include "path-util.h" > +-#include "random-util.h" > + #include "selinux-util.h" > + #include "smack-util.h" > + #include "stat-util.h" > +-#include "stdio-util.h" > + #include "string-util.h" > +-#include "strxcpyx.h" > +-#include "time-util.h" > + #include "udev-node.h" > + #include "user-util.h" > + > +-#define CREATE_LINK_MAX_RETRIES 128 > +-#define LINK_UPDATE_MAX_RETRIES 128 > +-#define UPDATE_TIMESTAMP_MAX_RETRIES 128 > +-#define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC) > +-#define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC) > + #define UDEV_NODE_HASH_KEY > SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f) > + > +-static int create_symlink(const char *target, const char *slink) { > +- int r; > +- > +- assert(target); > +- assert(slink); > +- > +- for (unsigned i = 0; i < CREATE_LINK_MAX_RETRIES; i++) { > +- r = mkdir_parents_label(slink, 0755); > +- if (r == -ENOENT) > +- continue; > +- if (r < 0) > +- return r; > +- > +- mac_selinux_create_file_prepare(slink, S_IFLNK); > +- r = RET_NERRNO(symlink(target, slink)); > +- mac_selinux_create_file_clear(); > +- if (r != -ENOENT) > +- return r; > +- } > +- > +- return r; > +-} > +- > + static int node_symlink(sd_device *dev, const char *devnode, const char > *slink) { > + _cleanup_free_ char *target = NULL; > + const char *id, *slink_tmp; > +@@ -98,7 +61,13 @@ static int node_symlink(sd_device *dev, const char > *devnode, const char *slink) > + slink_tmp = strjoina(slink, ".tmp-", id); > + (void) unlink(slink_tmp); > + > +- r = create_symlink(target, slink_tmp); > ++ r = mkdir_parents_label(slink_tmp, 0755); > ++ if (r < 0) > ++ return log_device_debug_errno(dev, r, "Failed to create > parent directory of '%s': %m", slink_tmp); > ++ > ++ mac_selinux_create_file_prepare(slink_tmp, S_IFLNK); > ++ r = RET_NERRNO(symlink(target, slink_tmp)); > ++ mac_selinux_create_file_clear(); > + if (r < 0) > + return log_device_debug_errno(dev, r, "Failed to create > symlink '%s' to '%s': %m", slink_tmp, target); > + > +@@ -219,54 +188,7 @@ static int > stack_directory_find_prioritized_devnode(sd_device *dev, const char * > + return !!*ret; > + } > + > +-static int update_timestamp(sd_device *dev, int fd, struct stat *prev) { > +- assert(fd >= 0); > +- assert(prev); > +- > +- /* Even if a symlink in the stack directory is created/removed, > the mtime of the directory may > +- * not be changed. Why? Let's consider the following situation. > For simplicity, let's assume > +- * there exist two udev workers (A and B) and all of them calls > link_update() for the same > +- * devlink simultaneously. > +- * > +- * 1. A creates/removes a symlink in the stack directory. > +- * 2. A calls the first stat() in the loop of link_update(). > +- * 3. A calls link_find_prioritized(). > +- * 4. B creates/removes another symlink in the stack directory, > so the result of the step 3 is outdated. > +- * 5. B finishes link_update(). > +- * 6. A creates/removes devlink according to the outdated result > in the step 3. > +- * 7. A calls the second stat() in the loop of link_update(). > +- * > +- * If these 7 steps are processed in this order within a short > time period that kernel's timer > +- * does not increase, then even if the contents in the stack > directory is changed, the results > +- * of two stat() called by A shows the same timestamp, and A > cannot detect the change. > +- * > +- * By calling this function after creating/removing symlinks in > the stack directory, the > +- * timestamp of the stack directory is always increased at least > in the above step 5, so A can > +- * detect the update. */ > +- > +- for (unsigned i = 0; i < UPDATE_TIMESTAMP_MAX_RETRIES; i++) { > +- struct stat st; > +- > +- if (fstat(fd, &st) < 0) > +- return -errno; > +- > +- if (!stat_inode_unmodified(prev, &st)) > +- return 0; > +- > +- log_device_debug(dev, > +- "Stack directory is modified, but its > timestamp is not changed, " > +- "updating timestamp after 10ms."); > +- > +- (void) usleep(10 * USEC_PER_MSEC); > +- if (futimens(fd, NULL) < 0) > +- return -errno; > +- } > +- > +- return -ELOOP; > +-} > +- > + static int stack_directory_update(sd_device *dev, int fd, bool add) { > +- struct stat st; > + const char *id; > + int r; > + > +@@ -277,9 +199,6 @@ static int stack_directory_update(sd_device *dev, int > fd, bool add) { > + if (r < 0) > + return r; > + > +- if (fstat(fd, &st) < 0) > +- return -errno; > +- > + if (add) { > + _cleanup_free_ char *data = NULL, *buf = NULL; > + const char *devname; > +@@ -312,11 +231,7 @@ static int stack_directory_update(sd_device *dev, > int fd, bool add) { > + } > + } > + > +- r = update_timestamp(dev, fd, &st); > +- if (r < 0) > +- return r; > +- > +- return 0; > ++ return 1; /* Updated. */ > + } > + > + static int stack_directory_open(const char *dirname) { > +@@ -336,6 +251,21 @@ static int stack_directory_open(const char *dirname) > { > + return TAKE_FD(fd); > + } > + > ++static int stack_directory_lock(int dirfd) { > ++ _cleanup_close_ int fd = -1; > ++ > ++ assert(dirfd >= 0); > ++ > ++ fd = openat(dirfd, ".lock", O_CLOEXEC | O_NOFOLLOW | O_RDONLY | > O_CREAT, 0600); > ++ if (fd < 0) > ++ return -errno; > ++ > ++ if (flock(fd, LOCK_EX) < 0) > ++ return -errno; > ++ > ++ return TAKE_FD(fd); > ++} > ++ > + size_t udev_node_escape_path(const char *src, char *dest, size_t size) { > + size_t i, j; > + uint64_t h; > +@@ -410,8 +340,8 @@ static int stack_directory_get_name(const char > *slink, char **ret) { > + } > + > + static int link_update(sd_device *dev, const char *slink, bool add) { > +- _cleanup_free_ char *dirname = NULL; > +- _cleanup_close_ int dirfd = -1; > ++ _cleanup_free_ char *dirname = NULL, *devnode = NULL; > ++ _cleanup_close_ int dirfd = -1, lockfd = -1; > + int r; > + > + assert(dev); > +@@ -425,51 +355,28 @@ static int link_update(sd_device *dev, const char > *slink, bool add) { > + if (dirfd < 0) > + return log_device_debug_errno(dev, dirfd, "Failed to > open stack directory '%s': %m", dirname); > + > ++ lockfd = stack_directory_lock(dirfd); > ++ if (lockfd < 0) > ++ return log_device_debug_errno(dev, lockfd, "Failed to > lock stack directory '%s': %m", dirname); > ++ > + r = stack_directory_update(dev, dirfd, add); > + if (r < 0) > + return log_device_debug_errno(dev, r, "Failed to update > stack directory '%s': %m", dirname); > + > +- for (unsigned i = 0; i < LINK_UPDATE_MAX_RETRIES; i++) { > +- _cleanup_free_ char *target = NULL; > +- struct stat st1 = {}, st2 = {}; > +- > +- if (i > 0) { > +- usec_t delay = MIN_RANDOM_DELAY + > random_u64_range(MAX_RANDOM_DELAY - MIN_RANDOM_DELAY); > +- > +- log_device_debug(dev, "Directory %s was updated, > retrying to update devlink %s after %s.", > +- dirname, slink, > FORMAT_TIMESPAN(delay, USEC_PER_MSEC)); > +- (void) usleep(delay); > +- } > +- > +- if (stat(dirname, &st1) < 0 && errno != ENOENT) > +- return log_device_debug_errno(dev, errno, > "Failed to stat %s: %m", dirname); > +- > +- r = stack_directory_find_prioritized_devnode(dev, > dirname, add, &target); > +- if (r < 0) > +- return log_device_debug_errno(dev, r, "Failed to > determine device node with the highest priority for '%s': %m", slink); > +- if (r == 0) { > +- log_device_debug(dev, "No reference left for > '%s', removing", slink); > +- > +- if (unlink(slink) < 0 && errno != ENOENT) > +- log_device_debug_errno(dev, errno, > "Failed to remove '%s', ignoring: %m", slink); > ++ r = stack_directory_find_prioritized_devnode(dev, dirname, add, > &devnode); > ++ if (r < 0) > ++ return log_device_debug_errno(dev, r, "Failed to > determine device node with the highest priority for '%s': %m", slink); > ++ if (r > 0) > ++ return node_symlink(dev, devnode, slink); > + > +- (void) rmdir_parents(slink, "/dev"); > +- return 0; > +- } > ++ log_device_debug(dev, "No reference left for '%s', removing", > slink); > + > +- r = node_symlink(dev, target, slink); > +- if (r < 0) > +- return r; > ++ if (unlink(slink) < 0 && errno != ENOENT) > ++ log_device_debug_errno(dev, errno, "Failed to remove > '%s', ignoring: %m", slink); > + > +- if (stat(dirname, &st2) < 0 && errno != ENOENT) > +- return log_device_debug_errno(dev, errno, > "Failed to stat %s: %m", dirname); > ++ (void) rmdir_parents(slink, "/dev"); > + > +- if (((st1.st_mode & S_IFMT) == 0 && (st2.st_mode & > S_IFMT) == 0) || > +- stat_inode_unmodified(&st1, &st2)) > +- return 0; > +- } > +- > +- return -ELOOP; > ++ return 0; > + } > + > + static int device_get_devpath_by_devnum(sd_device *dev, char **ret) { > +-- > +2.25.1 > + > diff --git > a/meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch > b/meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch > new file mode 100644 > index 0000000000..7a6f614db7 > --- /dev/null > +++ > b/meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch > @@ -0,0 +1,130 @@ > +From 1055172804e660df2e1c498dafa998ffd65e0c88 Mon Sep 17 00:00:00 2001 > +From: Yu Watanabe <watanabe.yu+github@gmail.com> > +Date: Mon, 11 Apr 2022 21:52:49 +0900 > +Subject: [PATCH 10/10] udev: cleanup stack directory /run/udev/links when > all > + workers exited > + > +By the previous commit, the stack directories are not removed even if > +it is empty. To reduce the inode usage of /run, let's cleanup the > +directories. > + > +PR - https://github.com/systemd/systemd/pull/23043 > +Upstream-Status: Backport [ > https://github.com/systemd/systemd/pull/23043/commits/1055172804e660df2e1c498dafa998ffd65e0c88 > ] > +Comments: Refreshed all hunks to apply patch cleanly without patch-fuzz > +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> > + > +--- > + src/udev/udev-node.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > + src/udev/udev-node.h | 1 + > + src/udev/udevd.c | 10 ++++++++++ > + 3 files changed, 53 insertions(+) > + > +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c > +index 42efaaa028..4e7dca06de 100644 > +--- a/src/udev/udev-node.c > ++++ b/src/udev/udev-node.c > +@@ -24,6 +24,48 @@ > + > + #define UDEV_NODE_HASH_KEY > SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f) > + > ++int udev_node_cleanup(void) { > ++ _cleanup_closedir_ DIR *dir = NULL; > ++ > ++ /* This must not be called when any workers exist. It would > cause a race between mkdir() called > ++ * by stack_directory_lock() and unlinkat() called by this. */ > ++ > ++ dir = opendir("/run/udev/links"); > ++ if (!dir) { > ++ if (errno == ENOENT) > ++ return 0; > ++ > ++ return log_debug_errno(errno, "Failed to open directory > '/run/udev/links', ignoring: %m"); > ++ } > ++ > ++ FOREACH_DIRENT_ALL(de, dir, break) { > ++ _cleanup_free_ char *lockfile = NULL; > ++ > ++ if (de->d_name[0] == '.') > ++ continue; > ++ > ++ if (de->d_type != DT_DIR) > ++ continue; > ++ > ++ /* As commented in the above, this is called when no > worker exists, hence the file is not > ++ * locked. On a later uevent, the lock file will be > created if necessary. So, we can safely > ++ * remove the file now. */ > ++ lockfile = path_join(de->d_name, ".lock"); > ++ if (!lockfile) > ++ return log_oom_debug(); > ++ > ++ if (unlinkat(dirfd(dir), lockfile, 0) < 0 && errno != > ENOENT) { > ++ log_debug_errno(errno, "Failed to remove > '/run/udev/links/%s', ignoring: %m", lockfile); > ++ continue; > ++ } > ++ > ++ if (unlinkat(dirfd(dir), de->d_name, AT_REMOVEDIR) < 0 > && errno != ENOTEMPTY) > ++ log_debug_errno(errno, "Failed to remove > '/run/udev/links/%s', ignoring: %m", de->d_name); > ++ } > ++ > ++ return 0; > ++} > ++ > + static int node_symlink(sd_device *dev, const char *devnode, const char > *slink) { > + _cleanup_free_ char *target = NULL; > + const char *id, *slink_tmp; > +diff --git a/src/udev/udev-node.h b/src/udev/udev-node.h > +index 86a829545a..0c545e4a0f 100644 > +--- a/src/udev/udev-node.h > ++++ b/src/udev/udev-node.h > +@@ -17,5 +17,6 @@ int udev_node_apply_permissions( > + OrderedHashmap *seclabel_list); > + int udev_node_remove(sd_device *dev); > + int udev_node_update(sd_device *dev, sd_device *dev_old); > ++int udev_node_cleanup(void); > + > + size_t udev_node_escape_path(const char *src, char *dest, size_t size); > +diff --git a/src/udev/udevd.c b/src/udev/udevd.c > +index b179dfac37..c519e19897 100644 > +--- a/src/udev/udevd.c > ++++ b/src/udev/udevd.c > +@@ -62,6 +62,7 @@ > + #include "udev-builtin.h" > + #include "udev-ctrl.h" > + #include "udev-event.h" > ++#include "udev-node.h" > + #include "udev-util.h" > + #include "udev-watch.h" > + #include "user-util.h" > +@@ -106,6 +107,7 @@ typedef struct Manager { > + > + usec_t last_usec; > + > ++ bool udev_node_needs_cleanup; > + bool stop_exec_queue; > + bool exit; > + } Manager; > +@@ -933,6 +935,9 @@ static int event_queue_start(Manager *ma > + manager->last_usec = usec; > + } > + > ++ /* To make the stack directory /run/udev/links cleaned up later. > */ > ++ manager->udev_node_needs_cleanup = true; > ++ > + 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"); > +@@ -1487,6 +1492,11 @@ static int on_post(sd_event_source *s, v > + > + /* There are no idle workers. */ > + > ++ if (manager->udev_node_needs_cleanup) { > ++ (void) udev_node_cleanup(); > ++ manager->udev_node_needs_cleanup = false; > ++ } > ++ > + if (manager->exit) > + return sd_event_exit(manager->event, 0); > + > +-- > +2.25.1 > + > diff --git a/meta/recipes-core/systemd/systemd_250.5.bb > b/meta/recipes-core/systemd/systemd_250.5.bb > index 4d520c85f3..22ebc0a229 100644 > --- a/meta/recipes-core/systemd/systemd_250.5.bb > +++ b/meta/recipes-core/systemd/systemd_250.5.bb > @@ -34,6 +34,16 @@ SRC_URI += "file://touchscreen.rules \ > > file://0001-nspawn-make-sure-host-root-can-write-to-the-uidmappe.patch \ > file://CVE-2023-7008.patch \ > file://fix-vlan-qos-mapping.patch \ > + file://0001-udev-move-udev_node_escape_path.patch \ > + > file://0002-udev-split-link_update-and-introduce-stack_directory.patch \ > + > file://0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch \ > + > file://0004-path-util-introduce-path_make_relative_parent.patch \ > + file://0005-udev-use-readlinkat_malloc.patch \ > + > file://0006-udev-rename-link_find_prioritized-and-variables.patch \ > + file://0007-udev-use-path_make_relative_parent.patch \ > + file://0008-udev-make-node_symlink-accept-NULL-devname.patch \ > + > file://0009-udev-use-flock-when-updating-device-node-symlinks.patch \ > + > file://0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch \ > " > > # patches needed by musl > -- > 2.25.1 > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#199203): > https://lists.openembedded.org/g/openembedded-core/message/199203 > Mute This Topic: https://lists.openembedded.org/mt/106034797/1686489 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [ > alex.kanavin@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=- > >
diff --git a/meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch b/meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch new file mode 100644 index 0000000000..900ca81170 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0001-udev-move-udev_node_escape_path.patch @@ -0,0 +1,120 @@ +From b9168275c39a190441fee73ba1c8a64515fd3b0e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 11:25:37 +0900 +Subject: [PATCH 01/10] udev: move udev_node_escape_path() + +No functionality is changed. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/b9168275c39a190441fee73ba1c8a64515fd3b0e] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 84 ++++++++++++++++++++++---------------------- + 1 file changed, 42 insertions(+), 42 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index bb34977d97..79d050cce6 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -222,48 +222,6 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + return !!*ret; + } + +-size_t udev_node_escape_path(const char *src, char *dest, size_t size) { +- size_t i, j; +- uint64_t h; +- +- assert(src); +- assert(dest); +- assert(size >= 12); +- +- for (i = 0, j = 0; src[i] != '\0'; i++) { +- if (src[i] == '/') { +- if (j+4 >= size - 12 + 1) +- goto toolong; +- memcpy(&dest[j], "\\x2f", 4); +- j += 4; +- } else if (src[i] == '\\') { +- if (j+4 >= size - 12 + 1) +- goto toolong; +- memcpy(&dest[j], "\\x5c", 4); +- j += 4; +- } else { +- if (j+1 >= size - 12 + 1) +- goto toolong; +- dest[j] = src[i]; +- j++; +- } +- } +- dest[j] = '\0'; +- return j; +- +-toolong: +- /* If the input path is too long to encode as a filename, then let's suffix with a string +- * generated from the hash of the path. */ +- +- h = siphash24_string(src, UDEV_NODE_HASH_KEY.bytes); +- +- for (unsigned k = 0; k <= 10; k++) +- dest[size - k - 2] = urlsafe_base64char((h >> (k * 6)) & 63); +- +- dest[size - 1] = '\0'; +- return size - 1; +-} +- + static int update_timestamp(sd_device *dev, const char *path, struct stat *prev) { + assert(path); + assert(prev); +@@ -414,6 +372,48 @@ static int update_stack_directory(sd_device *dev, const char *dirname, bool add) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ELOOP), "Failed to create symbolic link %s: %m", filename); + } + ++size_t udev_node_escape_path(const char *src, char *dest, size_t size) { ++ size_t i, j; ++ uint64_t h; ++ ++ assert(src); ++ assert(dest); ++ assert(size >= 12); ++ ++ for (i = 0, j = 0; src[i] != '\0'; i++) { ++ if (src[i] == '/') { ++ if (j+4 >= size - 12 + 1) ++ goto toolong; ++ memcpy(&dest[j], "\\x2f", 4); ++ j += 4; ++ } else if (src[i] == '\\') { ++ if (j+4 >= size - 12 + 1) ++ goto toolong; ++ memcpy(&dest[j], "\\x5c", 4); ++ j += 4; ++ } else { ++ if (j+1 >= size - 12 + 1) ++ goto toolong; ++ dest[j] = src[i]; ++ j++; ++ } ++ } ++ dest[j] = '\0'; ++ return j; ++ ++toolong: ++ /* If the input path is too long to encode as a filename, then let's suffix with a string ++ * generated from the hash of the path. */ ++ ++ h = siphash24_string(src, UDEV_NODE_HASH_KEY.bytes); ++ ++ for (unsigned k = 0; k <= 10; k++) ++ dest[size - k - 2] = urlsafe_base64char((h >> (k * 6)) & 63); ++ ++ dest[size - 1] = '\0'; ++ return size - 1; ++} ++ + /* manage "stack of names" with possibly specified device priorities */ + static int link_update(sd_device *dev, const char *slink_in, bool add) { + _cleanup_free_ char *slink = NULL, *dirname = NULL; +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch b/meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch new file mode 100644 index 0000000000..edc7ab5b38 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0002-udev-split-link_update-and-introduce-stack_directory.patch @@ -0,0 +1,90 @@ +From 7e7c36fbbb396364c386bf1edbe9b25179a134c6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 11:26:08 +0900 +Subject: [PATCH 02/10] udev: split link_update() and introduce + stack_directory_get_name() + +No functionality is changed. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/7e7c36fbbb396364c386bf1edbe9b25179a134c6] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 52 ++++++++++++++++++++++++++++---------------- + 1 file changed, 33 insertions(+), 19 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 79d050cce6..b4b865c021 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -414,33 +414,47 @@ toolong: + return size - 1; + } + +-/* manage "stack of names" with possibly specified device priorities */ +-static int link_update(sd_device *dev, const char *slink_in, bool add) { +- _cleanup_free_ char *slink = NULL, *dirname = NULL; +- const char *slink_name; ++static int stack_directory_get_name(const char *slink, char **ret) { ++ _cleanup_free_ char *s = NULL, *dirname = NULL; + char name_enc[NAME_MAX+1]; +- int r; ++ const char *name; + +- assert(dev); +- assert(slink_in); ++ assert(slink); ++ assert(ret); + +- slink = strdup(slink_in); +- if (!slink) +- return log_oom_debug(); ++ s = strdup(slink); ++ if (!s) ++ return -ENOMEM; + +- path_simplify(slink); ++ path_simplify(s); + +- slink_name = path_startswith(slink, "/dev"); +- if (!slink_name || +- empty_or_root(slink_name) || +- !path_is_normalized(slink_name)) +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), +- "Invalid symbolic link of device node: %s", slink); ++ if (!path_is_normalized(s)) ++ return -EINVAL; ++ ++ name = path_startswith(s, "/dev"); ++ if (empty_or_root(name)) ++ return -EINVAL; ++ ++ udev_node_escape_path(name, name_enc, sizeof(name_enc)); + +- (void) udev_node_escape_path(slink_name, name_enc, sizeof(name_enc)); + dirname = path_join("/run/udev/links", name_enc); + if (!dirname) +- return log_oom_debug(); ++ return -ENOMEM; ++ ++ *ret = TAKE_PTR(dirname); ++ return 0; ++} ++ ++static int link_update(sd_device *dev, const char *slink, bool add) { ++ _cleanup_free_ char *dirname = NULL; ++ int r; ++ ++ assert(dev); ++ assert(slink); ++ ++ r = stack_directory_get_name(slink, &dirname); ++ if (r < 0) ++ return log_device_debug_errno(dev, r, "Failed to build stack directory name for '%s': %m", slink); + + r = update_stack_directory(dev, dirname, add); + if (r < 0) +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch b/meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch new file mode 100644 index 0000000000..6d2b178bd4 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch @@ -0,0 +1,267 @@ +From a28d67a90374a9d11bd5635f81961f72e5a8b33e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 11:47:20 +0900 +Subject: [PATCH 03/10] udev: do not remove stack directory even if it is empty + +Then, we can always assume the directory exists, and the code become +slightly simpler. + +Note, unused directories are removed by the main udevd process in a +later commit. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/a28d67a90374a9d11bd5635f81961f72e5a8b33e] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 158 +++++++++++++++++-------------------------- + 1 file changed, 61 insertions(+), 97 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index b4b865c021..6ead839a5f 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -35,7 +35,6 @@ + + #define CREATE_LINK_MAX_RETRIES 128 + #define LINK_UPDATE_MAX_RETRIES 128 +-#define CREATE_STACK_LINK_MAX_RETRIES 128 + #define UPDATE_TIMESTAMP_MAX_RETRIES 128 + #define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC) + #define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC) +@@ -140,15 +139,8 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + } + + dir = opendir(stackdir); +- if (!dir) { +- if (add) /* The stack directory must exist. */ +- return -errno; +- if (errno != ENOENT) +- return -errno; +- +- *ret = NULL; +- return 0; +- } ++ if (!dir) ++ return -errno; + + r = device_get_device_id(dev, &id); + if (r < 0) +@@ -222,8 +214,8 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + return !!*ret; + } + +-static int update_timestamp(sd_device *dev, const char *path, struct stat *prev) { +- assert(path); ++static int update_timestamp(sd_device *dev, int fd, struct stat *prev) { ++ assert(fd >= 0); + assert(prev); + + /* Even if a symlink in the stack directory is created/removed, the mtime of the directory may +@@ -247,129 +239,96 @@ static int update_timestamp(sd_device *dev, const char *path, struct stat *prev) + * timestamp of the stack directory is always increased at least in the above step 5, so A can + * detect the update. */ + +- if ((prev->st_mode & S_IFMT) == 0) +- return 0; /* Does not exist, or previous stat() failed. */ +- + for (unsigned i = 0; i < UPDATE_TIMESTAMP_MAX_RETRIES; i++) { + struct stat st; + +- if (stat(path, &st) < 0) ++ if (fstat(fd, &st) < 0) + return -errno; + + if (!stat_inode_unmodified(prev, &st)) + return 0; + + log_device_debug(dev, +- "%s is modified, but its timestamp is not changed, " +- "updating timestamp after 10ms.", +- path); ++ "Stack directory is modified, but its timestamp is not changed, " ++ "updating timestamp after 10ms."); + + (void) usleep(10 * USEC_PER_MSEC); +- if (utimensat(AT_FDCWD, path, NULL, 0) < 0) ++ if (futimens(fd, NULL) < 0) + return -errno; + } + + return -ELOOP; + } + +-static int update_stack_directory(sd_device *dev, const char *dirname, bool add) { +- _cleanup_free_ char *filename = NULL, *data = NULL, *buf = NULL; +- const char *devname, *id; +- struct stat st = {}; +- int priority, r; ++static int stack_directory_update(sd_device *dev, int fd, bool add) { ++ struct stat st; ++ const char *id; ++ int r; + + assert(dev); +- assert(dirname); ++ assert(fd >= 0); + + r = device_get_device_id(dev, &id); + if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to get device id: %m"); +- +- filename = path_join(dirname, id); +- if (!filename) +- return log_oom_debug(); ++ return r; + +- if (!add) { +- int unlink_error = 0, stat_error = 0; ++ if (fstat(fd, &st) < 0) ++ return -errno; + +- if (stat(dirname, &st) < 0) { +- if (errno == ENOENT) +- return 0; /* The stack directory is already removed. That's OK. */ +- stat_error = -errno; +- } ++ if (add) { ++ _cleanup_free_ char *data = NULL, *buf = NULL; ++ const char *devname; ++ int priority; + +- if (unlink(filename) < 0) +- unlink_error = -errno; ++ r = sd_device_get_devname(dev, &devname); ++ if (r < 0) ++ return r; + +- if (rmdir(dirname) >= 0 || errno == ENOENT) +- return 0; ++ r = device_get_devlink_priority(dev, &priority); ++ if (r < 0) ++ return r; + +- if (unlink_error < 0) { +- if (unlink_error == -ENOENT) +- return 0; ++ if (asprintf(&data, "%i:%s", priority, devname) < 0) ++ return -ENOMEM; + +- /* If we failed to remove the symlink, then there is almost nothing we can do. */ +- return log_device_debug_errno(dev, unlink_error, "Failed to remove %s: %m", filename); +- } ++ if (readlinkat_malloc(fd, id, &buf) >= 0 && streq(buf, data)) ++ return 0; /* Unchanged. */ + +- if (stat_error < 0) +- return log_device_debug_errno(dev, stat_error, "Failed to stat %s: %m", dirname); ++ (void) unlinkat(fd, id, 0); + +- /* The symlink was removed. Check if the timestamp of directory is changed. */ +- r = update_timestamp(dev, dirname, &st); +- if (r < 0 && r != -ENOENT) +- return log_device_debug_errno(dev, r, "Failed to update timestamp of %s: %m", dirname); ++ if (symlinkat(data, fd, id) < 0) ++ return -errno; + +- return 0; ++ } else { ++ if (unlinkat(fd, id, 0) < 0) { ++ if (errno == ENOENT) ++ return 0; /* Unchanged. */ ++ return -errno; ++ } + } + +- r = sd_device_get_devname(dev, &devname); ++ r = update_timestamp(dev, fd, &st); + if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to get device node: %m"); +- +- r = device_get_devlink_priority(dev, &priority); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to get priority of device node symlink: %m"); +- +- if (asprintf(&data, "%i:%s", priority, devname) < 0) +- return log_oom_debug(); +- +- if (readlink_malloc(filename, &buf) >= 0 && streq(buf, data)) +- return 0; +- +- if (unlink(filename) < 0 && errno != ENOENT) +- log_device_debug_errno(dev, errno, "Failed to remove %s, ignoring: %m", filename); ++ return r; + +- for (unsigned j = 0; j < CREATE_STACK_LINK_MAX_RETRIES; j++) { +- /* This may fail with -ENOENT when the parent directory is removed during +- * creating the file by another udevd worker. */ +- r = mkdir_p(dirname, 0755); +- if (r == -ENOENT) +- continue; +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to create directory %s: %m", dirname); ++ return 0; ++} + +- if (stat(dirname, &st) < 0) { +- if (errno == ENOENT) +- continue; +- return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname); +- } ++static int stack_directory_open(const char *dirname) { ++ _cleanup_close_ int fd = -1; ++ int r; + +- if (symlink(data, filename) < 0) { +- if (errno == ENOENT) +- continue; +- return log_device_debug_errno(dev, errno, "Failed to create symbolic link %s: %m", filename); +- } ++ assert(dirname); + +- /* The symlink was created. Check if the timestamp of directory is changed. */ +- r = update_timestamp(dev, dirname, &st); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to update timestamp of %s: %m", dirname); ++ r = mkdir_parents(dirname, 0755); ++ if (r < 0) ++ return r; + +- return 0; +- } ++ fd = open_mkdir_at(AT_FDCWD, dirname, O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW | O_RDONLY, 0755); ++ if (fd < 0) ++ return fd; + +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ELOOP), "Failed to create symbolic link %s: %m", filename); ++ return TAKE_FD(fd); + } + + size_t udev_node_escape_path(const char *src, char *dest, size_t size) { +@@ -447,6 +406,7 @@ static int stack_directory_get_name(const char *slink, char **ret) { + + static int link_update(sd_device *dev, const char *slink, bool add) { + _cleanup_free_ char *dirname = NULL; ++ _cleanup_close_ int dirfd = -1; + int r; + + assert(dev); +@@ -456,9 +416,13 @@ static int link_update(sd_device *dev, const char *slink, bool add) { + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to build stack directory name for '%s': %m", slink); + +- r = update_stack_directory(dev, dirname, add); ++ dirfd = stack_directory_open(dirname); ++ if (dirfd < 0) ++ return log_device_debug_errno(dev, dirfd, "Failed to open stack directory '%s': %m", dirname); ++ ++ r = stack_directory_update(dev, dirfd, add); + if (r < 0) +- return r; ++ return log_device_debug_errno(dev, r, "Failed to update stack directory '%s': %m", dirname); + + for (unsigned i = 0; i < LINK_UPDATE_MAX_RETRIES; i++) { + _cleanup_free_ char *target = NULL; +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch b/meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch new file mode 100644 index 0000000000..dfc9fc9886 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0004-path-util-introduce-path_make_relative_parent.patch @@ -0,0 +1,99 @@ +From d4f60bdc11d8e6275922ca5c7f80b130ebbb3d5f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 07:01:59 +0900 +Subject: [PATCH 04/10] path-util: introduce path_make_relative_parent() + + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/d4f60bdc11d8e6275922ca5c7f80b130ebbb3d5f] +Comments: Refreshed first two hunks to apply patch cleanly without patch-fuzz +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/basic/path-util.c | 18 ++++++++++++++++++ + src/basic/path-util.h | 1 + + src/test/test-path-util.c | 27 +++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+) + +diff --git a/src/basic/path-util.c b/src/basic/path-util.c +index 338377d918..41e0d4d753 100644 +--- a/src/basic/path-util.c ++++ b/src/basic/path-util.c +@@ -201,6 +201,24 @@ int path_make_relative(const char *from, + return 0; + } + ++int path_make_relative_parent(const char *from_child, const char *to, char **ret) { ++ _cleanup_free_ char *from = NULL; ++ int r; ++ ++ assert(from_child); ++ assert(to); ++ assert(ret); ++ ++ /* Similar to path_make_relative(), but provides the relative path from the parent directory of ++ * 'from_child'. This may be useful when creating relative symlink. */ ++ ++ r = path_extract_directory(from_child, &from); ++ if (r < 0) ++ return r; ++ ++ return path_make_relative(from, to, ret); ++} ++ + char* path_startswith_strv(const char *p, char **set) { + char **s, *t; + +diff --git a/src/basic/path-util.h b/src/basic/path-util.h +index 41bbc7bb86..8cd7f512a6 100644 +--- a/src/basic/path-util.h ++++ b/src/basic/path-util.h +@@ -57,6 +57,7 @@ char* path_make_absolute(const char *p, + int safe_getcwd(char **ret); + int path_make_absolute_cwd(const char *p, char **ret); + int path_make_relative(const char *from, const char *to, char **ret); ++int path_make_relative_parent(const char *from_child, const char *to, char **ret); + char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_; + static inline char* path_startswith(const char *path, const char *prefix) { + return path_startswith_full(path, prefix, true); +diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c +index e0583cfbab..a26e351233 100644 +--- a/src/test/test-path-util.c ++++ b/src/test/test-path-util.c +@@ -477,6 +477,33 @@ TEST(path_make_relative) { + test_path_make_relative_one("//extra.//.//./.slashes//./won't////fo.ol///anybody//", "/././/extra././/.slashes////ar.e/.just/././.fine///", "../../../ar.e/.just/.fine"); + } + ++static void test_path_make_relative_parent_one(const char *from, const char *to, const char *expected) { ++ _cleanup_free_ char *z = NULL; ++ int r; ++ ++ log_info("/* %s(%s, %s) */", __func__, from, to); ++ ++ r = path_make_relative_parent(from, to, &z); ++ assert_se((r >= 0) == !!expected); ++ assert_se(streq_ptr(z, expected)); ++} ++ ++TEST(path_make_relative_parent) { ++ test_path_make_relative_parent_one("some/relative/path/hoge", "/some/path", NULL); ++ test_path_make_relative_parent_one("/some/path/hoge", "some/relative/path", NULL); ++ test_path_make_relative_parent_one("/some/dotdot/../path/hoge", "/some/path", NULL); ++ test_path_make_relative_parent_one("/", "/aaa", NULL); ++ ++ test_path_make_relative_parent_one("/hoge", "/", "."); ++ test_path_make_relative_parent_one("/hoge", "/some/path", "some/path"); ++ test_path_make_relative_parent_one("/some/path/hoge", "/some/path", "."); ++ test_path_make_relative_parent_one("/some/path/hoge", "/some/path/in/subdir", "in/subdir"); ++ test_path_make_relative_parent_one("/some/path/hoge", "/", "../.."); ++ test_path_make_relative_parent_one("/some/path/hoge", "/some/other/path", "../other/path"); ++ test_path_make_relative_parent_one("/some/path/./dot/hoge", "/some/further/path", "../../further/path"); ++ test_path_make_relative_parent_one("//extra.//.//./.slashes//./won't////fo.ol///anybody//hoge", "/././/extra././/.slashes////ar.e/.just/././.fine///", "../../../ar.e/.just/.fine"); ++} ++ + TEST(path_strv_resolve) { + char tmp_dir[] = "/tmp/test-path-util-XXXXXX"; + _cleanup_strv_free_ char **search_dirs = NULL; +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch b/meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch new file mode 100644 index 0000000000..42179f2031 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0005-udev-use-readlinkat_malloc.patch @@ -0,0 +1,74 @@ +From faadf97500dc8e76350a409c127f3f0fed116f9a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 03:29:07 +0900 +Subject: [PATCH 05/10] udev: use readlinkat_malloc() + +And try to read it only when the file is symlink. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/faadf97500dc8e76350a409c127f3f0fed116f9a] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 6ead839a5f..0320f2d041 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -147,7 +147,6 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + return r; + + FOREACH_DIRENT_ALL(de, dir, break) { +- _cleanup_free_ char *path = NULL, *buf = NULL; + int tmp_prio; + + if (de->d_name[0] == '.') +@@ -157,15 +156,18 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + if (streq(de->d_name, id)) + continue; + +- path = path_join(stackdir, de->d_name); +- if (!path) +- return -ENOMEM; +- +- if (readlink_malloc(path, &buf) >= 0) { ++ if (de->d_type == DT_LNK) { ++ _cleanup_free_ char *buf = NULL; + char *devnode; + + /* New format. The devnode and priority can be obtained from symlink. */ + ++ r = readlinkat_malloc(dirfd(dir), de->d_name, &buf); ++ if (r < 0) { ++ log_device_debug_errno(dev, r, "Failed to read symlink %s, ignoring: %m", de->d_name); ++ continue; ++ } ++ + devnode = strchr(buf, ':'); + if (!devnode || devnode == buf) + continue; +@@ -183,7 +185,8 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + r = free_and_strdup(&target, devnode); + if (r < 0) + return r; +- } else { ++ ++ } else if (de->d_type == DT_REG) { + _cleanup_(sd_device_unrefp) sd_device *tmp_dev = NULL; + const char *devnode; + +@@ -205,7 +208,8 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + r = free_and_strdup(&target, devnode); + if (r < 0) + return r; +- } ++ } else ++ continue; + + priority = tmp_prio; + } +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch b/meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch new file mode 100644 index 0000000000..8fe4c9281c --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0006-udev-rename-link_find_prioritized-and-variables.patch @@ -0,0 +1,190 @@ +From 6b01e2905c387002a20b0a38f4b7670c8eb82cb8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 11:56:52 +0900 +Subject: [PATCH 06/10] udev: rename link_find_prioritized() and variables + +Also shorten code a bit. + +Just for consistency with other part and readability of the code. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/6b01e2905c387002a20b0a38f4b7670c8eb82cb8] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 62 ++++++++++++++++++++++---------------------- + 1 file changed, 31 insertions(+), 31 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 0320f2d041..f358564b41 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -63,20 +63,21 @@ static int create_symlink(const char *target, const char *slink) { + return r; + } + +-static int node_symlink(sd_device *dev, const char *node, const char *slink) { ++static int node_symlink(sd_device *dev, const char *devnode, const char *slink) { + _cleanup_free_ char *slink_dirname = NULL, *target = NULL; + const char *id, *slink_tmp; +- struct stat stats; ++ struct stat st; + int r; + + assert(dev); +- assert(node); ++ assert(devnode); + assert(slink); + +- if (lstat(slink, &stats) >= 0) { +- if (!S_ISLNK(stats.st_mode)) ++ if (lstat(slink, &st) >= 0) { ++ if (!S_ISLNK(st.st_mode)) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST), +- "Conflicting inode '%s' found, link to '%s' will not be created.", slink, node); ++ "Conflicting inode '%s' found, link to '%s' will not be created.", ++ slink, devnode); + } else if (errno != ENOENT) + return log_device_debug_errno(dev, errno, "Failed to lstat() '%s': %m", slink); + +@@ -85,9 +86,9 @@ static int node_symlink(sd_device *dev, const char *node, const char *slink) { + return log_device_debug_errno(dev, r, "Failed to get parent directory of '%s': %m", slink); + + /* use relative link */ +- r = path_make_relative(slink_dirname, node, &target); ++ r = path_make_relative(slink_dirname, devnode, &target); + if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, node); ++ return log_device_debug_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, devnode); + + r = device_get_device_id(dev, &id); + if (r < 0) +@@ -109,36 +110,36 @@ static int node_symlink(sd_device *dev, const char *node, const char *slink) { + return 0; + } + +-static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) { ++static int stack_directory_find_prioritized_devnode(sd_device *dev, const char *dirname, bool add, char **ret) { + _cleanup_closedir_ DIR *dir = NULL; +- _cleanup_free_ char *target = NULL; ++ _cleanup_free_ char *devnode = NULL; + int r, priority = 0; + const char *id; + + assert(dev); +- assert(stackdir); ++ assert(dirname); + assert(ret); + + /* Find device node of device with highest priority. This returns 1 if a device found, 0 if no +- * device found, or a negative errno. */ ++ * device found, or a negative errno on error. */ + + if (add) { +- const char *devnode; ++ const char *n; + + r = device_get_devlink_priority(dev, &priority); + if (r < 0) + return r; + +- r = sd_device_get_devname(dev, &devnode); ++ r = sd_device_get_devname(dev, &n); + if (r < 0) + return r; + +- target = strdup(devnode); +- if (!target) ++ devnode = strdup(n); ++ if (!devnode) + return -ENOMEM; + } + +- dir = opendir(stackdir); ++ dir = opendir(dirname); + if (!dir) + return -errno; + +@@ -158,7 +159,7 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + + if (de->d_type == DT_LNK) { + _cleanup_free_ char *buf = NULL; +- char *devnode; ++ char *colon; + + /* New format. The devnode and priority can be obtained from symlink. */ + +@@ -168,27 +169,25 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + continue; + } + +- devnode = strchr(buf, ':'); +- if (!devnode || devnode == buf) ++ colon = strchr(buf, ':'); ++ if (!colon || colon == buf) + continue; + +- *(devnode++) = '\0'; +- if (!path_startswith(devnode, "/dev")) +- continue; ++ *colon = '\0'; + + if (safe_atoi(buf, &tmp_prio) < 0) + continue; + +- if (target && tmp_prio <= priority) ++ if (devnode && tmp_prio <= priority) + continue; + +- r = free_and_strdup(&target, devnode); ++ r = free_and_strdup(&devnode, colon + 1); + if (r < 0) + return r; + + } else if (de->d_type == DT_REG) { + _cleanup_(sd_device_unrefp) sd_device *tmp_dev = NULL; +- const char *devnode; ++ const char *val; + + /* Old format. The devnode and priority must be obtained from uevent and + * udev database files. */ +@@ -199,22 +198,23 @@ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, + if (device_get_devlink_priority(tmp_dev, &tmp_prio) < 0) + continue; + +- if (target && tmp_prio <= priority) ++ if (devnode && tmp_prio <= priority) + continue; + +- if (sd_device_get_devname(tmp_dev, &devnode) < 0) ++ if (sd_device_get_devname(tmp_dev, &val) < 0) + continue; + +- r = free_and_strdup(&target, devnode); ++ r = free_and_strdup(&devnode, val); + if (r < 0) + return r; ++ + } else + continue; + + priority = tmp_prio; + } + +- *ret = TAKE_PTR(target); ++ *ret = TAKE_PTR(devnode); + return !!*ret; + } + +@@ -443,7 +443,7 @@ static int link_update(sd_device *dev, const char *slink, bool add) { + if (stat(dirname, &st1) < 0 && errno != ENOENT) + return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname); + +- r = link_find_prioritized(dev, add, dirname, &target); ++ r = stack_directory_find_prioritized_devnode(dev, dirname, add, &target); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to determine device node with the highest priority for '%s': %m", slink); + if (r == 0) { +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch b/meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch new file mode 100644 index 0000000000..6a0ea22672 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0007-udev-use-path_make_relative_parent.patch @@ -0,0 +1,43 @@ +From d6595c5ced636d44dc40adfb0b7cfc929bcac7a3 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 12:05:36 +0900 +Subject: [PATCH 07/10] udev: use path_make_relative_parent() + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/d6595c5ced636d44dc40adfb0b7cfc929bcac7a3] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index f358564b41..5a011cf86b 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -64,7 +64,7 @@ static int create_symlink(const char *target, const char *slink) { + } + + static int node_symlink(sd_device *dev, const char *devnode, const char *slink) { +- _cleanup_free_ char *slink_dirname = NULL, *target = NULL; ++ _cleanup_free_ char *target = NULL; + const char *id, *slink_tmp; + struct stat st; + int r; +@@ -81,12 +81,8 @@ static int node_symlink(sd_device *dev, const char *devnode, const char *slink) + } else if (errno != ENOENT) + return log_device_debug_errno(dev, errno, "Failed to lstat() '%s': %m", slink); + +- r = path_extract_directory(slink, &slink_dirname); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to get parent directory of '%s': %m", slink); +- + /* use relative link */ +- r = path_make_relative(slink_dirname, devnode, &target); ++ r = path_make_relative_parent(slink, devnode, &target); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, devnode); + +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch b/meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch new file mode 100644 index 0000000000..cb29367f4d --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0008-udev-make-node_symlink-accept-NULL-devname.patch @@ -0,0 +1,75 @@ +From 541a463fd5aad912c07c88d84e5a1c597c810956 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 12:08:06 +0900 +Subject: [PATCH 08/10] udev: make node_symlink() accept NULL devname + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/541a463fd5aad912c07c88d84e5a1c597c810956] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 24 +++++++++--------------- + 1 file changed, 9 insertions(+), 15 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 5a011cf86b..8e78546e18 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -70,13 +70,18 @@ static int node_symlink(sd_device *dev, const char *devnode, const char *slink) + int r; + + assert(dev); +- assert(devnode); + assert(slink); + ++ if (!devnode) { ++ r = sd_device_get_devname(dev, &devnode); ++ if (r < 0) ++ return log_device_debug_errno(dev, r, "Failed to get device node: %m"); ++ } ++ + if (lstat(slink, &st) >= 0) { + if (!S_ISLNK(st.st_mode)) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST), +- "Conflicting inode '%s' found, link to '%s' will not be created.", ++ "Conflicting inode '%s' found, symlink to '%s' will not be created.", + slink, devnode); + } else if (errno != ENOENT) + return log_device_debug_errno(dev, errno, "Failed to lstat() '%s': %m", slink); +@@ -488,23 +493,12 @@ static int device_get_devpath_by_devnum(sd_device *dev, char **ret) { + + int udev_node_update(sd_device *dev, sd_device *dev_old) { + _cleanup_free_ char *filename = NULL; +- const char *devnode, *devlink; ++ const char *devlink; + int r; + + assert(dev); + assert(dev_old); + +- r = sd_device_get_devname(dev, &devnode); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to get devnode: %m"); +- +- if (DEBUG_LOGGING) { +- const char *id = NULL; +- +- (void) device_get_device_id(dev, &id); +- log_device_debug(dev, "Handling device node '%s', devnum=%s", devnode, strna(id)); +- } +- + /* update possible left-over symlinks */ + FOREACH_DEVICE_DEVLINK(dev_old, devlink) { + /* check if old link name still belongs to this device */ +@@ -536,7 +530,7 @@ int udev_node_update(sd_device *dev, sd_device *dev_old) { + return log_device_debug_errno(dev, r, "Failed to get device path: %m"); + + /* always add /dev/{block,char}/$major:$minor */ +- r = node_symlink(dev, devnode, filename); ++ r = node_symlink(dev, NULL, filename); + if (r < 0) + return log_device_warning_errno(dev, r, "Failed to create device symlink '%s': %m", filename); + +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch b/meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch new file mode 100644 index 0000000000..96ce076378 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0009-udev-use-flock-when-updating-device-node-symlinks.patch @@ -0,0 +1,277 @@ +From 57a272902aa821f9598dd0d74eab98d287473a63 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 12:17:23 +0900 +Subject: [PATCH 09/10] udev: use flock() when updating device node symlinks + +By locking the stack directory, we can safely determine the device node +with the highest priority for a symlink. So, the multiple try-and-wait +loops can be dropped, and the code becomes quite simple. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/57a272902aa821f9598dd0d74eab98d287473a63] +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 173 ++++++++++--------------------------------- + 1 file changed, 40 insertions(+), 133 deletions(-) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 8e78546e18..42efaaa028 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -1,11 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-or-later */ + +-#include <errno.h> +-#include <fcntl.h> +-#include <stdbool.h> +-#include <stddef.h> +-#include <sys/stat.h> +-#include <unistd.h> ++#include <sys/file.h> + + #include "sd-id128.h" + +@@ -22,47 +17,15 @@ + #include "mkdir-label.h" + #include "parse-util.h" + #include "path-util.h" +-#include "random-util.h" + #include "selinux-util.h" + #include "smack-util.h" + #include "stat-util.h" +-#include "stdio-util.h" + #include "string-util.h" +-#include "strxcpyx.h" +-#include "time-util.h" + #include "udev-node.h" + #include "user-util.h" + +-#define CREATE_LINK_MAX_RETRIES 128 +-#define LINK_UPDATE_MAX_RETRIES 128 +-#define UPDATE_TIMESTAMP_MAX_RETRIES 128 +-#define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC) +-#define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC) + #define UDEV_NODE_HASH_KEY SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f) + +-static int create_symlink(const char *target, const char *slink) { +- int r; +- +- assert(target); +- assert(slink); +- +- for (unsigned i = 0; i < CREATE_LINK_MAX_RETRIES; i++) { +- r = mkdir_parents_label(slink, 0755); +- if (r == -ENOENT) +- continue; +- if (r < 0) +- return r; +- +- mac_selinux_create_file_prepare(slink, S_IFLNK); +- r = RET_NERRNO(symlink(target, slink)); +- mac_selinux_create_file_clear(); +- if (r != -ENOENT) +- return r; +- } +- +- return r; +-} +- + static int node_symlink(sd_device *dev, const char *devnode, const char *slink) { + _cleanup_free_ char *target = NULL; + const char *id, *slink_tmp; +@@ -98,7 +61,13 @@ static int node_symlink(sd_device *dev, const char *devnode, const char *slink) + slink_tmp = strjoina(slink, ".tmp-", id); + (void) unlink(slink_tmp); + +- r = create_symlink(target, slink_tmp); ++ r = mkdir_parents_label(slink_tmp, 0755); ++ if (r < 0) ++ return log_device_debug_errno(dev, r, "Failed to create parent directory of '%s': %m", slink_tmp); ++ ++ mac_selinux_create_file_prepare(slink_tmp, S_IFLNK); ++ r = RET_NERRNO(symlink(target, slink_tmp)); ++ mac_selinux_create_file_clear(); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink_tmp, target); + +@@ -219,54 +188,7 @@ static int stack_directory_find_prioritized_devnode(sd_device *dev, const char * + return !!*ret; + } + +-static int update_timestamp(sd_device *dev, int fd, struct stat *prev) { +- assert(fd >= 0); +- assert(prev); +- +- /* Even if a symlink in the stack directory is created/removed, the mtime of the directory may +- * not be changed. Why? Let's consider the following situation. For simplicity, let's assume +- * there exist two udev workers (A and B) and all of them calls link_update() for the same +- * devlink simultaneously. +- * +- * 1. A creates/removes a symlink in the stack directory. +- * 2. A calls the first stat() in the loop of link_update(). +- * 3. A calls link_find_prioritized(). +- * 4. B creates/removes another symlink in the stack directory, so the result of the step 3 is outdated. +- * 5. B finishes link_update(). +- * 6. A creates/removes devlink according to the outdated result in the step 3. +- * 7. A calls the second stat() in the loop of link_update(). +- * +- * If these 7 steps are processed in this order within a short time period that kernel's timer +- * does not increase, then even if the contents in the stack directory is changed, the results +- * of two stat() called by A shows the same timestamp, and A cannot detect the change. +- * +- * By calling this function after creating/removing symlinks in the stack directory, the +- * timestamp of the stack directory is always increased at least in the above step 5, so A can +- * detect the update. */ +- +- for (unsigned i = 0; i < UPDATE_TIMESTAMP_MAX_RETRIES; i++) { +- struct stat st; +- +- if (fstat(fd, &st) < 0) +- return -errno; +- +- if (!stat_inode_unmodified(prev, &st)) +- return 0; +- +- log_device_debug(dev, +- "Stack directory is modified, but its timestamp is not changed, " +- "updating timestamp after 10ms."); +- +- (void) usleep(10 * USEC_PER_MSEC); +- if (futimens(fd, NULL) < 0) +- return -errno; +- } +- +- return -ELOOP; +-} +- + static int stack_directory_update(sd_device *dev, int fd, bool add) { +- struct stat st; + const char *id; + int r; + +@@ -277,9 +199,6 @@ static int stack_directory_update(sd_device *dev, int fd, bool add) { + if (r < 0) + return r; + +- if (fstat(fd, &st) < 0) +- return -errno; +- + if (add) { + _cleanup_free_ char *data = NULL, *buf = NULL; + const char *devname; +@@ -312,11 +231,7 @@ static int stack_directory_update(sd_device *dev, int fd, bool add) { + } + } + +- r = update_timestamp(dev, fd, &st); +- if (r < 0) +- return r; +- +- return 0; ++ return 1; /* Updated. */ + } + + static int stack_directory_open(const char *dirname) { +@@ -336,6 +251,21 @@ static int stack_directory_open(const char *dirname) { + return TAKE_FD(fd); + } + ++static int stack_directory_lock(int dirfd) { ++ _cleanup_close_ int fd = -1; ++ ++ assert(dirfd >= 0); ++ ++ fd = openat(dirfd, ".lock", O_CLOEXEC | O_NOFOLLOW | O_RDONLY | O_CREAT, 0600); ++ if (fd < 0) ++ return -errno; ++ ++ if (flock(fd, LOCK_EX) < 0) ++ return -errno; ++ ++ return TAKE_FD(fd); ++} ++ + size_t udev_node_escape_path(const char *src, char *dest, size_t size) { + size_t i, j; + uint64_t h; +@@ -410,8 +340,8 @@ static int stack_directory_get_name(const char *slink, char **ret) { + } + + static int link_update(sd_device *dev, const char *slink, bool add) { +- _cleanup_free_ char *dirname = NULL; +- _cleanup_close_ int dirfd = -1; ++ _cleanup_free_ char *dirname = NULL, *devnode = NULL; ++ _cleanup_close_ int dirfd = -1, lockfd = -1; + int r; + + assert(dev); +@@ -425,51 +355,28 @@ static int link_update(sd_device *dev, const char *slink, bool add) { + if (dirfd < 0) + return log_device_debug_errno(dev, dirfd, "Failed to open stack directory '%s': %m", dirname); + ++ lockfd = stack_directory_lock(dirfd); ++ if (lockfd < 0) ++ return log_device_debug_errno(dev, lockfd, "Failed to lock stack directory '%s': %m", dirname); ++ + r = stack_directory_update(dev, dirfd, add); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to update stack directory '%s': %m", dirname); + +- for (unsigned i = 0; i < LINK_UPDATE_MAX_RETRIES; i++) { +- _cleanup_free_ char *target = NULL; +- struct stat st1 = {}, st2 = {}; +- +- if (i > 0) { +- usec_t delay = MIN_RANDOM_DELAY + random_u64_range(MAX_RANDOM_DELAY - MIN_RANDOM_DELAY); +- +- log_device_debug(dev, "Directory %s was updated, retrying to update devlink %s after %s.", +- dirname, slink, FORMAT_TIMESPAN(delay, USEC_PER_MSEC)); +- (void) usleep(delay); +- } +- +- if (stat(dirname, &st1) < 0 && errno != ENOENT) +- return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname); +- +- r = stack_directory_find_prioritized_devnode(dev, dirname, add, &target); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to determine device node with the highest priority for '%s': %m", slink); +- if (r == 0) { +- log_device_debug(dev, "No reference left for '%s', removing", slink); +- +- if (unlink(slink) < 0 && errno != ENOENT) +- log_device_debug_errno(dev, errno, "Failed to remove '%s', ignoring: %m", slink); ++ r = stack_directory_find_prioritized_devnode(dev, dirname, add, &devnode); ++ if (r < 0) ++ return log_device_debug_errno(dev, r, "Failed to determine device node with the highest priority for '%s': %m", slink); ++ if (r > 0) ++ return node_symlink(dev, devnode, slink); + +- (void) rmdir_parents(slink, "/dev"); +- return 0; +- } ++ log_device_debug(dev, "No reference left for '%s', removing", slink); + +- r = node_symlink(dev, target, slink); +- if (r < 0) +- return r; ++ if (unlink(slink) < 0 && errno != ENOENT) ++ log_device_debug_errno(dev, errno, "Failed to remove '%s', ignoring: %m", slink); + +- if (stat(dirname, &st2) < 0 && errno != ENOENT) +- return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname); ++ (void) rmdir_parents(slink, "/dev"); + +- if (((st1.st_mode & S_IFMT) == 0 && (st2.st_mode & S_IFMT) == 0) || +- stat_inode_unmodified(&st1, &st2)) +- return 0; +- } +- +- return -ELOOP; ++ return 0; + } + + static int device_get_devpath_by_devnum(sd_device *dev, char **ret) { +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch b/meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch new file mode 100644 index 0000000000..7a6f614db7 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch @@ -0,0 +1,130 @@ +From 1055172804e660df2e1c498dafa998ffd65e0c88 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Mon, 11 Apr 2022 21:52:49 +0900 +Subject: [PATCH 10/10] udev: cleanup stack directory /run/udev/links when all + workers exited + +By the previous commit, the stack directories are not removed even if +it is empty. To reduce the inode usage of /run, let's cleanup the +directories. + +PR - https://github.com/systemd/systemd/pull/23043 +Upstream-Status: Backport [https://github.com/systemd/systemd/pull/23043/commits/1055172804e660df2e1c498dafa998ffd65e0c88] +Comments: Refreshed all hunks to apply patch cleanly without patch-fuzz +Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> + +--- + src/udev/udev-node.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + src/udev/udev-node.h | 1 + + src/udev/udevd.c | 10 ++++++++++ + 3 files changed, 53 insertions(+) + +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 42efaaa028..4e7dca06de 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -24,6 +24,48 @@ + + #define UDEV_NODE_HASH_KEY SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f) + ++int udev_node_cleanup(void) { ++ _cleanup_closedir_ DIR *dir = NULL; ++ ++ /* This must not be called when any workers exist. It would cause a race between mkdir() called ++ * by stack_directory_lock() and unlinkat() called by this. */ ++ ++ dir = opendir("/run/udev/links"); ++ if (!dir) { ++ if (errno == ENOENT) ++ return 0; ++ ++ return log_debug_errno(errno, "Failed to open directory '/run/udev/links', ignoring: %m"); ++ } ++ ++ FOREACH_DIRENT_ALL(de, dir, break) { ++ _cleanup_free_ char *lockfile = NULL; ++ ++ if (de->d_name[0] == '.') ++ continue; ++ ++ if (de->d_type != DT_DIR) ++ continue; ++ ++ /* As commented in the above, this is called when no worker exists, hence the file is not ++ * locked. On a later uevent, the lock file will be created if necessary. So, we can safely ++ * remove the file now. */ ++ lockfile = path_join(de->d_name, ".lock"); ++ if (!lockfile) ++ return log_oom_debug(); ++ ++ if (unlinkat(dirfd(dir), lockfile, 0) < 0 && errno != ENOENT) { ++ log_debug_errno(errno, "Failed to remove '/run/udev/links/%s', ignoring: %m", lockfile); ++ continue; ++ } ++ ++ if (unlinkat(dirfd(dir), de->d_name, AT_REMOVEDIR) < 0 && errno != ENOTEMPTY) ++ log_debug_errno(errno, "Failed to remove '/run/udev/links/%s', ignoring: %m", de->d_name); ++ } ++ ++ return 0; ++} ++ + static int node_symlink(sd_device *dev, const char *devnode, const char *slink) { + _cleanup_free_ char *target = NULL; + const char *id, *slink_tmp; +diff --git a/src/udev/udev-node.h b/src/udev/udev-node.h +index 86a829545a..0c545e4a0f 100644 +--- a/src/udev/udev-node.h ++++ b/src/udev/udev-node.h +@@ -17,5 +17,6 @@ int udev_node_apply_permissions( + OrderedHashmap *seclabel_list); + int udev_node_remove(sd_device *dev); + int udev_node_update(sd_device *dev, sd_device *dev_old); ++int udev_node_cleanup(void); + + size_t udev_node_escape_path(const char *src, char *dest, size_t size); +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index b179dfac37..c519e19897 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -62,6 +62,7 @@ + #include "udev-builtin.h" + #include "udev-ctrl.h" + #include "udev-event.h" ++#include "udev-node.h" + #include "udev-util.h" + #include "udev-watch.h" + #include "user-util.h" +@@ -106,6 +107,7 @@ typedef struct Manager { + + usec_t last_usec; + ++ bool udev_node_needs_cleanup; + bool stop_exec_queue; + bool exit; + } Manager; +@@ -933,6 +935,9 @@ static int event_queue_start(Manager *ma + manager->last_usec = usec; + } + ++ /* To make the stack directory /run/udev/links cleaned up later. */ ++ manager->udev_node_needs_cleanup = true; ++ + 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"); +@@ -1487,6 +1492,11 @@ static int on_post(sd_event_source *s, v + + /* There are no idle workers. */ + ++ if (manager->udev_node_needs_cleanup) { ++ (void) udev_node_cleanup(); ++ manager->udev_node_needs_cleanup = false; ++ } ++ + if (manager->exit) + return sd_event_exit(manager->event, 0); + +-- +2.25.1 + diff --git a/meta/recipes-core/systemd/systemd_250.5.bb b/meta/recipes-core/systemd/systemd_250.5.bb index 4d520c85f3..22ebc0a229 100644 --- a/meta/recipes-core/systemd/systemd_250.5.bb +++ b/meta/recipes-core/systemd/systemd_250.5.bb @@ -34,6 +34,16 @@ SRC_URI += "file://touchscreen.rules \ file://0001-nspawn-make-sure-host-root-can-write-to-the-uidmappe.patch \ file://CVE-2023-7008.patch \ file://fix-vlan-qos-mapping.patch \ + file://0001-udev-move-udev_node_escape_path.patch \ + file://0002-udev-split-link_update-and-introduce-stack_directory.patch \ + file://0003-udev-do-not-remove-stack-directory-even-if-it-is-emp.patch \ + file://0004-path-util-introduce-path_make_relative_parent.patch \ + file://0005-udev-use-readlinkat_malloc.patch \ + file://0006-udev-rename-link_find_prioritized-and-variables.patch \ + file://0007-udev-use-path_make_relative_parent.patch \ + file://0008-udev-make-node_symlink-accept-NULL-devname.patch \ + file://0009-udev-use-flock-when-updating-device-node-symlinks.patch \ + file://0010-udev-cleanup-stack-directory-run-udev-links-when-all.patch \ " # patches needed by musl