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);
+
+ snprintf(device, sizeof(device), "/sys/dev/block/%d:%d", major(dev),
+ minor(dev));
+
+ /* 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);
- sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev));
+ device_free_len -= strlen(device);
+ for (i = 0; i < dev_level; i++) {
+ if (device_free_len < dev_str_len)
+ return NULL;
- rp = realpath(device, NULL);
- if (!rp)
- return NULL;
+ strncat(device, dev_str, device_free_len);
- buf = get_nvme_multipath_dev_hw_path(rp);
- if (buf) {
- free(rp);
- return buf;
+ /* 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
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)
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)
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)
*/
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)
}
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);
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);
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;
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)) {
continue;
}
- device_path = diskfd_to_devpath(fd);
+ device_path = diskfd_to_devpath(fd, 1, NULL);
if (!device_path) {
close(fd);
continue;
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)
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);
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"
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)) {
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)) {
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) {
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);