}
static int stack_directory_read_one(int dirfd, const char *id, char **devnode, int *priority) {
- _cleanup_free_ char *buf = NULL;
- int tmp_prio, r;
+ int r;
assert(dirfd >= 0);
assert(id);
assert(priority);
- /* This reads priority and device node from the symlink under /run/udev/links (or udev database).
+ /* This reads priority and device node from the symlink under /run/udev/links/ directory.
* If 'devnode' is NULL, obtained priority is always set to '*priority'. If 'devnode' is non-NULL,
- * this updates '*devnode' and '*priority'. */
+ * this updates '*devnode' and '*priority' if the obtained one has a higher priority. */
- /* First, let's try to read the entry with the new format, which should replace the old format pretty
- * quickly. */
+ _cleanup_free_ char *buf = NULL;
r = readlinkat_malloc(dirfd, id, &buf);
- if (r >= 0) {
- char *colon;
-
- /* With the new format, the devnode and priority can be obtained from symlink itself. */
-
- colon = strchr(buf, ':');
- if (!colon || colon == buf)
- return -EINVAL;
+ if (r < 0)
+ return r == -ENOENT ? -ENODEV : r;
- *colon = '\0';
+ char *colon = strchr(buf, ':');
+ if (!colon || colon == buf)
+ return -EINVAL;
- /* Of course, this check is racy, but it is not necessary to be perfect. Even if the device
- * node will be removed after this check, we will receive 'remove' uevent, and the invalid
- * symlink will be removed during processing the event. The check is just for shortening the
- * timespan that the symlink points to a non-existing device node. */
- if (access(colon + 1, F_OK) < 0)
- return -ENODEV;
+ *colon = '\0';
- r = safe_atoi(buf, &tmp_prio);
- if (r < 0)
- return r;
+ /* Of course, this check is racy, but it is not necessary to be perfect. Even if the device
+ * node will be removed after this check, we will receive 'remove' uevent, and the invalid
+ * symlink will be removed during processing the event. The check is just for shortening the
+ * timespan that the symlink points to a non-existing device node. */
+ if (access(colon + 1, F_OK) < 0)
+ return -ENODEV;
- if (!devnode)
- goto finalize;
+ int tmp_prio;
+ r = safe_atoi(buf, &tmp_prio);
+ if (r < 0)
+ return r;
+ if (devnode) {
if (*devnode && tmp_prio <= *priority)
return 0; /* Unchanged */
r = free_and_strdup(devnode, colon + 1);
if (r < 0)
return r;
+ }
- } else if (r == -EINVAL) { /* Not a symlink ? try the old format */
- _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
- const char *val;
-
- /* Old format. The devnode and priority must be obtained from uevent and udev database. */
-
- r = sd_device_new_from_device_id(&dev, id);
- if (r < 0)
- return r;
-
- r = device_get_devlink_priority(dev, &tmp_prio);
- if (r < 0)
- return r;
-
- if (!devnode)
- goto finalize;
-
- if (*devnode && tmp_prio <= *priority)
- return 0; /* Unchanged */
-
- r = sd_device_get_devname(dev, &val);
- if (r < 0)
- return r;
-
- r = free_and_strdup(devnode, val);
- if (r < 0)
- return r;
-
- } else
- return r == -ENOENT ? -ENODEV : r;
-
-finalize:
*priority = tmp_prio;
return 1; /* Updated */
}