udev-node: chase devlink on remove event
Previously, readlink_malloc() was used to find the target device. However, devlink is a relative symbolic link, hence the path obtained by readlink_malloc() never matched with the one by sd_device_get_devname(). Also path_startswith(target, "/dev/") was always negative. Let's use chase_and_stat() to obtain the absolute path to the target device that the devlink currently points to. Fixes the following spurious logs on remove event: (udev-worker)[2338]: loop1p1: Processing device (SEQNUM=2231, ACTION=remove) (udev-worker)[2338]: Notify message sent to '@4814750286313953891': "INOTIFY_WATCH_REMOVE=1" (udev-worker)[2338]: loop1p1: Symbolic link '/dev/udevtest/x2' points to '../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/udevtest/x2', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-diskseq/9-part1' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-diskseq/9-part1', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-label/udevtest-b-fs1' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-label/udevtest-b-fs1', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-uuid/221d135f-7bf7-45b8-abeb-d9b3afb2c215' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-uuid/221d135f-7bf7-45b8-abeb-d9b3afb2c215', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-partlabel/udevtest-b-part1' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-partlabel/udevtest-b-part1', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/udevtest/b1' points to '../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/udevtest/b1', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/udevtest/x1' points to '../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/udevtest/x1', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-partuuid/5ef627b6-95f1-a942-8d7a-bd4ac53485ac' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-partuuid/5ef627b6-95f1-a942-8d7a-bd4ac53485ac', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/udevtest/b3' points to '../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/udevtest/b3', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-loop-inode/0:36-13-part1' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-loop-inode/0:36-13-part1', removing (udev-worker)[2338]: loop1p1: Symbolic link '/dev/disk/by-loop-ref/\x2ftmp\x2fudevtest-b.img-part1' points to '../../loop1p1' which is outside of '/dev/', updating it. (udev-worker)[2338]: loop1p1: No reference left for '/dev/disk/by-loop-ref/\x2ftmp\x2fudevtest-b.img-part1', removing (udev-worker)[2338]: loop1p1: Device processed (SEQNUM=2231, ACTION=remove) (cherry picked from commit 03a65741d77d61929b98977d1bfdf2b470e14b55)
This commit is contained in:
committed by
Luca Boccassi
parent
2c4e3b9a6b
commit
96be8707ef
+7
-16
@@ -7,6 +7,7 @@
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "chase.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "devnum-util.h"
|
||||
@@ -423,22 +424,21 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
|
||||
return log_device_debug_errno(dev, r, "Failed to update stack directory for '%s': %m", slink);
|
||||
|
||||
if (!add) {
|
||||
_cleanup_free_ char *target = NULL;
|
||||
|
||||
/* Especially on 'remove' event, the device ID obtained by node_get_current() may not be
|
||||
* reliable, as the device node and/or device number may be reused. Hence, let's read the
|
||||
* devlink here and if it points to our device node, then we need to update the devlink. If
|
||||
* it points to another device node, then it is already owned by another device, hence we
|
||||
* should not touch it and keep it as is. */
|
||||
|
||||
r = readlink_malloc(slink, &target);
|
||||
_cleanup_free_ char *target = NULL;
|
||||
struct stat st;
|
||||
r = chase_and_stat(slink, /* root= */ NULL, /* chase_flags= */ 0, &target, &st);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
log_device_debug_errno(dev, r, "Failed to read symbolic link '%s', ignoring: %m", slink);
|
||||
log_device_debug_errno(dev, r, "Failed to chase and stat '%s', ignoring: %m", slink);
|
||||
|
||||
/* The devlink does not exist. Let's find the most suitable owner, and create the
|
||||
* devlink. This is typically not necessary and does nothing, but for safety in the
|
||||
* case that the devlink is removed manually. */
|
||||
/* The devlink or its target device does not exist. Let's find the most suitable
|
||||
* owner, and create or update the devlink. */
|
||||
return link_search_and_update(dev, slink, dirfd, add);
|
||||
}
|
||||
|
||||
@@ -458,15 +458,6 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
|
||||
return link_search_and_update(dev, slink, dirfd, add);
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (lstat(target, &st) < 0) {
|
||||
if (errno != ENOENT)
|
||||
log_device_debug_errno(dev, errno, "Failed to stat '%s', ignoring: %m", target);
|
||||
|
||||
/* The current target device is also already removed? Let's update. */
|
||||
return link_search_and_update(dev, slink, dirfd, add);
|
||||
}
|
||||
|
||||
if (!IN_SET(st.st_mode & S_IFMT, S_IFBLK, S_IFCHR)) {
|
||||
log_device_debug(dev, "Symbolic link '%s' points to '%s' which is not a device node, updating it.", slink, target);
|
||||
return link_search_and_update(dev, slink, dirfd, add);
|
||||
|
||||
Reference in New Issue
Block a user