summaryrefslogtreecommitdiffstats
path: root/debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch')
-rw-r--r--debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch163
1 files changed, 163 insertions, 0 deletions
diff --git a/debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch b/debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch
new file mode 100644
index 0000000..36bdbb5
--- /dev/null
+++ b/debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch
@@ -0,0 +1,163 @@
+From: Michael Biebl <biebl@debian.org>
+Date: Sat, 25 Sep 2021 21:08:36 +0200
+Subject: Revert "udev: make algorithm that selects highest priority devlink
+ less susceptible to race conditions"
+
+This reverts commit 30f6dce62cb3a738b20253f2192270607c31b55b.
+---
+ src/udev/udev-event.c | 7 -----
+ src/udev/udev-node.c | 75 +++++++++++----------------------------------------
+ 2 files changed, 15 insertions(+), 67 deletions(-)
+
+diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
+index 5159d19..9cf5190 100644
+--- a/src/udev/udev-event.c
++++ b/src/udev/udev-event.c
+@@ -1041,13 +1041,6 @@ int udev_event_execute_rules(UdevEvent *event,
+ if (r < 0)
+ return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m");
+
+- /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database,
+- * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure
+- * symlinks point to devices that claim them with the highest priority. */
+- r = update_devnode(event);
+- if (r < 0)
+- return r;
+-
+ device_set_is_initialized(dev);
+
+ return 0;
+diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
+index bde18f7..9d4b7d9 100644
+--- a/src/udev/udev-node.c
++++ b/src/udev/udev-node.c
+@@ -20,15 +20,12 @@
+ #include "path-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 "udev-node.h"
+ #include "user-util.h"
+
+-#define LINK_UPDATE_MAX_RETRIES 128
+-
+ static int node_symlink(sd_device *dev, const char *node, const char *slink) {
+ _cleanup_free_ char *slink_dirname = NULL, *target = NULL;
+ const char *id_filename, *slink_tmp;
+@@ -102,9 +99,7 @@ static int node_symlink(sd_device *dev, const char *node, const char *slink) {
+ if (rename(slink_tmp, slink) < 0) {
+ r = log_device_error_errno(dev, errno, "Failed to rename '%s' to '%s': %m", slink_tmp, slink);
+ (void) unlink(slink_tmp);
+- } else
+- /* Tell caller that we replaced already existing symlink. */
+- r = 1;
++ }
+
+ return r;
+ }
+@@ -197,7 +192,7 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
+ _cleanup_free_ char *target = NULL, *filename = NULL, *dirname = NULL;
+ char name_enc[PATH_MAX];
+ const char *id_filename;
+- int i, r, retries;
++ int r;
+
+ assert(dev);
+ assert(slink);
+@@ -217,6 +212,14 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
+ if (!add && unlink(filename) == 0)
+ (void) rmdir(dirname);
+
++ r = link_find_prioritized(dev, add, dirname, &target);
++ if (r < 0) {
++ log_device_debug(dev, "No reference left, removing '%s'", slink);
++ if (unlink(slink) == 0)
++ (void) rmdir_parents(slink, "/");
++ } else
++ (void) node_symlink(dev, target, slink);
++
+ if (add)
+ do {
+ _cleanup_close_ int fd = -1;
+@@ -229,49 +232,7 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
+ r = -errno;
+ } while (r == -ENOENT);
+
+- /* If the database entry is not written yet we will just do one iteration and possibly wrong symlink
+- * will be fixed in the second invocation. */
+- retries = sd_device_get_is_initialized(dev) > 0 ? LINK_UPDATE_MAX_RETRIES : 1;
+-
+- for (i = 0; i < retries; i++) {
+- struct stat st1 = {}, st2 = {};
+-
+- r = stat(dirname, &st1);
+- if (r < 0 && errno != ENOENT)
+- return -errno;
+-
+- r = link_find_prioritized(dev, add, dirname, &target);
+- if (r == -ENOENT) {
+- log_device_debug(dev, "No reference left, removing '%s'", slink);
+- if (unlink(slink) == 0)
+- (void) rmdir_parents(slink, "/");
+-
+- break;
+- } else if (r < 0)
+- return log_device_error_errno(dev, r, "Failed to determine highest priority symlink: %m");
+-
+- r = node_symlink(dev, target, slink);
+- if (r < 0) {
+- (void) unlink(filename);
+- break;
+- } else if (r == 1)
+- /* We have replaced already existing symlink, possibly there is some other device trying
+- * to claim the same symlink. Let's do one more iteration to give us a chance to fix
+- * the error if other device actually claims the symlink with higher priority. */
+- continue;
+-
+- /* Skip the second stat() if the first failed, stat_inode_unmodified() would return false regardless. */
+- if ((st1.st_mode & S_IFMT) != 0) {
+- r = stat(dirname, &st2);
+- if (r < 0 && errno != ENOENT)
+- return -errno;
+-
+- if (stat_inode_unmodified(&st1, &st2))
+- break;
+- }
+- }
+-
+- return i < LINK_UPDATE_MAX_RETRIES ? 0 : -ELOOP;
++ return r;
+ }
+
+ int udev_node_update_old_links(sd_device *dev, sd_device *dev_old) {
+@@ -490,11 +451,8 @@ int udev_node_add(sd_device *dev, bool apply,
+ (void) node_symlink(dev, devnode, filename);
+
+ /* create/update symlinks, add symlinks to name index */
+- FOREACH_DEVICE_DEVLINK(dev, devlink) {
+- r = link_update(dev, devlink, true);
+- if (r < 0)
+- log_device_info_errno(dev, r, "Failed to update device symlinks: %m");
+- }
++ FOREACH_DEVICE_DEVLINK(dev, devlink)
++ (void) link_update(dev, devlink, true);
+
+ return 0;
+ }
+@@ -507,11 +465,8 @@ int udev_node_remove(sd_device *dev) {
+ assert(dev);
+
+ /* remove/update symlinks, remove symlinks from name index */
+- FOREACH_DEVICE_DEVLINK(dev, devlink) {
+- r = link_update(dev, devlink, false);
+- if (r < 0)
+- log_device_info_errno(dev, r, "Failed to update device symlinks: %m");
+- }
++ FOREACH_DEVICE_DEVLINK(dev, devlink)
++ (void) link_update(dev, devlink, false);
+
+ r = xsprintf_dev_num_path_from_sd_device(dev, &filename);
+ if (r < 0)