From: Hannes Reinecke Date: Wed, 14 May 2008 11:42:41 +0000 (+0200) Subject: scsi_id: remove all sysfs dependencies X-Git-Tag: 174~1709 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=753417db2ba6faafa3aa30f6b15678e1557e20b8;hp=838436fa328345ffb0b355e6921b6d75a9b2992f;p=elogind.git scsi_id: remove all sysfs dependencies --- diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 538108717..4f0233ed0 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -31,21 +31,14 @@ #include "scsi_id.h" #include "scsi_id_version.h" -/* temporary names for mknod */ -#define TMP_DIR "/dev" -#define TMP_PREFIX "tmp-scsi" - static const struct option options[] = { { "device", 1, NULL, 'd' }, { "config", 1, NULL, 'f' }, { "page", 1, NULL, 'p' }, - { "devpath", 1, NULL, 's' }, - { "fallback-to-sysfs", 0, NULL, 'a' }, { "blacklisted", 0, NULL, 'b' }, { "whitelisted", 0, NULL, 'g' }, { "prefix-bus-id", 0, NULL, 'i' }, { "replace-whitespace", 0, NULL, 'u' }, - { "ignore-sysfs", 0, NULL, 'n' }, { "verbose", 0, NULL, 'v' }, { "version", 0, NULL, 'V' }, { "export", 0, NULL, 'x' }, @@ -53,21 +46,17 @@ static const struct option options[] = { {} }; -static const char short_options[] = "abd:f:ghinp:s:uvVx"; +static const char short_options[] = "d:f:ghip:uvVx"; static const char dev_short_options[] = "bgp:"; static int all_good; -static int always_info; static int dev_specified; -static int sys_specified; static char config_file[MAX_PATH_LEN] = SCSI_ID_CONFIG_FILE; static int display_bus_id; static enum page_code default_page_code; 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]; @@ -169,35 +158,6 @@ static void set_type(char *to, const char *from, size_t len) to[len-1] = '\0'; } -static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) -{ - unsigned int maj, min; - const char *attr; - - dbg("%s\n", devpath); - attr = sysfs_attr_get_value(devpath, "dev"); - if (attr == NULL) { - dbg("%s: could not get dev attribute: %s\n", devpath, strerror(errno)); - return -1; - } - - dbg("dev value %s\n", attr); - if (sscanf(attr, "%u:%u", &maj, &min) != 2) { - err("%s: invalid dev major/minor\n", devpath); - return -1; - } - - snprintf(tmpdev, MAX_PATH_LEN, "%s/%s-maj%d-min%d-%u", - TMP_DIR, TMP_PREFIX, maj, min, getpid()); - - dbg("tmpdev '%s'\n", tmpdev); - if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) { - err("mknod failed: %s\n", strerror(errno)); - return -1; - } - return 0; -} - /* * get_value: * @@ -415,7 +375,7 @@ static int get_file_options(const char *vendor, const char *model, } static int set_options(int argc, char **argv, const char *short_opts, - char *target, char *maj_min_dev) + char *maj_min_dev) { int option; @@ -436,9 +396,6 @@ static int set_options(int argc, char **argv, const char *short_opts, dbg("option '%c'\n", option); switch (option) { - case 'a': - always_info = 1; - break; case 'b': all_good = 0; break; @@ -465,11 +422,8 @@ static int set_options(int argc, char **argv, const char *short_opts, case 'h': printf("Usage: scsi_id OPTIONS \n" " --device device node for SG_IO commands\n" - " --devpath sysfs devpath\n" " --config location of config file\n" " --page SCSI page (0x80, 0x83, pre-spc3-83)\n" - " --fallback-to-sysfs print sysfs values if inquiry fails\n" - " --ignore-sysfs ignore sysfs entries\n" " --blacklisted threat device as blacklisted\n" " --whitelisted threat device as whitelisted\n" " --prefix-bus-id prefix SCSI bus id\n" @@ -497,16 +451,6 @@ 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); - target[MAX_PATH_LEN-1] = '\0'; - break; - case 'u': reformat_serial = 1; break; @@ -528,10 +472,15 @@ static int set_options(int argc, char **argv, const char *short_opts, exit(1); } } + if (optind < argc && !dev_specified) { + dev_specified = 1; + strncpy(maj_min_dev, argv[optind], MAX_PATH_LEN); + maj_min_dev[MAX_PATH_LEN-1] = '\0'; + } return 0; } -static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *page_code) +static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) { int retval; int newargc; @@ -590,54 +539,18 @@ 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\n", 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\n", 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) +static int set_inq_values(struct scsi_id_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); + retval = scsi_std_inquiry(dev_scsi, path); 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); + set_str(vendor_str, dev_scsi->vendor, 8); + set_str(model_str, dev_scsi->model, 16); + set_type(type_str, dev_scsi->type, sizeof(type_str) - 1); + set_str(revision_str, dev_scsi->revision, sizeof(revision_str) -1); return 0; } @@ -674,60 +587,25 @@ static void format_serial(char *serial) * memory etc. return 2, and return 1 for expected cases (like broken * device found) that do not print an id. */ -static int scsi_id(const char *devpath, char *maj_min_dev) +static int scsi_id(char *maj_min_dev) { int retval; - int dev_type = 0; - struct sysfs_device *dev; - struct sysfs_device *dev_scsi = NULL; + struct scsi_id_device dev_scsi; int good_dev; int page_code; - char serial[MAX_SERIAL_LEN] = ""; char serial_short[MAX_SERIAL_LEN] = ""; - const char *bus_str = NULL; - - dbg("devpath %s\n", devpath); - dev = sysfs_device_get(devpath); - if (dev == NULL) { - err("unable to access '%s'\n", devpath); - return 1; - } - - if (strcmp(dev->subsystem, "block") == 0) - dev_type = S_IFBLK; - else - dev_type = S_IFCHR; - - /* mknod a temp dev to communicate with the device */ - if (!dev_specified && create_tmp_dev(dev->devpath, maj_min_dev, dev_type)) { - dbg("create_tmp_dev failed\n"); - 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'\n", devpath); - return 1; - } - set_sysfs_values(dev_scsi); - bus_str = "scsi"; - } else { - dev_scsi = dev; - set_inq_values(dev_scsi, maj_min_dev); - } + set_inq_values(&dev_scsi, maj_min_dev); /* get per device (vendor + model) options from the config file */ - retval = per_dev_options(dev_scsi, &good_dev, &page_code); + retval = per_dev_options(&dev_scsi, &good_dev, &page_code); dbg("per dev options: good %d; page code 0x%x\n", good_dev, page_code); if (!good_dev) { retval = 1; - } else if (scsi_get_serial(dev_scsi, maj_min_dev, page_code, - serial, serial_short, MAX_SERIAL_LEN)) { - retval = always_info?0:1; + } else if (scsi_get_serial(&dev_scsi, maj_min_dev, page_code, + serial_short, MAX_SERIAL_LEN)) { + retval = 1; } else { retval = 0; } @@ -738,59 +616,33 @@ static int scsi_id(const char *devpath, char *maj_min_dev) printf("ID_VENDOR=%s\n", vendor_str); printf("ID_MODEL=%s\n", model_str); printf("ID_REVISION=%s\n", revision_str); - set_str(serial_str, serial, sizeof(serial_str)); + set_str(serial_str, dev_scsi.serial, sizeof(serial_str)); printf("ID_SERIAL=%s\n", serial_str); set_str(serial_str, serial_short, sizeof(serial_str)); printf("ID_SERIAL_SHORT=%s\n", serial_str); printf("ID_TYPE=%s\n", type_str); - if (bus_str != NULL) - printf("ID_BUS=%s\n", bus_str); } else { if (reformat_serial) - format_serial(serial); - if (display_bus_id) - printf("%s: ", dev_scsi->kernel); - printf("%s\n", serial); + format_serial(dev_scsi.serial); + printf("%s\n", dev_scsi.serial); } - dbg("%s\n", serial); + dbg("%s\n", dev_scsi.serial); retval = 0; } - if (!dev_specified) - unlink(maj_min_dev); - return retval; } int main(int argc, char **argv) { int retval = 0; - char devpath[MAX_PATH_LEN]; char maj_min_dev[MAX_PATH_LEN]; int newargc; - const char *env; char **newargv; logging_init("scsi_id"); - sysfs_init(); dbg("argc is %d\n", argc); - /* sysfs path can be overridden for testing */ - env = getenv("SYSFS_PATH"); - if (env) { - strncpy(sysfs_path, env, sizeof(sysfs_path)); - sysfs_path[sizeof(sysfs_path)-1] = '\0'; - } else - strcpy(sysfs_path, "/sys"); - - env = getenv("DEVPATH"); - if (env) { - hotplug_mode = 1; - sys_specified = 1; - strncpy(devpath, env, MAX_PATH_LEN); - devpath[sizeof(devpath)-1] = '\0'; - } - /* * Get config file options. */ @@ -801,8 +653,7 @@ int main(int argc, char **argv) goto exit; } if (newargv && (retval == 0)) { - if (set_options(newargc, newargv, short_options, devpath, - maj_min_dev) < 0) { + if (set_options(newargc, newargv, short_options, maj_min_dev) < 0) { retval = 2; goto exit; } @@ -810,22 +661,20 @@ int main(int argc, char **argv) } /* - * Get command line options (overriding any config file or DEVPATH - * settings). + * Get command line options (overriding any config file settings). */ - if (set_options(argc, argv, short_options, devpath, maj_min_dev) < 0) + if (set_options(argc, argv, short_options, maj_min_dev) < 0) exit(1); - if (!sys_specified) { - info("--devpath= must be specified\n"); + if (!dev_specified) { + info("no device specified\n"); retval = 1; goto exit; } - retval = scsi_id(devpath, maj_min_dev); + retval = scsi_id(maj_min_dev); exit: - sysfs_cleanup(); logging_close(); return retval; } diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 0e2b297d2..3b3a000dd 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -30,13 +30,21 @@ */ #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); +struct scsi_id_device { + char vendor[9]; + char model[17]; + char revision[5]; + char type[33]; + char kernel[64]; + char serial[MAX_SERIAL_LEN]; +}; + +extern int scsi_std_inquiry(struct scsi_id_device *dev_scsi, const char *devname); +extern int scsi_get_serial (struct scsi_id_device *dev_scsi, const char *devname, + int page_code, char *serial_short, int len); /* - * Page code values. + * Page code values. */ enum page_code { PAGE_83_PRE_SPC3 = -0x83, @@ -44,3 +52,4 @@ enum page_code { PAGE_80 = 0x80, PAGE_83 = 0x83, }; + diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 28e82db3c..32bb0f423 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -148,7 +148,7 @@ static int sg_err_category3(struct sg_io_hdr *hp) hp->sbp, hp->sb_len_wr); } -static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) +static int scsi_dump_sense(struct scsi_id_device *dev_scsi, struct sg_io_hdr *io) { unsigned char *sense_buffer; int s; @@ -254,7 +254,7 @@ static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) return -1; } -static int scsi_dump(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) +static int scsi_dump(struct scsi_id_device *dev_scsi, struct sg_io_hdr *io) { if (!io->status && !io->host_status && !io->msg_status && !io->driver_status) { @@ -273,7 +273,7 @@ static int scsi_dump(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) return -1; } -static int scsi_inquiry(struct sysfs_device *dev_scsi, int fd, +static int scsi_inquiry(struct scsi_id_device *dev_scsi, int fd, unsigned char evpd, unsigned char page, unsigned char *buf, unsigned int buflen) { @@ -343,11 +343,10 @@ error: } /* Get list of supported EVPD pages */ -static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd, +static int do_scsi_page0_inquiry(struct scsi_id_device *dev_scsi, int fd, unsigned char *buffer, unsigned int len) { int retval; - const char *vendor; memset(buffer, 0, len); retval = scsi_inquiry(dev_scsi, fd, 1, 0x0, buffer, len); @@ -375,12 +374,7 @@ static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd, * If the vendor id appears in the page assume the page is * invalid. */ - vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); - if (!vendor) { - info("%s: cannot get model attribute\n", dev_scsi->kernel); - return 1; - } - if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) { + if (!strncmp((char *)&buffer[VENDOR_LENGTH], dev_scsi->vendor, VENDOR_LENGTH)) { info("%s: invalid page0 data\n", dev_scsi->kernel); return 1; } @@ -392,25 +386,14 @@ static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd, * The caller checks that serial is long enough to include the vendor + * model. */ -static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial) +static int prepend_vendor_model(struct scsi_id_device *dev_scsi, char *serial) { - const char *attr; int ind; - attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); - if (!attr) { - info("%s: cannot get vendor attribute\n", dev_scsi->kernel); - return 1; - } - strncpy(serial, attr, VENDOR_LENGTH); + strncpy(serial, dev_scsi->vendor, VENDOR_LENGTH); ind = strlen(serial) - 1; - attr = sysfs_attr_get_value(dev_scsi->devpath, "model"); - if (!attr) { - info("%s: cannot get model attribute\n", dev_scsi->kernel); - return 1; - } - strncat(serial, attr, MODEL_LENGTH); + strncat(serial, dev_scsi->model, MODEL_LENGTH); ind = strlen(serial) - 1; ind++; @@ -430,7 +413,7 @@ static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial) * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill * serial number. **/ -static int check_fill_0x83_id(struct sysfs_device *dev_scsi, +static int check_fill_0x83_id(struct scsi_id_device *dev_scsi, unsigned char *page_83, const struct scsi_id_search_values *id_search, char *serial, char *serial_short, int max_len) @@ -521,7 +504,7 @@ static int check_fill_0x83_id(struct sysfs_device *dev_scsi, } /* Extract the raw binary from VPD 0x83 pre-SPC devices */ -static int check_fill_0x83_prespc3(struct sysfs_device *dev_scsi, +static int check_fill_0x83_prespc3(struct scsi_id_device *dev_scsi, unsigned char *page_83, const struct scsi_id_search_values *id_search, char *serial, char *serial_short, int max_len) @@ -543,7 +526,7 @@ static int check_fill_0x83_prespc3(struct sysfs_device *dev_scsi, /* Get device identification VPD page */ -static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd, +static int do_scsi_page83_inquiry(struct scsi_id_device *dev_scsi, int fd, char *serial, char *serial_short, int len) { int retval; @@ -633,7 +616,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd, * Return the hard coded error code value 2 if the page 83 reply is not * conformant to the SCSI-2 format. */ -static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd, +static int do_scsi_page83_prespc3_inquiry(struct scsi_id_device *dev_scsi, int fd, char *serial, char *serial_short, int len) { int retval; @@ -695,7 +678,7 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd, } /* Get unit serial number VPD page */ -static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd, +static int do_scsi_page80_inquiry(struct scsi_id_device *dev_scsi, int fd, char *serial, char *serial_short, int max_len) { int retval; @@ -736,30 +719,38 @@ 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 scsi_std_inquiry(struct scsi_id_device *dev_scsi, const char *devname) { int retval; int fd; unsigned char buf[SCSI_INQ_BUFF_LEN]; + struct stat statbuf; dbg("opening %s\n", devname); fd = open(devname, O_RDONLY | O_NONBLOCK); if (fd < 0) { - info("%s: cannot open %s: %s\n", - dev_scsi->kernel, devname, strerror(errno)); + info("scsi_id: cannot open %s: %s\n", + devname, strerror(errno)); return 1; } + if (fstat(fd, &statbuf) < 0) { + info("scsi_id: cannot stat %s: %s\n", + devname, strerror(errno)); + return 2; + } + sprintf(dev_scsi->kernel,"%d:%d", major(statbuf.st_rdev), + minor(statbuf.st_rdev)); + 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); + memcpy(dev_scsi->vendor, buf + 8, 8); + memcpy(dev_scsi->model, buf + 16, 16); + memcpy(dev_scsi->revision, buf + 32, 4); + sprintf(dev_scsi->type,"%x", buf[0] & 0x1f); if (close(fd) < 0) info("%s: close failed: %s\n", dev_scsi->kernel, strerror(errno)); @@ -767,15 +758,15 @@ int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname, return 0; } -int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, - int page_code, char *serial, char *serial_short, int len) +int scsi_get_serial (struct scsi_id_device *dev_scsi, const char *devname, + int page_code, char *serial_short, int len) { unsigned char page0[SCSI_INQ_BUFF_LEN]; int fd; int ind; int retval; - memset(serial, 0, len); + memset(dev_scsi->serial, 0, len); dbg("opening %s\n", devname); fd = open(devname, O_RDONLY | O_NONBLOCK); if (fd < 0) { @@ -785,7 +776,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, } if (page_code == PAGE_80) { - if (do_scsi_page80_inquiry(dev_scsi, fd, serial, serial_short, len)) { + if (do_scsi_page80_inquiry(dev_scsi, fd, dev_scsi->serial, serial_short, len)) { retval = 1; goto completed; } else { @@ -793,7 +784,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, goto completed; } } else if (page_code == PAGE_83) { - if (do_scsi_page83_inquiry(dev_scsi, fd, serial, serial_short, len)) { + if (do_scsi_page83_inquiry(dev_scsi, fd, dev_scsi->serial, serial_short, len)) { retval = 1; goto completed; } else { @@ -801,7 +792,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, goto completed; } } else if (page_code == PAGE_83_PRE_SPC3) { - retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, serial, serial_short, len); + retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, dev_scsi->serial, serial_short, len); if (retval) { /* * Fallback to servicing a SPC-2/3 compliant page 83 @@ -809,7 +800,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, * conform to pre-SPC3 expectations. */ if (retval == 2) { - if (do_scsi_page83_inquiry(dev_scsi, fd, serial, serial_short, len)) { + if (do_scsi_page83_inquiry(dev_scsi, fd, dev_scsi->serial, serial_short, len)) { retval = 1; goto completed; } else { @@ -849,7 +840,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_83) if (!do_scsi_page83_inquiry(dev_scsi, fd, - serial, serial_short, len)) { + dev_scsi->serial, serial_short, len)) { /* * Success */ @@ -860,7 +851,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_80) if (!do_scsi_page80_inquiry(dev_scsi, fd, - serial, serial_short, len)) { + dev_scsi->serial, serial_short, len)) { /* * Success */