X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=extras%2Fscsi_id%2Fscsi_id.c;h=f45563d1b3b9ed328318ff8f909051e92d144188;hp=1cd6981e5e3700ea773d0e4de1daf291497e5b10;hb=fd3eeb7502d9ed52569bdb3e01a50ecbc132035e;hpb=b484e43622c04aaf4a2ca851bc7436b873530b1d diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 1cd6981e5..f45563d1b 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -44,15 +44,15 @@ /* * temporary names for mknod. */ -#define TMP_DIR "/tmp" -#define TMP_PREFIX "scsi" +#define TMP_DIR "/dev" +#define TMP_PREFIX "tmp-scsi" /* * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) * 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, ...) { @@ -111,7 +112,7 @@ int sysfs_get_attr(const char *devpath, const char *attr, char *value, return sysfs_read_attribute_value(attr_path, value, SYSFS_NAME_LEN); } -static int get_major_minor(const char *devpath, int *major, int *minor) +static int get_major_minor(const char *devpath, int *maj, int *min) { char dev_value[MAX_ATTR_LEN]; @@ -129,7 +130,7 @@ static int get_major_minor(const char *devpath, int *major, int *minor) } dprintf("dev value %s", dev_value); /* dev_value has a trailing \n */ - if (sscanf(dev_value, "%u:%u", major, minor) != 2) { + if (sscanf(dev_value, "%u:%u", maj, min) != 2) { log_message(LOG_WARNING, "%s: invalid dev major/minor\n", devpath); return -1; @@ -140,18 +141,18 @@ static int get_major_minor(const char *devpath, int *major, int *minor) static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) { - int major, minor; + int maj, min; dprintf("(%s)\n", devpath); - if (get_major_minor(devpath, &major, &minor)) + if (get_major_minor(devpath, &maj, &min)) return -1; snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u", - TMP_DIR, TMP_PREFIX, major, minor, getpid()); + TMP_DIR, TMP_PREFIX, maj, min, getpid()); dprintf("tmpdev '%s'\n", tmpdev); - if (mknod(tmpdev, 0600 | dev_type, makedev(major, minor))) { + if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) { log_message(LOG_WARNING, "mknod failed: %s\n", strerror(errno)); return -1; } @@ -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,13 @@ 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*) (((unsigned long) 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 +732,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); @@ -759,10 +790,6 @@ int main(int argc, char **argv) strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); strncat(target_path, devpath, MAX_NAME_LEN); - } else { - if (set_options(argc, argv, short_options, target_path, - maj_min_dev) < 0) - exit(1); } /* @@ -779,6 +806,11 @@ int main(int argc, char **argv) exit(1); free(newargv); } + if (!hotplug_mode) { + if (set_options(argc, argv, short_options, target_path, + maj_min_dev) < 0) + exit(1); + } if (!sys_specified) { log_message(LOG_WARNING, "-s must be specified\n");