diff --git a/platform-intel.c b/platform-intel.c index 2da152f..2ed63ed 100644 --- a/platform-intel.c +++ b/platform-intel.c @@ -712,28 +712,61 @@ char *get_nvme_multipath_dev_hw_path(const char *dev_path) return rp; } -char *devt_to_devpath(dev_t dev) +/* Description: Return part or whole realpath for the dev + * Parameters: + * dev - the device to be quered + * dev_level - level of "/device" entries. It allows to caller to access + * virtual or physical devices which are on "path" to quered + * one. + * buf - optional, must be PATH_MAX size. If set, then will be used. + */ +char *devt_to_devpath(dev_t dev, int dev_level, char *buf) { - char device[46]; - char *rp; - char *buf; + char device[PATH_MAX]; + char *hw_path; + int i; + unsigned long device_free_len = sizeof(device) - 1; + char dev_str[] = "/device"; + unsigned long dev_str_len = strlen(dev_str); - sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev)); + snprintf(device, sizeof(device), "/sys/dev/block/%d:%d", major(dev), + minor(dev)); - rp = realpath(device, NULL); - if (!rp) - return NULL; + /* If caller wants block device, return path to it even if it is exposed + * via virtual layer. + */ + if (dev_level == 0) + return realpath(device, buf); - buf = get_nvme_multipath_dev_hw_path(rp); - if (buf) { - free(rp); - return buf; + device_free_len -= strlen(device); + for (i = 0; i < dev_level; i++) { + if (device_free_len < dev_str_len) + return NULL; + + strncat(device, dev_str, device_free_len); + + /* Resolve nvme-subsystem abstraction if needed + */ + device_free_len -= dev_str_len; + if (i == 0) { + char rp[PATH_MAX]; + + if (!realpath(device, rp)) + return NULL; + hw_path = get_nvme_multipath_dev_hw_path(rp); + if (hw_path) { + strcpy(device, hw_path); + device_free_len = sizeof(device) - + strlen(device) - 1; + free(hw_path); + } + } } - return rp; + return realpath(device, buf); } -char *diskfd_to_devpath(int fd) +char *diskfd_to_devpath(int fd, int dev_level, char *buf) { /* return the device path for a disk, return NULL on error or fd * refers to a partition @@ -745,7 +778,7 @@ char *diskfd_to_devpath(int fd) if (!S_ISBLK(st.st_mode)) return NULL; - return devt_to_devpath(st.st_rdev); + return devt_to_devpath(st.st_rdev, dev_level, buf); } int path_attached_to_hba(const char *disk_path, const char *hba_path) @@ -770,7 +803,7 @@ int path_attached_to_hba(const char *disk_path, const char *hba_path) int devt_attached_to_hba(dev_t dev, const char *hba_path) { - char *disk_path = devt_to_devpath(dev); + char *disk_path = devt_to_devpath(dev, 1, NULL); int rc = path_attached_to_hba(disk_path, hba_path); if (disk_path) @@ -781,7 +814,7 @@ int devt_attached_to_hba(dev_t dev, const char *hba_path) int disk_attached_to_hba(int fd, const char *hba_path) { - char *disk_path = diskfd_to_devpath(fd); + char *disk_path = diskfd_to_devpath(fd, 1, NULL); int rc = path_attached_to_hba(disk_path, hba_path); if (disk_path) @@ -862,15 +895,9 @@ int imsm_is_nvme_supported(int disk_fd, int verbose) */ int is_multipath_nvme(int disk_fd) { - char path_buf[PATH_MAX]; char ns_path[PATH_MAX]; - char *kname = fd2kname(disk_fd); - if (!kname) - return 0; - sprintf(path_buf, "/sys/block/%s", kname); - - if (!realpath(path_buf, ns_path)) + if (!diskfd_to_devpath(disk_fd, 0, ns_path)) return 0; if (strncmp(ns_path, NVME_SUBSYS_PATH, strlen(NVME_SUBSYS_PATH)) == 0) diff --git a/platform-intel.h b/platform-intel.h index 8396a0f..f93add5 100644 --- a/platform-intel.h +++ b/platform-intel.h @@ -237,7 +237,7 @@ static inline char *guid_str(char *buf, struct efi_guid guid) } char *get_nvme_multipath_dev_hw_path(const char *dev_path); -char *diskfd_to_devpath(int fd); +char *diskfd_to_devpath(int fd, int dev_level, char *buf); __u16 devpath_to_vendor(const char *dev_path); struct sys_dev *find_driver_devices(const char *bus, const char *driver); struct sys_dev *find_intel_devices(void); @@ -245,7 +245,7 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba); const struct imsm_orom *find_imsm_orom(void); int disk_attached_to_hba(int fd, const char *hba_path); int devt_attached_to_hba(dev_t dev, const char *hba_path); -char *devt_to_devpath(dev_t dev); +char *devt_to_devpath(dev_t dev, int dev_level, char *buf); int path_attached_to_hba(const char *disk_path, const char *hba_path); const char *get_sys_dev_type(enum sys_dev_type); const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id); diff --git a/super-intel.c b/super-intel.c index 5469912..cff8550 100644 --- a/super-intel.c +++ b/super-intel.c @@ -694,7 +694,7 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname) if (fd < 0) disk_path = (char *) devname; else - disk_path = diskfd_to_devpath(fd); + disk_path = diskfd_to_devpath(fd, 1, NULL); if (!disk_path) return 0; @@ -2253,7 +2253,7 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b if (sscanf(ent->d_name, "%d:%d", &major, &minor) != 2) continue; - path = devt_to_devpath(makedev(major, minor)); + path = devt_to_devpath(makedev(major, minor), 1, NULL); if (!path) continue; if (!path_attached_to_hba(path, hba_path)) { @@ -2407,7 +2407,7 @@ static int print_nvme_info(struct sys_dev *hba) continue; } - device_path = diskfd_to_devpath(fd); + device_path = diskfd_to_devpath(fd, 1, NULL); if (!device_path) { close(fd); continue; @@ -4015,28 +4015,13 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst, static void fd2devname(int fd, char *name) { - struct stat st; - char path[256]; - char dname[PATH_MAX]; char *nm; - int rv; - name[0] = '\0'; - if (fstat(fd, &st) != 0) - return; - sprintf(path, "/sys/dev/block/%d:%d", - major(st.st_rdev), minor(st.st_rdev)); - - rv = readlink(path, dname, sizeof(dname)-1); - if (rv <= 0) + nm = fd2kname(fd); + if (!nm) return; - dname[rv] = '\0'; - nm = strrchr(dname, '/'); - if (nm) { - nm++; - snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm); - } + snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm); } static int nvme_get_serial(int fd, void *buf, size_t buf_len) @@ -5941,29 +5926,23 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, free(dd); abort(); } + if (super->hba && ((super->hba->type == SYS_DEV_NVME) || (super->hba->type == SYS_DEV_VMD))) { int i; - char *devpath = diskfd_to_devpath(fd); - char controller_path[PATH_MAX]; - char *controller_name; + char cntrl_path[PATH_MAX]; + char *cntrl_name; + char pci_dev_path[PATH_MAX]; - if (!devpath) { - pr_err("failed to get devpath, aborting\n"); + if (!diskfd_to_devpath(fd, 2, pci_dev_path) || + !diskfd_to_devpath(fd, 1, cntrl_path)) { + pr_err("failed to get dev_path, aborting\n"); if (dd->devname) free(dd->devname); free(dd); return 1; } - snprintf(controller_path, PATH_MAX-1, "%s/device", devpath); - - controller_name = basename(devpath); - if (is_multipath_nvme(fd)) - pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n", controller_name); - - free(devpath); - if (!imsm_is_nvme_supported(dd->fd, 1)) { if (dd->devname) free(dd->devname); @@ -5971,7 +5950,12 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, return 1; } - if (devpath_to_vendor(controller_path) == 0x8086) { + cntrl_name = basename(cntrl_path); + if (is_multipath_nvme(fd)) + pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n", + cntrl_name); + + if (devpath_to_vendor(pci_dev_path) == 0x8086) { /* * If Intel's NVMe drive has serial ended with * "-A","-B","-1" or "-2" it means that this is "x8" @@ -6985,7 +6969,7 @@ get_devices(const char *hba_path) char *path = NULL; if (sscanf(ent->d_name, "%d:%d", &major, &minor) != 2) continue; - path = devt_to_devpath(makedev(major, minor)); + path = devt_to_devpath(makedev(major, minor), 1, NULL); if (!path) continue; if (!path_attached_to_hba(path, hba_path)) { @@ -10648,7 +10632,7 @@ int validate_container_imsm(struct mdinfo *info) struct sys_dev *hba = NULL; struct sys_dev *intel_devices = find_intel_devices(); char *dev_path = devt_to_devpath(makedev(info->disk.major, - info->disk.minor)); + info->disk.minor), 1, NULL); for (idev = intel_devices; idev; idev = idev->next) { if (dev_path && strstr(dev_path, idev->path)) { @@ -10669,7 +10653,8 @@ int validate_container_imsm(struct mdinfo *info) struct mdinfo *dev; for (dev = info->next; dev; dev = dev->next) { - dev_path = devt_to_devpath(makedev(dev->disk.major, dev->disk.minor)); + dev_path = devt_to_devpath(makedev(dev->disk.major, + dev->disk.minor), 1, NULL); struct sys_dev *hba2 = NULL; for (idev = intel_devices; idev; idev = idev->next) { @@ -11181,7 +11166,7 @@ static const char *imsm_get_disk_controller_domain(const char *path) struct sys_dev* hba; char *path; - path = devt_to_devpath(st.st_rdev); + path = devt_to_devpath(st.st_rdev, 1, NULL); if (path == NULL) return "unknown"; hba = find_disk_attached_hba(-1, path);