From 734cf32be1f4bf3fa57bbdcc83147f92c4199b54 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 20 Nov 2008 09:00:39 +0100 Subject: [PATCH] Use /sys/dev for reverse lookup Newer kernels provide /sys/dev for reverse lookup of major:minor numbers. Also some error checking is in order here. Signed-off-by: Hannes Reinecke --- libmultipath/discovery.c | 35 ++++++++++++++++++++++++++++++----- 1 files changed, 30 insertions(+), 5 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 20d0684..56186bd 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -152,11 +152,11 @@ sysfs_get_dev (struct sysfs_device * dev, char * buff, size_t len) attr = sysfs_attr_get_value(dev->devpath, "dev"); if (!attr) { - condlog(3, "%s: no 'dev' attribute in sysfs", dev->kernel); + condlog(3, "%s: no 'dev' attribute in sysfs", dev->devpath); return 1; } if (strlcpy(buff, attr, len) != strlen(attr)) { - condlog(3, "%s: overflow in 'dev' attribute", dev->kernel); + condlog(3, "%s: overflow in 'dev' attribute", dev->devpath); return 2; } return 0; @@ -169,13 +169,18 @@ sysfs_get_size (struct sysfs_device * dev, unsigned long long * size) int r; attr = sysfs_attr_get_value(dev->devpath, "size"); - if (!attr) + if (!attr) { + condlog(3, "%s: No size attribute in sysfs", dev->devpath); return 1; + } r = sscanf(attr, "%llu\n", size); - if (r != 1) + if (r != 1) { + condlog(3, "%s: Cannot parse size attribute '%s'", + dev->devpath, attr); return 1; + } return 0; } @@ -232,12 +237,30 @@ devt2devname (char *devname, char *devt) char block_path[FILE_NAME_SIZE]; struct stat statbuf; - memset(block_path, 0, FILE_NAME_SIZE); if (sscanf(devt, "%u:%u", &major, &minor) != 2) { condlog(0, "Invalid device number %s", devt); return 1; } + sprintf(block_path,"/sys/dev/%u:%u", major, minor); + if (stat(block_path, &statbuf) == 0) { + /* Newer kernels have /sys/dev */ + if (S_ISLNK(statbuf.st_mode) && + readlink(block_path, dev, FILE_NAME_SIZE) > 0) { + char *p = strrchr(dev, '/'); + + if (!p) { + condlog(0, "No sysfs entry for %s\n", + block_path); + return 1; + } + p++; + strncpy(devname, p, FILE_NAME_SIZE); + return 0; + } + } + memset(block_path, 0, FILE_NAME_SIZE); + if (!(fd = fopen("/proc/partitions", "r"))) { condlog(0, "Cannot open /proc/partitions"); return 1; @@ -271,6 +294,7 @@ devt2devname (char *devname, char *devt) condlog(0, "sysfs entry %s is not a directory\n", block_path); return 1; } + strncpy(devname, dev, FILE_NAME_SIZE); return 0; } @@ -291,6 +315,7 @@ do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff); inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff); memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + memset(sense_b, 0, SENSE_BUFF_LEN); io_hdr.interface_id = 'S'; io_hdr.cmd_len = sizeof (inqCmdBlk); io_hdr.mx_sb_len = sizeof (sense_b); -- 1.5.3.2