summaryrefslogtreecommitdiffstats
path: root/debian/patches/debian/Revert-udev-make-algorithm-that-selects-highest-priority-.patch
blob: 36bdbb55106cab85903ffb29f1157dbc149505df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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)