[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
[dm-devel] [libmultipath] Add cciss support
- From: Hannes Reinecke <hare suse de>
- To: christophe varoqui <christophe varoqui free fr>
- Cc: Ahmad Sadeghpour <asadeghpour novell com>, device-mapper development <dm-devel redhat com>, Mike Miller <mike miller hp com>
- Subject: [dm-devel] [libmultipath] Add cciss support
- Date: Mon, 16 Jul 2007 13:17:29 +0200
Hi Christophe,
HP asked me to implement cciss support for multipathing.
Apparently their newer HBAs are multipathing capable.
However, I have no idea about the failover method they're
using; so I used multibus as a default.
Maybe someone from HP can comment on this.
There were several patches floating around which tried to
achieve the same but given that they're trying to access
/sys/block/cciss!cXdY/device (which doesn't exist for cciss)
I doubt they'll do anything sensible.
Please commit.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare suse de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
tree df9be98603906572e64ce368beb37befe7e17fd8
parent 384e85dfd13c58cfa9ef752aed1530b46116119d
author Hannes Reinecke <hare suse de> 1184584249 +0200
committer Hannes Reinecke <hare suse de> 1184584249 +0200
libmultipath: Add support for cciss devices
This patch enables multipath support for cciss devices.
Signed-off-by: Hannes Reinecke <hare suse de>
85dd54f10fb296c609b5537e802b491b167ca02f
libmultipath/blacklist.c | 8 +---
libmultipath/discovery.c | 101 ++++++++++++++++++++++++++++++++++++++++++---
libmultipath/hwtable.c | 16 +++++++
libmultipath/structs.h | 1 +
4 files changed, 112 insertions(+), 14 deletions(-)
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
index 82a6a58..92ddec6 100644
--- a/libmultipath/blacklist.c
+++ b/libmultipath/blacklist.c
@@ -114,12 +114,6 @@ setup_default_blist (struct config * conf)
return 1;
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
return 1;
-
- str = STRDUP("^cciss!c[0-9]d[0-9]*");
- if (!str)
- return 1;
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
- return 1;
vector_foreach_slot (conf->hwtable, hwe, i) {
if (hwe->bl_product) {
@@ -136,7 +130,7 @@ setup_default_blist (struct config * conf)
}
}
}
-
+
return 0;
}
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index e3d4cd5..6219973 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -70,9 +70,11 @@ path_discover (vector pathvec, struct config * conf, char * devname, int flag)
condlog(0, "path too small");
return 1;
}
-
- if (!filepresent(path))
+
+ if (strncmp(devname,"cciss",5) && !filepresent(path)) {
+ condlog(4, "path %s not present", path);
return 0;
+ }
pp = find_path_by_dev(pathvec, devname);
@@ -207,12 +209,18 @@ sysfs_get_fc_nodename (struct sysfs_device * dev, char * node,
static int
opennode (char * dev, int mode)
{
- char devpath[FILE_NAME_SIZE];
+ char devpath[FILE_NAME_SIZE], *ptr;
if (safe_sprintf(devpath, "%s/%s", conf->udev_dir, dev)) {
condlog(0, "devpath too small");
return -1;
}
+ /* Translate '!' into '/' */
+ ptr = devpath;
+ while ((ptr = strchr(ptr, '!'))) {
+ *ptr = '/';
+ ptr++;
+ }
return open(devpath, mode);
}
@@ -342,6 +350,27 @@ get_serial (char * str, int maxlen, int fd)
}
static int
+get_inq (char * vendor, char * product, char * rev, int fd)
+{
+ int len = 0;
+ char buff[MX_ALLOC_LEN + 1] = {0};
+
+ if (fd < 0)
+ return 1;
+
+ if (0 == do_inq(fd, 0, 0, 0, buff, MX_ALLOC_LEN, 0)) {
+ memcpy(vendor, buff + 8, 8);
+ vendor[8] = '\0';
+ memcpy(product, buff + 16, 16);
+ product[16] = '\0';
+ memcpy(rev, buff + 32, 4);
+ rev[4] = '\0';
+ return 0;
+ }
+ return 1;
+}
+
+static int
scsi_sysfs_pathinfo (struct path * pp, struct sysfs_device * parent)
{
char attr_path[FILE_NAME_SIZE];
@@ -445,6 +474,31 @@ ccw_sysfs_pathinfo (struct path * pp, struct sysfs_device * parent)
}
static int
+cciss_sysfs_pathinfo (struct path * pp, struct sysfs_device * dev)
+{
+ char attr_path[FILE_NAME_SIZE];
+ char attr_buff[FILE_NAME_SIZE];
+
+ /*
+ * host / bus / target / lun
+ */
+ basename(dev->devpath, attr_path);
+ pp->sg_id.lun = 0;
+ pp->sg_id.channel = 0;
+ sscanf(attr_path, "cciss!c%id%i",
+ &pp->sg_id.host_no,
+ &pp->sg_id.scsi_id);
+ condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
+ pp->dev,
+ pp->sg_id.host_no,
+ pp->sg_id.channel,
+ pp->sg_id.scsi_id,
+ pp->sg_id.lun);
+
+ return 0;
+}
+
+static int
common_sysfs_pathinfo (struct path * pp, struct sysfs_device *dev)
{
char *attr;
@@ -486,18 +540,22 @@ sysfs_pathinfo(struct path * pp)
condlog(1, "%s: failed to get sysfs information", pp->dev);
return 1;
}
-
- parent = sysfs_device_get_parent(pp->sysdev);
if (common_sysfs_pathinfo(pp, pp->sysdev))
return 1;
+ parent = sysfs_device_get_parent(pp->sysdev);
+ if (!parent)
+ parent = pp->sysdev;
+
condlog(3, "%s: subsystem = %s", pp->dev, parent->subsystem);
if (!strncmp(parent->subsystem, "scsi",4))
pp->bus = SYSFS_BUS_SCSI;
if (!strncmp(parent->subsystem, "ccw",3))
pp->bus = SYSFS_BUS_CCW;
+ if (!strncmp(pp->dev,"cciss",5))
+ pp->bus = SYSFS_BUS_CCISS;
if (pp->bus == SYSFS_BUS_UNDEF)
return 0;
@@ -507,6 +565,9 @@ sysfs_pathinfo(struct path * pp)
} else if (pp->bus == SYSFS_BUS_CCW) {
if (ccw_sysfs_pathinfo(pp, parent))
return 1;
+ } else if (pp->bus == SYSFS_BUS_CCISS) {
+ if (cciss_sysfs_pathinfo(pp, pp->sysdev))
+ return 1;
}
return 0;
}
@@ -523,6 +584,25 @@ scsi_ioctl_pathinfo (struct path * pp, int mask)
}
static int
+cciss_ioctl_pathinfo (struct path * pp, int mask)
+{
+ if (mask & DI_SYSFS) {
+ get_inq(pp->vendor_id, pp->product_id, pp->rev, pp->fd);
+ condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
+ condlog(3, "%s: product = %s", pp->dev, pp->product_id);
+ condlog(3, "%s: revision = %s", pp->dev, pp->rev);
+ /*
+ * set the hwe configlet pointer
+ */
+ pp->hwe = find_hwe(conf->hwtable, pp->vendor_id,
+ pp->product_id, pp->rev);
+
+ }
+
+ return 0;
+}
+
+static int
get_state (struct path * pp)
{
struct checker * c = &pp->checker;
@@ -610,16 +690,23 @@ pathinfo (struct path *pp, vector hwtable, int mask)
if (pp->fd < 0)
pp->fd = opennode(pp->dev, O_RDONLY);
- if (pp->fd < 0)
+ if (pp->fd < 0) {
+ condlog(4, "Couldn't open node for %s: %s",
+ pp->dev, strerror(errno));
goto blank;
+ }
if (pp->bus == SYSFS_BUS_SCSI &&
scsi_ioctl_pathinfo(pp, mask))
goto blank;
+ if (pp->bus == SYSFS_BUS_CCISS &&
+ cciss_ioctl_pathinfo(pp, mask))
+ goto blank;
+
if (mask & DI_CHECKER && get_state(pp))
goto blank;
-
+
/*
* Retrieve path priority even for not PATH_UP paths if it has never
* been successfully obtained before.
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
index 356e184..fb1a808 100644
--- a/libmultipath/hwtable.c
+++ b/libmultipath/hwtable.c
@@ -153,6 +153,22 @@ static struct hwentry default_hw[] = {
.minio = DEFAULT_MINIO,
.checker_name = TUR,
},
+ {
+ /* HP Smart Array */
+ .vendor = "HP",
+ .product = "LOGICAL VOLUME.*",
+ .getuid = "/lib/udev/scsi_id -n -g -u -s /block/%n",
+ .getprio = NULL,
+ .features = DEFAULT_FEATURES,
+ .hwhandler = DEFAULT_HWHANDLER,
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = MULTIBUS,
+ .pgfailback = FAILBACK_UNDEF,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = NO_PATH_RETRY_UNDEF,
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ },
/*
* DDN controller family
*
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index 75322aa..f821f87 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -46,6 +46,7 @@ enum sysfs_buses {
SYSFS_BUS_SCSI,
SYSFS_BUS_IDE,
SYSFS_BUS_CCW,
+ SYSFS_BUS_CCISS,
};
enum pathstates {
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]