forked from pool/multipath-tools
104 lines
3.0 KiB
Plaintext
104 lines
3.0 KiB
Plaintext
From 734cf32be1f4bf3fa57bbdcc83147f92c4199b54 Mon Sep 17 00:00:00 2001
|
|
From: Hannes Reinecke <hare@suse.de>
|
|
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 <hare@suse.de>
|
|
---
|
|
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
|
|
|