/* retrieve on-board index number and label from firmware */ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { unsigned dev_port = 0; size_t l; char *s; const char *attr; int idx; /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */ attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); /* SMBIOS type 41 -- Onboard Devices Extended Information */ if (!attr) attr = udev_device_get_sysattr_value(names->pcidev, "index"); if (!attr) return -ENOENT; idx = strtoul(attr, NULL, 0); if (idx <= 0) return -EINVAL; /* kernel provided port index for multiple ports on a single PCI function */ attr = udev_device_get_sysattr_value(dev, "dev_port"); if (attr) dev_port = strtol(attr, NULL, 10); s = names->pci_onboard; l = sizeof(names->pci_onboard); l = strpcpyf(&s, l, "o%d", idx); if (dev_port > 0) l = strpcpyf(&s, l, "d%d", dev_port); if (l == 0) names->pci_onboard[0] = '\0'; names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label"); return 0; }
static int pretty_boot_time(sd_bus *bus, char **_buf) { char ts[FORMAT_TIMESPAN_MAX]; struct boot_times *t; static char buf[4096]; size_t size; char *ptr; int r; r = acquire_boot_times(bus, &t); if (r < 0) return r; ptr = buf; size = sizeof(buf); size = strpcpyf(&ptr, size, "Startup finished in "); if (t->firmware_time) size = strpcpyf(&ptr, size, "%s (firmware) + ", format_timespan(ts, sizeof(ts), t->firmware_time - t->loader_time, USEC_PER_MSEC)); if (t->loader_time) size = strpcpyf(&ptr, size, "%s (loader) + ", format_timespan(ts, sizeof(ts), t->loader_time, USEC_PER_MSEC)); if (t->kernel_time) size = strpcpyf(&ptr, size, "%s (kernel) + ", format_timespan(ts, sizeof(ts), t->kernel_done_time, USEC_PER_MSEC)); if (t->initrd_time > 0) size = strpcpyf(&ptr, size, "%s (initrd) + ", format_timespan(ts, sizeof(ts), t->userspace_time - t->initrd_time, USEC_PER_MSEC)); size = strpcpyf(&ptr, size, "%s (userspace) ", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC)); if (t->kernel_time > 0) strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->firmware_time + t->finish_time, USEC_PER_MSEC)); else strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC)); ptr = strdup(buf); if (!ptr) return log_oom(); *_buf = ptr; return 0; }
static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) { struct udev_device *atkbd; const char *cur; char codes[4096]; char *s; size_t l; unsigned i; int ret; assert(dev); assert(release); atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL); if (!atkbd) return -ENODEV; cur = udev_device_get_sysattr_value(atkbd, "force_release"); if (!cur) return -ENODEV; s = codes; l = sizeof(codes); /* copy current content */ l = strpcpy(&s, l, cur); /* append new codes */ for (i = 0; i < release_count; i++) l = strpcpyf(&s, l, ",%u", release[i]); log_debug("keyboard: updating force-release list with '%s'", codes); ret = udev_device_set_sysattr_value(atkbd, "force_release", codes); if (ret < 0) log_error_errno(ret, "Error writing force-release attribute: %m"); return ret; }
static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { struct udev *udev = udev_device_get_udev(names->pcidev); unsigned domain, bus, slot, func, dev_port = 0; size_t l; char *s; const char *attr; struct udev_device *pci = NULL; char slots[256], str[256]; _cleanup_closedir_ DIR *dir = NULL; struct dirent *dent; int hotplug_slot = 0, err = 0; if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) return -ENOENT; /* kernel provided port index for multiple ports on a single PCI function */ attr = udev_device_get_sysattr_value(dev, "dev_port"); if (attr) dev_port = strtol(attr, NULL, 10); /* compose a name based on the raw kernel's PCI bus, slot numbers */ s = names->pci_path; l = sizeof(names->pci_path); if (domain > 0) l = strpcpyf(&s, l, "P%u", domain); l = strpcpyf(&s, l, "p%us%u", bus, slot); if (func > 0 || is_pci_multifunction(names->pcidev)) l = strpcpyf(&s, l, "f%u", func); if (dev_port > 0) l = strpcpyf(&s, l, "d%u", dev_port); if (l == 0) names->pci_path[0] = '\0'; /* ACPI _SUN — slot user number */ pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci"); if (!pci) { err = -ENOENT; goto out; } xsprintf(slots, "%s/slots", udev_device_get_syspath(pci)); dir = opendir(slots); if (!dir) { err = -errno; goto out; } for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { int i; char *rest; char *address; if (dent->d_name[0] == '.') continue; i = strtol(dent->d_name, &rest, 10); if (rest[0] != '\0') continue; if (i < 1) continue; xsprintf(str, "%s/%s/address", slots, dent->d_name); if (read_one_line_file(str, &address) >= 0) { /* match slot address with device by stripping the function */ if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address))) hotplug_slot = i; free(address); } if (hotplug_slot > 0) break; } if (hotplug_slot > 0) { s = names->pci_slot; l = sizeof(names->pci_slot); if (domain > 0) l = strpcpyf(&s, l, "P%d", domain); l = strpcpyf(&s, l, "s%d", hotplug_slot); if (func > 0 || is_pci_multifunction(names->pcidev)) l = strpcpyf(&s, l, "f%d", func); if (dev_port > 0) l = strpcpyf(&s, l, "d%d", dev_port); if (l == 0) names->pci_slot[0] = '\0'; } out: udev_device_unref(pci); return err; }