[dm-devel] Re: [libmultipath] Add cciss support

Christophe Varoqui christophe.varoqui at free.fr
Mon Jul 30 22:09:27 UTC 2007


I commited this work as a starting point. Thank you Hannes.

I hope to get an insight of what cciss multipathing means when the HP
patchs start to flow ... multi-initiator SAS ? I'm interested :)

Regards,
cvaroqui

Le lundi 16 juillet 2007 à 13:17 +0200, Hannes Reinecke a écrit :
> 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
> pièce jointe document plein texte (multipath-tools-enable-cciss)
> tree df9be98603906572e64ce368beb37befe7e17fd8
> parent 384e85dfd13c58cfa9ef752aed1530b46116119d
> author Hannes Reinecke <hare at suse.de> 1184584249 +0200
> committer Hannes Reinecke <hare at suse.de> 1184584249 +0200
> 
> libmultipath: Add support for cciss devices
> 
> This patch enables multipath support for cciss devices.
> 
> Signed-off-by: Hannes Reinecke <hare at 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 {




More information about the dm-devel mailing list