/* * This function returns the support for target port groups by evaluating the * data returned by the standard inquiry command. */ int get_target_port_group_support(int fd) { struct inquiry_data inq; int rc; memset((unsigned char *)&inq, 0, sizeof(inq)); rc = do_inquiry(fd, 0, 0x00, &inq, sizeof(inq)); if (!rc) { rc = inquiry_data_get_tpgs(&inq); } return rc; }
static void scrub_disk(const char *path) { sg_t sg; int dev_type; scsi_vendor_t vendor; scsi_model_t model; scsi_fw_revision_t revision; scsi_serial_t serial; uint64_t num_blocks; uint32_t block_size; printf("Scrubbing disk %s\n", path); if (!sg_open(&sg, path)) { fprintf(stderr, "Error opening disk %s: %m\n", path); return; } if (!do_inquiry(&sg, vendor, model, revision, serial, &dev_type)) { fprintf(stderr, "Error while reading inquiry\n"); goto Exit; } if (dev_type != TYPE_DISK) { fprintf(stderr, "Device is not a disk, scrubbing makes no sense\n"); goto Exit; } if (!do_read_capacity(&sg, &num_blocks, &block_size)) { fprintf(stderr, "Error while reading capacity\n"); goto Exit; } printf("Device attributes:\n" "\tVendor: %s\n" "\tModel: %s\n" "\tRevision: %s\n" "\tSerial: %s\n" "\tNum blocks: %llu\n" "\tBlock size: %u\n" "\tSize: %llu GB\n" , vendor, model, revision, serial, (unsigned long long)num_blocks, block_size, (unsigned long long)num_blocks*block_size/1000/1000/1000); do_scrub(&sg, num_blocks, block_size); Exit: sg_close(&sg); }
int get_target_port_group(int fd) { unsigned char buf[128]; struct vpd83_data * vpd83; struct vpd83_dscr * dscr; int rc; memset(buf, 0, sizeof(buf)); rc = do_inquiry(fd, 1, 0x83, buf, sizeof(buf)); if (!rc) { vpd83 = (struct vpd83_data *) buf; rc = -RTPG_NO_TPG_IDENTIFIER; FOR_EACH_VPD83_DSCR(vpd83, dscr) { if ((((char *) dscr) - ((char *) vpd83)) > sizeof(buf)) break; if (vpd83_dscr_istype(dscr, IDTYPE_TARGET_PORT_GROUP)) { struct vpd83_tpg_dscr * p; if (rc != -RTPG_NO_TPG_IDENTIFIER) { PRINT_DEBUG("get_target_port_group: " "more than one TPG identifier " "found!\n"); continue; } p = (struct vpd83_tpg_dscr *) dscr->data; rc = get_uint16(p->tpg); } } if (rc == -RTPG_NO_TPG_IDENTIFIER) { PRINT_DEBUG("get_target_port_group: " "no TPG identifier found!\n"); } }
int main(int argc, char *argv[]) { struct iscsi_context *iscsi; const char *url = NULL; struct iscsi_url *iscsi_url = NULL; int evpd = 0, pagecode = 0; int show_help = 0, show_usage = 0, debug = 0; int c; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"usage", no_argument, NULL, 'u'}, {"debug", no_argument, NULL, 'd'}, {"initiator-name", required_argument, NULL, 'i'}, {"evpd", required_argument, NULL, 'e'}, {"pagecode", required_argument, NULL, 'c'}, {0, 0, 0, 0} }; int option_index; while ((c = getopt_long(argc, argv, "h?udi:e:c:", long_options, &option_index)) != -1) { switch (c) { case 'h': case '?': show_help = 1; break; case 'u': show_usage = 1; break; case 'd': debug = 1; break; case 'i': initiator = optarg; break; case 'e': evpd = atoi(optarg); break; case 'c': pagecode = atoi(optarg); break; default: fprintf(stderr, "Unrecognized option '%c'\n\n", c); print_help(); exit(0); } } if (show_help != 0) { print_help(); exit(0); } if (show_usage != 0) { print_usage(); exit(0); } iscsi = iscsi_create_context(initiator); if (iscsi == NULL) { fprintf(stderr, "Failed to create context\n"); exit(10); } if (debug > 0) { iscsi_set_log_level(iscsi, debug); iscsi_set_log_fn(iscsi, iscsi_log_to_stderr); } if (argv[optind] != NULL) { url = strdup(argv[optind]); } if (url == NULL) { fprintf(stderr, "You must specify the URL\n"); print_usage(); exit(10); } iscsi_url = iscsi_parse_full_url(iscsi, url); if (url) { free(discard_const(url)); } if (iscsi_url == NULL) { fprintf(stderr, "Failed to parse URL: %s\n", iscsi_get_error(iscsi)); exit(10); } iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi)); iscsi_destroy_url(iscsi_url); iscsi_destroy_context(iscsi); exit(10); } do_inquiry(iscsi, iscsi_url->lun, evpd, pagecode); iscsi_destroy_url(iscsi_url); iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return 0; }
static void survey_disk(const char *path) { sg_t sg; FILE *out = NULL; printf("Scrubbing disk %s\n", path); if (!sg_open(&sg, path)) { fprintf(stderr, "Error opening disk %s: %m\n", path); return; } int dev_type; scsi_vendor_t vendor; scsi_model_t model; scsi_fw_revision_t revision; scsi_serial_t serial; if (!do_inquiry(&sg, vendor, model, revision, serial, &dev_type)) { fprintf(stderr, "Error while reading inquiry\n"); goto Exit; } if (dev_type != TYPE_DISK) { fprintf(stderr, "Device is not a disk (%d), bailing out.\n", dev_type); goto Exit; } char filename[256]; snprintf(filename, sizeof(filename), "disk-survey-%s-%s-%s.xml", strtrim(vendor), strtrim(model), strtrim(serial)); out = fopen(filename, "w"); if (!out) { fprintf(stderr, "Failed to open log file '%s' for output\n", filename); goto Exit; } char largebuf[1024*1024]; setbuffer(out, largebuf, sizeof(largebuf)); fprintf(out, "<survey>\n" "\t<inquiry>\n" "\t\t<vendor>%s</vendor>\n" "\t\t<model>%s</model>\n" "\t\t<revision>%s</revision>\n" "\t\t<serial>%s</serial>\n" "\t\t<raw>%s</raw>\n" "\t</inquiry>\n" , vendor, model, revision, serial, hex_encode(inquiry_buf, sizeof(inquiry_buf), 1)); uint64_t num_blocks; uint32_t block_size; survey_disk_capacity(&sg, out, &num_blocks, &block_size); survey_vpds(&sg, out); survey_timestamp(&sg, out); survey_mode_pages(&sg, out); survey_read_diagnostics(&sg, out); if (disk_is_ata(vendor)) { survey_ata_identify(&sg, out); } // It woud be preferable to have no other IO during the read // performance test, so flush the pending output buffer to keep all of // the space for the next test fflush(out); survey_read_performance(&sg, out, num_blocks, block_size, path); Exit: if (out) { fprintf(out, "</survey>\n"); fclose(out); } sg_close(&sg); }
int get_target_port_group(struct path * pp, unsigned int timeout) { unsigned char *buf; struct vpd83_data * vpd83; struct vpd83_dscr * dscr; int rc; int buflen, scsi_buflen; buflen = 4096; buf = (unsigned char *)malloc(buflen); if (!buf) { PRINT_DEBUG("malloc failed: could not allocate" "%u bytes\n", buflen); return -RTPG_RTPG_FAILED; } memset(buf, 0, buflen); rc = get_sysfs_pg83(pp, buf, buflen); if (rc < 0) { rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen, timeout); if (rc < 0) goto out; scsi_buflen = (buf[2] << 8 | buf[3]) + 4; /* Paranoia */ if (scsi_buflen >= USHRT_MAX) scsi_buflen = USHRT_MAX; if (buflen < scsi_buflen) { free(buf); buf = (unsigned char *)malloc(scsi_buflen); if (!buf) { PRINT_DEBUG("malloc failed: could not allocate" "%u bytes\n", scsi_buflen); return -RTPG_RTPG_FAILED; } buflen = scsi_buflen; memset(buf, 0, buflen); rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen, timeout); if (rc < 0) goto out; } } vpd83 = (struct vpd83_data *) buf; rc = -RTPG_NO_TPG_IDENTIFIER; FOR_EACH_VPD83_DSCR(vpd83, dscr) { if (vpd83_dscr_istype(dscr, IDTYPE_TARGET_PORT_GROUP)) { struct vpd83_tpg_dscr *p; if (rc != -RTPG_NO_TPG_IDENTIFIER) { PRINT_DEBUG("get_target_port_group: more " "than one TPG identifier found!\n"); continue; } p = (struct vpd83_tpg_dscr *)dscr->data; rc = get_uint16(p->tpg); } } if (rc == -RTPG_NO_TPG_IDENTIFIER) { PRINT_DEBUG("get_target_port_group: " "no TPG identifier found!\n"); } out: free(buf); return rc; }