📄 scsi_io.c
字号:
printf("WR_EX_AR:%d EX_AC_RO:%d WR_EX_RO:%d EX_AC:%d WR_EX:%d EX_AC_AR:%d\n", !!(data[4]&0x80), !!(data[4]&0x40), !!(data[4]&0x20), !!(data[4]&0x08), !!(data[4]&0x02), !!(data[4]&0x01)); return 0;}int scsi_persistent_reserve_in_read_full_status(int fd){ unsigned char cdb[]={0x5e,0,0,0,0,0,0,0,0,0}; unsigned int data_size=0x00ff; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=3; int res; unsigned long prgeneration, additional_length; cdb[1]=service_action; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; printf("PRESISTENT RESERVE IN: READ FULL STATUS\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } /* PRGeneration */ prgeneration=data[0]; prgeneration<<=8;prgeneration|=data[1]; prgeneration<<=8;prgeneration|=data[2]; prgeneration<<=8;prgeneration|=data[3]; printf("PRGeneration:%lu\n", prgeneration); /* Additional Length */ additional_length=data[4]; additional_length<<=8;additional_length|=data[5]; additional_length<<=8;additional_length|=data[6]; additional_length<<=8;additional_length|=data[7]; printf("Additional Length:%lu\n", additional_length);/*XXX*/ return 0;}int scsi_persistent_reserve_out_clear(int fd){ unsigned char cdb[]={0x5f,0,0,0,0,0,0,0,0,0}; unsigned int data_size=24; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=3; int res; long long k; if (scope==-1) { printf("Must specify scope\n"); printf("scsi_io --device=<DEVICE> --command=clear --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (type==-1) { printf("Must specify type\n"); printf("scsi_io --device=<DEVICE> --command=clear --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (!key) { printf("Must specify key\n"); printf("scsi_io --device=<DEVICE> --command=clear --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } sscanf(key, "%llx", &k); cdb[1]=service_action; cdb[2]=(scope<<4)|type; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; memset(data, 0, data_size); /* Reservation Key */ data[0]=(k>>56)&0xff; data[1]=(k>>48)&0xff; data[2]=(k>>40)&0xff; data[3]=(k>>32)&0xff; data[4]=(k>>24)&0xff; data[5]=(k>>16)&0xff; data[6]=(k>> 8)&0xff; data[7]=(k )&0xff; /* Service Action Key */ data[8]=0; data[9]=0; data[10]=0; data[11]=0; data[12]=0; data[13]=0; data[14]=0; data[15]=0; /* Spec_ip_ti=0 all_tg_pt=1 aptpl=0 */ data[20]=0x04; printf("PRESISTENT RESERVE IN: CLEAR\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_TO_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } return 0;}int scsi_persistent_reserve_out_reserve(int fd){ unsigned char cdb[]={0x5f,0,0,0,0,0,0,0,0,0}; unsigned int data_size=24; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=1; int res; long long k; if (scope==-1) { printf("Must specify scope\n"); printf("scsi_io --device=<DEVICE> --command=reserve --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (type==-1) { printf("Must specify type\n"); printf("scsi_io --device=<DEVICE> --command=reserve --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (!key) { printf("Must specify key\n"); printf("scsi_io --device=<DEVICE> --command=reserve --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } sscanf(key, "%llx", &k); cdb[1]=service_action; cdb[2]=(scope<<4)|type; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; memset(data, 0, data_size); /* Reservation Key */ data[0]=(k>>56)&0xff; data[1]=(k>>48)&0xff; data[2]=(k>>40)&0xff; data[3]=(k>>32)&0xff; data[4]=(k>>24)&0xff; data[5]=(k>>16)&0xff; data[6]=(k>> 8)&0xff; data[7]=(k )&0xff; /* Service Action Key */ data[8]=0; data[9]=0; data[10]=0; data[11]=0; data[12]=0; data[13]=0; data[14]=0; data[15]=0; /* Spec_ip_ti=0 all_tg_pt=1 aptpl=0 */ data[20]=0x04; printf("PRESISTENT RESERVE IN: RESERVE\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_TO_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } return 0;}int scsi_persistent_reserve_out_preempt(int fd){ unsigned char cdb[]={0x5f,0,0,0,0,0,0,0,0,0}; unsigned int data_size=24; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=4; int res; long long k; if (scope==-1) { printf("Must specify scope\n"); printf("scsi_io --device=<DEVICE> --command=preempt --scope=<SCOPE> --type=<TYPE> --key=<KEY> --rmkey=<KEY>\n"); _exit(10); } if (type==-1) { printf("Must specify type\n"); printf("scsi_io --device=<DEVICE> --command=preempt --scope=<SCOPE> --type=<TYPE> --key=<KEY> --rmkey=<KEY>\n"); _exit(10); } if (!key) { printf("Must specify key\n"); printf("scsi_io --device=<DEVICE> --command=preempt --scope=<SCOPE> --type=<TYPE> --key=<KEY> --rmkey=<KEY>\n"); _exit(10); } if (!rmkey) { printf("Must specify rmkey\n"); printf("scsi_io --device=<DEVICE> --command=preempt --scope=<SCOPE> --type=<TYPE> --key=<KEY> --rmkey=<KEY>\n"); _exit(10); } cdb[1]=service_action; cdb[2]=(scope<<4)|type; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; memset(data, 0, data_size); /* Reservation Key */ sscanf(key, "%llx", &k); data[0]=(k>>56)&0xff; data[1]=(k>>48)&0xff; data[2]=(k>>40)&0xff; data[3]=(k>>32)&0xff; data[4]=(k>>24)&0xff; data[5]=(k>>16)&0xff; data[6]=(k>> 8)&0xff; data[7]=(k )&0xff; /* Service Action Key */ sscanf(rmkey, "%llx", &k); data[8] =(k>>56)&0xff; data[9] =(k>>48)&0xff; data[10]=(k>>40)&0xff; data[11]=(k>>32)&0xff; data[12]=(k>>24)&0xff; data[13]=(k>>16)&0xff; data[14]=(k>> 8)&0xff; data[15]=(k )&0xff; /* Spec_ip_ti=0 all_tg_pt=1 aptpl=0 */ data[20]=0x04; printf("PRESISTENT RESERVE IN: RESERVE\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_TO_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } return 0;}int scsi_persistent_reserve_out_register_and_ignore_existing_key(int fd){ unsigned char cdb[]={0x5f,0,0,0,0,0,0,0,0,0}; unsigned int data_size=24; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=6; int res; long long k; if (scope==-1) { printf("Must specify scope\n"); printf("scsi_io --device=<DEVICE> --command=registerkey --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (type==-1) { printf("Must specify type\n"); printf("scsi_io --device=<DEVICE> --command=registerkey --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (!key) { printf("Must specify key\n"); printf("scsi_io --device=<DEVICE> --command=registerkey --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } sscanf(key, "%llx", &k); cdb[1]=service_action; cdb[2]=(scope<<4)|type; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; memset(data, 0, data_size); /* Reservation Key */ data[0]=0; data[1]=0; data[2]=0; data[3]=0; data[4]=0; data[5]=0; data[6]=0; data[7]=0; /* Service Action Key */ data[8] =(k>>56)&0xff; data[9] =(k>>48)&0xff; data[10]=(k>>40)&0xff; data[11]=(k>>32)&0xff; data[12]=(k>>24)&0xff; data[13]=(k>>16)&0xff; data[14]=(k>> 8)&0xff; data[15]=(k )&0xff; /* Spec_ip_ti=0 all_tg_pt=1 aptpl=0 */ data[20]=0x04; printf("PRESISTENT RESERVE IN: REGISTER AND IGNORE EXISTING KEY\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_TO_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } return 0;}int scsi_persistent_reserve_out_unregister_key(int fd){ unsigned char cdb[]={0x5f,0,0,0,0,0,0,0,0,0}; unsigned int data_size=24; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=6; int res; long long k; if (scope==-1) { printf("Must specify scope\n"); printf("scsi_io --device=<DEVICE> --command=unregisterkey --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (type==-1) { printf("Must specify type\n"); printf("scsi_io --device=<DEVICE> --command=unregisterkey --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } if (!key) { printf("Must specify key\n"); printf("scsi_io --device=<DEVICE> --command=unregisterkey --scope=<SCOPE> --type=<TYPE> --key=<KEY>\n"); _exit(10); } sscanf(key, "%llx", &k); cdb[1]=service_action; cdb[2]=(scope<<4)|type; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; memset(data, 0, data_size); /* Reservation Key */ data[0]=(k>>56)&0xff; data[1]=(k>>48)&0xff; data[2]=(k>>40)&0xff; data[3]=(k>>32)&0xff; data[4]=(k>>24)&0xff; data[5]=(k>>16)&0xff; data[6]=(k>> 8)&0xff; data[7]=(k )&0xff; /* Service Action Key */ data[8]=0; data[9]=0; data[10]=0; data[11]=0; data[12]=0; data[13]=0; data[14]=0; data[15]=0; /* Spec_ip_ti=0 all_tg_pt=1 aptpl=0 */ data[20]=0x04; printf("PRESISTENT RESERVE IN: UNREGISTER KEY\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_TO_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } return 0;}int open_scsi_device(const char *dev){ int fd, vers; if((fd=open(dev, O_RDWR))<0){ printf("ERROR could not open device %s\n", dev); return -1; } if ((ioctl(fd, SG_GET_VERSION_NUM, &vers) < 0) || (vers < 30000)) { printf("/dev is not an sg device, or old sg driver\n"); close(fd); return -1; } return fd;}typedef int (*scsi_func_t)(int fd);typedef struct _cmds_t { const char *cmd; scsi_func_t func; const char *comment;} cmds_t;cmds_t cmds[] = { {"inq", scsi_inquiry, "Standard INQUIRY output"}, {"vpd", scsi_inquiry_supported_vpd_pages, "Supported VPD Pages"}, {"usn", scsi_inquiry_unit_serial_number, "Unit serial number"}, {"readkeys", scsi_persistent_reserve_in_read_keys, "Read SCSI Reservation Keys"}, {"readrsvr", scsi_persistent_reserve_in_read_reservation, "Read SCSI Reservation Data"}, {"reportcap", scsi_persistent_reserve_in_report_capabilities, "Report reservation Capabilities"}, {"registerkey", scsi_persistent_reserve_out_register_and_ignore_existing_key, "Register and ignore existing key"}, {"unregisterkey", scsi_persistent_reserve_out_unregister_key, "Unregister a key"}, {"clear", scsi_persistent_reserve_out_clear, "Clear all reservations and registrations"}, {"reserve", scsi_persistent_reserve_out_reserve, "Reserve"}, {"preempt", scsi_persistent_reserve_out_preempt, "Preempt (remove someone elses registration)"},};void usage(void){ int i; printf("Usage: scsi_io --command <command> --device <device>\n"); printf("Commands:\n"); for (i=0;i<sizeof(cmds)/sizeof(cmds[0]);i++){ printf(" %s %s\n", cmds[i].cmd, cmds[i].comment); } }int main(int argc, const char *argv[]){ int i, fd; int opt; scsi_func_t func=NULL; struct poptOption popt_options[] = { POPT_AUTOHELP { "scope", 's', POPT_ARG_INT, &scope, 0, "scope", "integer" }, { "type", 't', POPT_ARG_INT, &type, 0, "type", "integer" }, { "key", 'k', POPT_ARG_STRING, &key, 0, "key", "key" }, { "rmkey", 'r', POPT_ARG_STRING, &rmkey, 0, "rmkey", "rmkey" }, { "command", 'c', POPT_ARG_STRING, &command, 0, "command", "command" }, { "device", 'd', POPT_ARG_STRING, &device, 0, "device", "device" },// { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL }, POPT_TABLEEND }; poptContext pc; pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "Invalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); _exit(1); } } if (!command) { printf("Must specify the command\n"); usage(); _exit(10); } if (!device) { printf("Must specify the device\n"); usage(); _exit(10); } fd=open_scsi_device(device); if(fd<0){ printf("Could not open SCSI device %s\n",device); usage(); _exit(10); } for (i=0;i<sizeof(cmds)/sizeof(cmds[0]);i++){ if(!strcmp(cmds[i].cmd, command)) { func = cmds[i].func; break; } } if (!func) { printf("Unrecognized command : %s\n", command); usage(); _exit(10); } func(fd);#if 0 scsi_persistent_reserve_in_read_full_status(fd); scsi_persistent_reserve_out_register_and_ignore_existing_key(fd); scsi_persistent_reserve_in_read_keys(fd); scsi_persistent_reserve_out_reserve(fd); scsi_persistent_reserve_in_read_reservation(fd); scsi_persistent_reserve_out_clear(fd); scsi_persistent_reserve_in_read_reservation(fd); scsi_persistent_reserve_out_unregister_key(fd); scsi_persistent_reserve_in_read_keys(fd);#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -