4eda52
From 75275ae07233e213fe03a1a33870efe10dbb2b39 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
4eda52
Related: #2005024
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