]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: use uint32_t for hotplug_slot
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 7 Apr 2021 10:17:23 +0000 (19:17 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 7 Apr 2021 16:38:43 +0000 (01:38 +0900)
This also makes function id is parsed as uint64_t. Kernel internally
uses uint32_t for function id (see the definition of 'struct zpci_dev),
but it maybe extended in the future.

src/udev/udev-builtin-net_id.c

index 6be57db7c7a0ee832b0019ab533400bc377ac2e9..fa7f162a57c4ac3613ba980be72e1e202cc30439 100644 (file)
@@ -263,10 +263,11 @@ 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) {
+static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots, uint32_t *ret) {
+        uint64_t function_id;
         char path[PATH_MAX];
         const char *attr;
-        int function_id, r;
+        int 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
@@ -286,32 +287,36 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots
         if (sd_device_get_sysattr_value(dev, "function_id", &attr) < 0)
                 return 0;
 
-        r = safe_atoi(attr, &function_id);
+        r = safe_atou64(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 (function_id <= 0 || function_id > UINT32_MAX)
+                return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL),
+                                              "Invalid function id (0x%"PRIx64"), ignoring.",
+                                              function_id);
+
+        if (!snprintf_ok(path, sizeof path, "%s/%08"PRIx64, 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;
+        *ret = (uint32_t) 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;
-        int hotplug_slot = -1;
-        size_t l;
-        char *s;
         const char *sysname, *attr, *port_name = NULL, *syspath;
         _cleanup_(sd_device_unrefp) sd_device *pci = NULL;
-        sd_device *hotplug_slot_dev;
-        char slots[PATH_MAX];
         _cleanup_closedir_ DIR *dir = NULL;
-        struct dirent *dent;
+        unsigned domain, bus, slot, func;
+        sd_device *hotplug_slot_dev;
+        unsigned long dev_port = 0;
+        uint32_t hotplug_slot = 0;
+        char slots[PATH_MAX], *s;
+        size_t l;
         int r;
 
         r = sd_device_get_sysname(names->pcidev, &sysname);
@@ -380,6 +385,8 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
 
         hotplug_slot_dev = names->pcidev;
         while (hotplug_slot_dev) {
+                struct dirent *dent;
+
                 r = parse_hotplug_slot_from_function_id(hotplug_slot_dev, slots, &hotplug_slot);
                 if (r < 0)
                         return 0;
@@ -392,14 +399,14 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
                         continue;
 
                 FOREACH_DIRENT_ALL(dent, dir, break) {
-                        int i;
-                        char str[PATH_MAX];
                         _cleanup_free_ char *address = NULL;
+                        char str[PATH_MAX];
+                        uint32_t i;
 
                         if (dot_or_dot_dot(dent->d_name))
                                 continue;
 
-                        r = safe_atoi(dent->d_name, &i);
+                        r = safe_atou32(dent->d_name, &i);
                         if (r < 0 || i <= 0)
                                 continue;
 
@@ -419,7 +426,7 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
                                 break;
                         }
                 }
-                if (hotplug_slot >= 0)
+                if (hotplug_slot > 0)
                         break;
                 if (sd_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL, &hotplug_slot_dev) < 0)
                         break;
@@ -431,7 +438,7 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
                 l = sizeof(names->pci_slot);
                 if (domain > 0)
                         l = strpcpyf(&s, l, "P%d", domain);
-                l = strpcpyf(&s, l, "s%d", hotplug_slot);
+                l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot);
                 if (func > 0 || is_pci_multifunction(names->pcidev))
                         l = strpcpyf(&s, l, "f%d", func);
                 if (port_name)