From 87cf9f5aacf65d0bc186e5e525026cc760290379 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 25 May 2007 14:48:08 +0200 Subject: [PATCH] cciss device support --- etc/udev/rules.d/60-persistent-storage.rules | 9 +- extras/path_id/path_id | 11 ++ extras/scsi_id/scsi_id.c | 116 +++++++++++++------ extras/scsi_id/scsi_id.h | 2 + extras/scsi_id/scsi_serial.c | 31 +++++ 5 files changed, 127 insertions(+), 42 deletions(-) diff --git a/etc/udev/rules.d/60-persistent-storage.rules b/etc/udev/rules.d/60-persistent-storage.rules index 04c7e774..8de3e634 100644 --- a/etc/udev/rules.d/60-persistent-storage.rules +++ b/etc/udev/rules.d/60-persistent-storage.rules @@ -36,8 +36,9 @@ KERNEL=="sd*[!0-9]|sr*|st*", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{iee KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="usb_id -x" KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="scsi_id -g -x -s %p -d $tempnode" KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="scsi_id -g -x -a -s %p -d $tempnode" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" -KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" +KERNEL=="cciss?c[0-9]d[0-9]", ENV{ID_SERIAL}=="", IMPORT{program}="scsi_id -n -g -x -s %p -d $tempnode" +KERNEL=="sd*[!0-9]|sr*|cciss?c[0-9]d[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[0-9]|cciss*p[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" # libata compat (links like hd*) KERNEL=="sd*[!0-9]|sr*", ENV{ID_VENDOR}=="ATA", PROGRAM="ata_id $tempnode", ENV{ID_ATA_COMPAT}="$result" @@ -48,10 +49,10 @@ KERNEL=="mmcblk[0-9]", ATTR{name}=="?*", ATTR{serial}=="?*", ENV{ID_NAME}="$attr KERNEL=="mmcblk[0-9]p[0-9]", ATTR{name}=="?*", ATTR{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n" # by-path (shortest physical path) -KERNEL=="*[!0-9]|sr*", IMPORT{program}="path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[!0-9]|sr*|cciss?c[0-9]d[0-9]", IMPORT{program}="path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[0-9]|cciss*p[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" KERNEL=="st*", IMPORT{program}="path_id %p", SYMLINK+="tape/by-path/$env{ID_PATH}" KERNEL=="sr*|st*", GOTO="persistent_storage_end" -KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" # by-label/by-uuid (filesystem properties) KERNEL=="*[!0-9]", ATTR{removable}=="1", GOTO="persistent_storage_end" diff --git a/extras/path_id/path_id b/extras/path_id/path_id index a7d650bf..ee26dc1f 100644 --- a/extras/path_id/path_id +++ b/extras/path_id/path_id @@ -74,6 +74,17 @@ handle_pci () { DEV=${PWD} pci_id=${DEV##*/} host_dev_path=$DEV + + # cciss devices don't have a separate sysfs node + for blk_link in block*; do + if [ -L "$blk_link" ]; then + case "$blk_link" in + *cciss*) + d=cciss-${blk_link#*cciss\!} + ;; + esac + fi + done while [ ! -z "$host_dev_path" ] ; do case "$host_dev_path" in */pci[0-9]*) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index c00145f3..79a8d7e5 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -34,7 +34,7 @@ #define TMP_DIR "/dev" #define TMP_PREFIX "tmp-scsi" -static const char short_options[] = "abd:f:gip:s:uvVx"; +static const char short_options[] = "abd:f:ginp:s:uvVx"; static const char dev_short_options[] = "bgp:"; static int all_good; @@ -48,6 +48,7 @@ static int use_stderr; static int debug; static int hotplug_mode; static int reformat_serial; +static int ignore_sysfs; static int export; static char vendor_str[64]; static char model_str[64]; @@ -459,6 +460,10 @@ static int set_options(int argc, char **argv, const char *short_opts, } break; + case 'n': + ignore_sysfs = 1; + break; + case 's': sys_specified = 1; strncpy(target, optarg, MAX_PATH_LEN); @@ -495,41 +500,12 @@ static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *pa int retval; int newargc; char **newargv = NULL; - const char *vendor, *model, *type; int option; *good_bad = all_good; *page_code = default_page_code; - vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); - if (!vendor) { - info("%s: cannot get vendor attribute", dev_scsi->devpath); - return -1; - } - set_str(vendor_str, vendor, sizeof(vendor_str)-1); - - model = sysfs_attr_get_value(dev_scsi->devpath, "model"); - if (!model) { - info("%s: cannot get model attribute\n", dev_scsi->devpath); - return -1; - } - set_str(model_str, model, sizeof(model_str)-1); - - type = sysfs_attr_get_value(dev_scsi->devpath, "type"); - if (!type) { - info("%s: cannot get type attribute", dev_scsi->devpath); - return -1; - } - set_type(type_str, type, sizeof(type_str)); - - type = sysfs_attr_get_value(dev_scsi->devpath, "rev"); - if (!type) { - info("%s: cannot get type attribute\n", dev_scsi->devpath); - return -1; - } - set_str(revision_str, type, sizeof(revision_str)-1); - - retval = get_file_options(vendor, model, &newargc, &newargv); + retval = get_file_options(vendor_str, model_str, &newargc, &newargv); optind = 1; /* reset this global extern */ while (retval == 0) { @@ -578,6 +554,58 @@ static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *pa return retval; } +static int set_sysfs_values(struct sysfs_device *dev_scsi) +{ + const char *vendor, *model, *type; + + vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); + if (!vendor) { + info("%s: cannot get vendor attribute", dev_scsi->devpath); + return -1; + } + set_str(vendor_str, vendor, sizeof(vendor_str)-1); + + model = sysfs_attr_get_value(dev_scsi->devpath, "model"); + if (!model) { + info("%s: cannot get model attribute\n", dev_scsi->devpath); + return -1; + } + set_str(model_str, model, sizeof(model_str)-1); + + type = sysfs_attr_get_value(dev_scsi->devpath, "type"); + if (!type) { + info("%s: cannot get type attribute", dev_scsi->devpath); + return -1; + } + set_type(type_str, type, sizeof(type_str)); + + type = sysfs_attr_get_value(dev_scsi->devpath, "rev"); + if (!type) { + info("%s: cannot get type attribute\n", dev_scsi->devpath); + return -1; + } + set_str(revision_str, type, sizeof(revision_str)-1); + + return 0; +} + +static int set_inq_values(struct sysfs_device *dev_scsi, const char *path) +{ + int retval; + char vendor[8], model[16], type[4], rev[4]; + + retval = scsi_std_inquiry(dev_scsi, path, vendor, model, rev, type); + if (retval) + return retval; + + set_str(vendor_str, vendor, 8); + set_str(model_str, model, 16); + set_type(type_str, type, sizeof(type_str) - 1); + set_str(revision_str, rev, sizeof(revision_str) -1); + + return 0; +} + /* * format_serial: replace to whitespaces by underscores for calling * programs that use the serial for device naming (multipath, Suse @@ -615,11 +643,12 @@ static int scsi_id(const char *devpath, char *maj_min_dev) int retval; int dev_type = 0; struct sysfs_device *dev; - struct sysfs_device *dev_scsi; + struct sysfs_device *dev_scsi = NULL; int good_dev; int page_code; char serial[MAX_SERIAL_LEN]; char serial_short[MAX_SERIAL_LEN]; + char bus_str[8]; dbg("devpath %s\n", devpath); @@ -634,11 +663,13 @@ static int scsi_id(const char *devpath, char *maj_min_dev) else dev_type = S_IFCHR; - /* get scsi parent device */ - dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi"); - if (dev_scsi == NULL) { - err("unable to access parent device of '%s'", devpath); - return 1; + if (!ignore_sysfs) { + /* get scsi parent device */ + dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi"); + if (dev_scsi == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } } /* mknod a temp dev to communicate with the device */ @@ -647,6 +678,15 @@ static int scsi_id(const char *devpath, char *maj_min_dev) return 1; } + if (!ignore_sysfs) { + set_sysfs_values(dev_scsi); + strcpy(bus_str,"scsi"); + } else { + dev_scsi = dev; + set_inq_values(dev_scsi, maj_min_dev); + strcpy(bus_str,"cciss"); + } + /* get per device (vendor + model) options from the config file */ retval = per_dev_options(dev_scsi, &good_dev, &page_code); dbg("per dev options: good %d; page code 0x%x", good_dev, page_code); @@ -671,7 +711,7 @@ static int scsi_id(const char *devpath, char *maj_min_dev) set_str(serial_str, serial_short, sizeof(serial_str)); printf("ID_SERIAL_SHORT=%s\n", serial_str); printf("ID_TYPE=%s\n", type_str); - printf("ID_BUS=scsi\n"); + printf("ID_BUS=%s\n", bus_str); } else { if (reformat_serial) format_serial(serial); diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index d7f675fa..0e2b297d 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -30,6 +30,8 @@ */ #define MAX_BUFFER_LEN 256 +extern int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname, + char *vendor, char *model, char *rev, char *type); extern int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, int page_code, char *serial, char *serial_short, int len); diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index e1726bbd..c84f41e0 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -736,6 +736,37 @@ static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd, return 0; } +int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname, + char *vendor, char *model, char *rev, char *type) +{ + int retval; + int fd; + unsigned char buf[SCSI_INQ_BUFF_LEN]; + + dbg("opening %s\n", devname); + fd = open(devname, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + info("%s: cannot open %s: %s", + dev_scsi->kernel, devname, strerror(errno)); + return 1; + } + + memset(buf, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return retval; + + memcpy(vendor, buf + 8, 8); + memcpy(model, buf + 16, 16); + memcpy(rev, buf + 32, 4); + sprintf(type,"%x", buf[0] & 0x1f); + + if (close(fd) < 0) + info("%s: close failed: %s", dev_scsi->kernel, strerror(errno)); + + return 0; +} + int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, int page_code, char *serial, char *serial_short, int len) { -- 2.39.5