From: Yu Watanabe Date: Wed, 2 Jun 2021 14:36:03 +0000 (+0900) Subject: udev: use touch_file() and limit the number of trial X-Git-Tag: v249-rc1~91^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5733bd4862aa5b9b20f2fdd967c0c0e8dd26deb7;p=thirdparty%2Fsystemd.git udev: use touch_file() and limit the number of trial --- diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 1702f489d1c..5e556926f98 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -30,6 +30,7 @@ #include "user-util.h" #define LINK_UPDATE_MAX_RETRIES 128 +#define TOUCH_FILE_MAX_RETRIES 128 #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 node_symlink(sd_device *dev, const char *node, const char *slink) { @@ -279,20 +280,17 @@ static int link_update(sd_device *dev, const char *slink_in, bool add) { log_device_debug_errno(dev, errno, "Failed to remove %s, ignoring: %m", filename); (void) rmdir(dirname); - } else - for (;;) { - _cleanup_close_ int fd = -1; - - r = mkdir_parents(filename, 0755); - if (!IN_SET(r, 0, -ENOENT)) - return r; - - fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); - if (fd >= 0) + } else { + for (unsigned j = 0; j < TOUCH_FILE_MAX_RETRIES; j++) { + /* This may fail with -ENOENT when the parent directory is removed during + * creating the file by another udevd worker. */ + r = touch_file(filename, /* parents= */ true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444); + if (r != -ENOENT) break; - if (errno != ENOENT) - return -errno; } + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to create %s: %m", filename); + } /* 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. */