summaryrefslogtreecommitdiffstats
path: root/src/udev
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-04-07 15:11:00 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-04-07 18:35:43 +0200
commitfa28023c0fd3b474eb3fbb747f0202aaed73db15 (patch)
tree4628d7a818c1bf0f83755817391884eff172e075 /src/udev
parentudev: it is not necessary that the path is readable (diff)
downloadsystemd-fa28023c0fd3b474eb3fbb747f0202aaed73db15.tar.xz
systemd-fa28023c0fd3b474eb3fbb747f0202aaed73db15.zip
udev: split out logic of parsing s390 PCI slots
This also adds several debugging logs.
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udev-builtin-net_id.c72
1 files changed, 46 insertions, 26 deletions
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index c6f2e6ddf5..6be57db7c7 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -23,6 +23,7 @@
#include <linux/pci_regs.h>
#include "alloc-util.h"
+#include "device-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -262,6 +263,43 @@ static bool is_pci_bridge(sd_device *dev) {
return strneq(p + 2, "04", 2);
}
+static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots, int *ret) {
+ char path[PATH_MAX];
+ const char *attr;
+ int function_id, r;
+
+ /* The <sysname>/function_id attribute is unique to the s390 PCI driver. If present, we know
+ * that the slot's directory name for this device is /sys/bus/pci/XXXXXXXX/ where XXXXXXXX is
+ * the fixed length 8 hexadecimal character string representation of function_id. Therefore we
+ * can short cut here and just check for the existence of the slot directory. As this directory
+ * has to exist, we're emitting a debug message for the unlikely case it's not found. Note that
+ * the domain part doesn't belong to the slot name here because there's a 1-to-1 relationship
+ * between PCI function and its hotplug slot. */
+
+ assert(dev);
+ assert(slots);
+ assert(ret);
+
+ if (!naming_scheme_has(NAMING_SLOT_FUNCTION_ID))
+ return 0;
+
+ if (sd_device_get_sysattr_value(dev, "function_id", &attr) < 0)
+ return 0;
+
+ r = safe_atoi(attr, &function_id);
+ if (r < 0)
+ return log_device_debug_errno(dev, r, "Failed to parse function_id, ignoring: %s", attr);
+
+ if (!snprintf_ok(path, sizeof path, "%s/%08x/", slots, function_id))
+ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENAMETOOLONG), "PCI slot path is too long, ignoring.");
+
+ if (access(path, F_OK) < 0)
+ return log_device_debug_errno(dev, errno, "Cannot access %s, ignoring: %m", path);
+
+ *ret = function_id;
+ return 1;
+}
+
static int dev_pci_slot(sd_device *dev, struct netnames *names) {
unsigned long dev_port = 0;
unsigned domain, bus, slot, func;
@@ -342,35 +380,17 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
hotplug_slot_dev = names->pcidev;
while (hotplug_slot_dev) {
- if (sd_device_get_sysname(hotplug_slot_dev, &sysname) < 0)
- continue;
-
- /* The <sysname>/function_id attribute is unique to the s390 PCI driver.
- If present, we know that the slot's directory name for this device is
- /sys/bus/pci/XXXXXXXX/ where XXXXXXXX is the fixed length 8 hexadecimal
- character string representation of function_id.
- Therefore we can short cut here and just check for the existence of
- the slot directory. As this directory has to exist, we're emitting a
- debug message for the unlikely case it's not found.
- Note that the domain part of doesn't belong to the slot name here
- because there's a 1-to-1 relationship between PCI function and its hotplug
- slot.
- */
- if (naming_scheme_has(NAMING_SLOT_FUNCTION_ID) &&
- sd_device_get_sysattr_value(hotplug_slot_dev, "function_id", &attr) >= 0) {
- _cleanup_free_ char *str = NULL;
- int function_id;
-
- if (safe_atoi(attr, &function_id) >= 0 &&
- asprintf(&str, "%s/%08x/", slots, function_id) >= 0 &&
- access(str, F_OK) == 0) {
- hotplug_slot = function_id;
- domain = 0;
- } else
- log_debug("No matching slot for function_id (%s).", attr);
+ r = parse_hotplug_slot_from_function_id(hotplug_slot_dev, slots, &hotplug_slot);
+ if (r < 0)
+ return 0;
+ if (r > 0) {
+ domain = 0; /* See comments in parse_hotplug_slot_from_function_id(). */
break;
}
+ if (sd_device_get_sysname(hotplug_slot_dev, &sysname) < 0)
+ continue;
+
FOREACH_DIRENT_ALL(dent, dir, break) {
int i;
char str[PATH_MAX];