From 01f950e2eb86563255a269ecadd386cbe5361d0c Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Tue, 5 Oct 2004 21:30:54 -0700 Subject: [PATCH] [PATCH] update udev to include scsi_id 0.6 Here's a patch updating udev's copy of scsi_id to version 0.6. --- extras/scsi_id/ChangeLog | 23 ++++++++++++++++++++++ extras/scsi_id/Makefile | 2 +- extras/scsi_id/TODO | 3 --- extras/scsi_id/release-notes | 36 ++++++++++------------------------- extras/scsi_id/scsi.h | 7 +++++++ extras/scsi_id/scsi_id.8 | 3 +++ extras/scsi_id/scsi_id.c | 34 +++++++++++++++++++++++++++++++-- extras/scsi_id/scsi_id.h | 1 - extras/scsi_id/scsi_serial.c | 37 +++++++++++++++++------------------- 9 files changed, 93 insertions(+), 53 deletions(-) diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog index bfa35343..724977db 100644 --- a/extras/scsi_id/ChangeLog +++ b/extras/scsi_id/ChangeLog @@ -1,3 +1,26 @@ +2004-jul-30: + * scsi_id.c, scsi_serial.c: Align the buffer passed to scsi_serial, + don't bother aligning and memcpy-ing the result in scsi_inquiry. + Aligning to 512 probably does not help, since the IO length of + 254 is not a multiple of 512. + +2004-jul-30: + * scsi.h, scsi_serial.c: Use a define for the SCSI INQUIRY buffer + length. + +2004-jul-30: + * scsi_id.c: Patch from add a -u flag + to substitute white space with underscores so it is easier to use + the output as a device name. + +2004-jul-30: + * scsi_serial.c: Patch from Hannes Reinecke use 254 + bytes for SCSI INQUIRY commands. + +2004-jul-28: + * scsi_id.h, scsi_serial.c: get rid of dumb/dead code, and use a + 512 byte aligned buffer. + 2004-jun-23: * scsi_id.h: increase MAX_SERIAL_LEN from 128 to 256, as some devices (maybe broken ones) are giving really long id's. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 8fe29f36..7ccc4c51 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.5 +SCSI_ID_VERSION=0.6 prefix = etcdir = ${prefix}/etc diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO index e0283cf4..857c22b8 100644 --- a/extras/scsi_id/TODO +++ b/extras/scsi_id/TODO @@ -1,6 +1,3 @@ -- Add an option to replace blanks with spaces, so the generated id can be - more easily used as a /dev name. - - Add a bus white/black list option. So for example, all scsi devices under USB could easily be blacklisted. This should allow multiple busses to be listed. diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes index 29967131..302817ea 100644 --- a/extras/scsi_id/release-notes +++ b/extras/scsi_id/release-notes @@ -1,6 +1,6 @@ -Version 0.5 of scsi_id is available at: +Version 0.6 of scsi_id is available at: -http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.5.tar.gz +http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.6.tar.gz scsi_id is a program to generate a unique identifier for a given SCSI device. @@ -9,34 +9,18 @@ It is primarily for use with the udev program key, or hotplug scripts that want persistent naming of scsi devices. It could also be used for automatic multi-path configuration or device mapper configuration. -Version 0.5 requires: +Requires: - Linux kernel 2.6 - libsysfs 0.4.0 Major changes since the last release: + + - add -u option, patch from Christoph Varoqui, to substitute white + space with underscores so it is easier to use the output as a + device name. - - Ken Brush have the command line options - override generic options. + - Use 254 bytes for SCSI INQUIRY commands, patch from Hannes + Reinecke. - - Fix the gen_scsi_id_udev_rules.sh to handle spaces in the id. - - - Don't supply a makedev() when built with klibc. Also, the - scsi_id supplied makedev() was using the old major/minor method. - - - Include compiler.h so we can build against klibc, as recent sg.h - changes need a define for __user. - -Other changes: - - - Increase the MAX_SERIAL_LEN from 128 to 256, as some (possibly - broken devics) are returning very long id's - - - Add spotless target (via Olaf Hering's udev patch) - - - minor wording changes in scsi_id.config - - - Log INQUIRY failure, including the failing page code and vpd - values - - - Escape '-' with '\-' in the man page. +See ChangeLog for more details. diff --git a/extras/scsi_id/scsi.h b/extras/scsi_id/scsi.h index 780e0015..212765a1 100644 --- a/extras/scsi_id/scsi.h +++ b/extras/scsi_id/scsi.h @@ -37,6 +37,13 @@ struct scsi_ioctl_command { #define SENSE_BUFF_LEN 32 +/* + * The request buffer size passed to the SCSI INQUIRY commands, use 254, + * as this is a nice value for some devices, especially some of the usb + * mass storage devices. + */ +#define SCSI_INQ_BUFF_LEN 254 + /* * SCSI INQUIRY vendor and model (really product) lengths. */ diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index 69dd2a99..591bb793 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -95,6 +95,9 @@ Generate an id for the The sysfs mount point must not be included. For example, use /block/sd, not /sys/block/sd. .TP +.BI \-u +Reformat the output : replace all whitespaces by underscores +.TP .BI \-v Generate verbose debugging output. .TP diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index e8939878..6395b822 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -52,7 +52,7 @@ * options are not supported, but other code is still left in place for * now. */ -static const char short_options[] = "bd:f:gip:s:vV"; +static const char short_options[] = "bd:f:gip:s:uvV"; /* * Just duplicate per dev options. */ @@ -70,6 +70,7 @@ static int default_page_code; static int use_stderr; static int debug; static int hotplug_mode; +static int reformat_serial; void log_message (int level, const char *format, ...) { @@ -469,6 +470,10 @@ static int set_options(int argc, char **argv, const char *short_opts, strncat(target, optarg, MAX_NAME_LEN); break; + case 'u': + reformat_serial = 1; + break; + case 'v': debug++; break; @@ -572,6 +577,23 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, return retval; } +/* + * format_serial: replace to whitespaces by underscores for calling + * programs that use the serial for device naming (multipath, Suse + * naming, etc...) + */ +static void format_serial(char *serial) +{ + char *p = serial; + + while (*p != '\0') { + if (isspace(*p)) + *p = '_'; + p++; + } + return; +} + /* * scsi_id: try to get an id, if one is found, printf it to stdout. * returns a value passed to exit() - 0 if printed an id, else 1. This @@ -583,7 +605,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) { int retval; int dev_type = 0; - char serial[MAX_SERIAL_LEN]; + char *serial, *unaligned_buf; struct sysfs_class_device *class_dev; /* of target_path */ struct sysfs_class_device *class_dev_parent; /* for partitions */ struct sysfs_device *scsi_dev; /* the scsi_device */ @@ -689,6 +711,12 @@ static int scsi_id(const char *target_path, char *maj_min_dev) dprintf("per dev options: good %d; page code 0x%x; callout '%s'\n", good_dev, page_code, callout); +#define ALIGN 512 + unaligned_buf = malloc(MAX_SERIAL_LEN + ALIGN); + serial = (char*) (((int) unaligned_buf + (ALIGN - 1)) & ~(ALIGN - 1)); + dprintf("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial); +#undef ALIGN + if (!good_dev) { retval = 1; } else if (callout[0] != '\0') { @@ -703,6 +731,8 @@ static int scsi_id(const char *target_path, char *maj_min_dev) retval = 0; } if (!retval) { + if (reformat_serial) + format_serial(serial); if (display_bus_id) printf("%s: ", scsi_dev->name); printf("%s", serial); diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 10599ebb..0ca7cd42 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -25,7 +25,6 @@ log_message(LOG_DEBUG, "%s: " format, __FUNCTION__ , ## arg) #define MAX_NAME_LEN 72 -#define OFFSET (2 * sizeof(unsigned int)) /* * MAX_ATTR_LEN: maximum length of the result of reading a sysfs diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index e0074b66..0db75640 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -300,17 +300,12 @@ static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned unsigned char sense[SENSE_BUFF_LEN]; struct sg_io_hdr io_hdr; int retval; - unsigned char *inq; - unsigned char *buffer; int retry = 3; /* rather random */ - if (buflen > 255) { + if (buflen > SCSI_INQ_BUFF_LEN) { log_message(LOG_WARNING, "buflen %d too long\n", buflen); return -1; } - inq = malloc(OFFSET + sizeof (inq_cmd) + 512); - memset(inq, 0, OFFSET + sizeof (inq_cmd) + 512); - buffer = inq + OFFSET; resend: dprintf("%s evpd %d, page 0x%x\n", scsi_dev->name, evpd, page); @@ -321,7 +316,7 @@ resend: io_hdr.mx_sb_len = sizeof(sense); io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; io_hdr.dxfer_len = buflen; - io_hdr.dxferp = buffer; + io_hdr.dxferp = buf; io_hdr.cmdp = inq_cmd; io_hdr.sbp = sense; io_hdr.timeout = DEF_TIMEOUT; @@ -329,7 +324,8 @@ resend: if (ioctl(fd, SG_IO, &io_hdr) < 0) { log_message(LOG_WARNING, "%s: ioctl failed: %s\n", scsi_dev->name, strerror(errno)); - return -1; + retval = -1; + goto error; } retval = sg_err_category3(&io_hdr); @@ -346,7 +342,6 @@ resend: if (!retval) { retval = buflen; - memcpy(buf, buffer, retval); } else if (retval > 0) { if (--retry > 0) { dprintf("%s: Retrying ...\n", scsi_dev->name); @@ -355,15 +350,16 @@ resend: retval = -1; } +error: if (retval < 0) log_message(LOG_WARNING, "%s: Unable to get INQUIRY vpd %d page 0x%x.\n", scsi_dev->name, evpd, page); - free(inq); return retval; } +/* Get list of supported EVPD pages */ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, char *buffer, int len) { @@ -552,15 +548,17 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev, char return 0; } +/* Get device identification VPD page */ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int len) { int retval; int id_ind, j; - unsigned char page_83[256]; + unsigned char page_83[SCSI_INQ_BUFF_LEN]; - memset(page_83, 0, 256); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x83, page_83, 255); + memset(page_83, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x83, page_83, + SCSI_INQ_BUFF_LEN); if (retval < 0) return 1; @@ -609,6 +607,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, return 1; } +/* Get unit serial number VPD page */ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int max_len) { @@ -616,10 +615,10 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, int ser_ind; int i; int len; - unsigned char buf[256]; + unsigned char buf[SCSI_INQ_BUFF_LEN]; - memset(buf, 0, 256); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x80, buf, 255); + memset(buf, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x80, buf, SCSI_INQ_BUFF_LEN); if (retval < 0) return retval; @@ -652,13 +651,11 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, int page_code, char *serial, int len) { - unsigned char page0[256]; + unsigned char page0[SCSI_INQ_BUFF_LEN]; int fd; int ind; int retval; - if (len > 255) { - } memset(serial, 0, len); dprintf("opening %s\n", devname); fd = open(devname, O_RDONLY | O_NONBLOCK); @@ -694,7 +691,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, * Get page 0, the page of the pages. By default, try from best to * worst of supported pages: 0x83 then 0x80. */ - if (do_scsi_page0_inquiry(scsi_dev, fd, page0, 255)) { + if (do_scsi_page0_inquiry(scsi_dev, fd, page0, SCSI_INQ_BUFF_LEN)) { /* * Don't try anything else. Black list if a specific page * should be used for this vendor+model, or maybe have an -- 2.39.5