4295f9
From c484f91a87679fb26342408f20e7bdddf316f5a0 Mon Sep 17 00:00:00 2001
4295f9
From: Yu Watanabe <watanabe.yu+github@gmail.com>
4295f9
Date: Wed, 1 Sep 2021 04:34:48 +0900
4295f9
Subject: [PATCH] udev-node: add random delay on conflict in updating device
4295f9
 node symlink
4295f9
4295f9
To make multiple workers not update the same device node symlink
4295f9
simultaneously.
4295f9
4295f9
(cherry picked from commit 0063fa23a1384dd4385d03b568dc629916b7e72a)
4295f9
4295f9
Related: #1977994
4295f9
---
4295f9
 src/udev/udev-node.c | 12 ++++++++++++
4295f9
 1 file changed, 12 insertions(+)
4295f9
4295f9
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
4295f9
index 2e7df899e4..675e6ce313 100644
4295f9
--- a/src/udev/udev-node.c
4295f9
+++ b/src/udev/udev-node.c
4295f9
@@ -20,12 +20,14 @@
4295f9
 #include "mkdir.h"
4295f9
 #include "parse-util.h"
4295f9
 #include "path-util.h"
4295f9
+#include "random-util.h"
4295f9
 #include "selinux-util.h"
4295f9
 #include "smack-util.h"
4295f9
 #include "stat-util.h"
4295f9
 #include "stdio-util.h"
4295f9
 #include "string-util.h"
4295f9
 #include "strxcpyx.h"
4295f9
+#include "time-util.h"
4295f9
 #include "udev-node.h"
4295f9
 #include "user-util.h"
4295f9
 
4295f9
@@ -33,6 +35,8 @@
4295f9
 #define LINK_UPDATE_MAX_RETRIES        128
4295f9
 #define CREATE_STACK_LINK_MAX_RETRIES  128
4295f9
 #define UPDATE_TIMESTAMP_MAX_RETRIES   128
4295f9
+#define MAX_RANDOM_DELAY (250 * USEC_PER_MSEC)
4295f9
+#define MIN_RANDOM_DELAY ( 50 * USEC_PER_MSEC)
4295f9
 #define UDEV_NODE_HASH_KEY SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f)
4295f9
 
4295f9
 static int create_symlink(const char *target, const char *slink) {
4295f9
@@ -447,6 +451,14 @@ static int link_update(sd_device *dev, const char *slink_in, bool add) {
4295f9
                 _cleanup_free_ char *target = NULL;
4295f9
                 struct stat st1 = {}, st2 = {};
4295f9
 
4295f9
+                if (i > 0) {
4295f9
+                        usec_t delay = MIN_RANDOM_DELAY + random_u64_range(MAX_RANDOM_DELAY - MIN_RANDOM_DELAY);
4295f9
+
4295f9
+                        log_device_debug(dev, "Directory %s was updated, retrying to update devlink %s after %s.",
4295f9
+                                         dirname, slink, FORMAT_TIMESPAN(delay, USEC_PER_MSEC));
4295f9
+                        (void) usleep(delay);
4295f9
+                }
4295f9
+
4295f9
                 if (stat(dirname, &st1) < 0 && errno != ENOENT)
4295f9
                         return log_device_debug_errno(dev, errno, "Failed to stat %s: %m", dirname);
4295f9