ctdb-utils: Drop unused scsi_io.c source file
authorMartin Schwenke <mschwenke@ddn.com>
Wed, 22 Mar 2023 23:24:49 +0000 (10:24 +1100)
committerAmitay Isaacs <amitay@samba.org>
Wed, 19 Jul 2023 09:01:33 +0000 (09:01 +0000)
It will be in the git history if we ever decide to use SCSI persistent
reservations as a cluster lock.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/utils/scsi_io/scsi_io.c [deleted file]

diff --git a/ctdb/utils/scsi_io/scsi_io.c b/ctdb/utils/scsi_io/scsi_io.c
deleted file mode 100644 (file)
index 1d771de..0000000
+++ /dev/null
@@ -1,1152 +0,0 @@
-/* a tool to open a scsi device and issue some useful commands
-   such as INQUIRY and helpers to call various PERSISTENT RESERVATION
-   functions
-
-   Copyright   ronnie sahlberg 2007
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Very incomplete and needs to be enhanced with nice command line options
-   to drive it.
-   We need access to an array that supports the PERSISTENT RESERVATION cdb's
-   before we can proceed
-*/
-/* scsi bugs:
-   INQUIRY takes a 2 byte allocation_length parameter but it appears that
-   it only looks at the low byte. If you specify 0x00ff all is well
-   but if you specify 0x0100   it gets confused and returns garbage data
-   for (e.g) SupportedVPDPages. Same goes for UnitSerialNumber and probably all
-   other inq pages as well.
-
-*/
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <scsi/sg.h>
-#include "popt.h"
-
-
-#define SCSI_TIMEOUT 5000 /* ms */
-
-static char *command = NULL;
-static char *device  = NULL;
-static char *key     = NULL;
-static char *rmkey     = NULL;
-static int scope = -1;
-static int type  = -1;
-
-const char *sensetable[16]={
-       "no sense",
-       "recovered error",
-       "not ready",
-       "medium error",
-       "hardware error",
-       "illegal request",
-       "unit attention",
-       "data protect",
-       "blank check",
-       "vendor specific",
-       "copy aborted",
-       "aboreted command",
-       "unknown",
-       "unknown",
-       "unknown",
-       "unknown"
-};
-
-int scsi_io(int fd, unsigned char *cdb, unsigned char cdb_size, int xfer_dir, unsigned char *data, unsigned int *data_size, unsigned char *sense, unsigned int *sense_len)
-{
-       sg_io_hdr_t io_hdr;
-
-       memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
-       io_hdr.interface_id = 'S';
-
-       /* CDB */
-       io_hdr.cmdp = cdb;
-       io_hdr.cmd_len = cdb_size;
-
-       /* Where to store the sense_data, if there was an error */
-       io_hdr.sbp = sense;
-       io_hdr.mx_sb_len = *sense_len;
-       *sense_len=0;
-
-       /* Transfer direction, either in or out. Linux does not yet
-          support bidirectional SCSI transfers ?
-        */
-       io_hdr.dxfer_direction = xfer_dir;
-
-       /* Where to store the DATA IN/OUT from the device and how big the
-          buffer is
-        */
-       io_hdr.dxferp = data;
-       io_hdr.dxfer_len = *data_size;
-
-       /* SCSI timeout in ms */
-       io_hdr.timeout = SCSI_TIMEOUT;
-
-
-       if(ioctl(fd, SG_IO, &io_hdr) < 0){
-               perror("SG_IO ioctl failed");
-               return -1;
-       }
-
-       /* now for the error processing */
-       if((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK){
-               if(io_hdr.sb_len_wr > 0){
-                       *sense_len=io_hdr.sb_len_wr;
-                       return 0;
-               }
-       }
-       if(io_hdr.masked_status){
-               printf("status=0x%x\n", io_hdr.status);
-               printf("masked_status=0x%x\n", io_hdr.masked_status);
-               return -2;
-       }
-       if(io_hdr.host_status){
-               printf("host_status=0x%x\n", io_hdr.host_status);
-               return -3;
-       }
-       if(io_hdr.driver_status){
-               printf("driver_status=0x%x\n", io_hdr.driver_status);
-               return -4;
-       }
-
-#if 0
-{int i;
-printf("CDB:\n");
-for(i=0;i<cdb_size;i++){printf("0x%02x ",cdb[i]);if((i%8)==7)printf("\n");}
-printf("\n");
-}
-{int i;
-printf("DATA:\n");
-for(i=0;i<96;i++){printf("0x%02x ",data[i]);if((i%8)==7)printf("\n");}
-printf("\n");
-}
-#endif
-
-       return 0;
-}
-
-typedef struct _value_string_t {
-       int     value;
-       const char      *string;
-} value_string_t;
-
-
-
-value_string_t peripheral_device_types[] = {
-       {0, "SBC : Direct Access Block device"},
-       {1, "SSC : Sequential Access Device"},
-       {5, "MMC : Multimedia Device"},
-       {17,"OSD : Object Based Storage"},
-       {0,NULL}
-};
-
-value_string_t scsi_versions[] = {
-       {0, "No conformance to any standard claimed"},
-       {3, "SPC"},
-       {4, "SPC-2"},
-       {5, "SPC-3"},
-       {0,NULL}
-};
-
-value_string_t vpd_pages[] = {
-       {0x00, "Supported VPD Pages"},
-       {0x80, "Unit Serial number"},
-       {0x83, "Device Identification"},
-       {0,NULL}
-};
-
-const char *val_to_str(value_string_t *vs, int v)
-{
-       while(vs && vs->string){
-               if(vs->value==v){
-                       return vs->string;
-               }
-               vs++;
-       }
-       return "";
-}
-
-void print_sense_data(unsigned char *sense, int sense_len)
-{
-       int i;
-       unsigned char asc, ascq;
-
-       printf("Device returned sense information\n");
-       if(sense[0]==0x70){
-               printf("filemark:%d eom:%d ili:%d  sense-key:0x%02x (%s)\n",
-                       !!(sense[2]&0x80),
-                       !!(sense[2]&0x40),
-                       !!(sense[2]&0x20),
-                       sense[2]&0x0f,
-                       sensetable[sense[2]&0x0f]);
-               printf("command specific info: 0x%02x 0x%02x 0x%02x 0x%02x\n",
-                       sense[8],sense[9],sense[10],sense[11]);
-
-               asc=sense[12];
-               printf("additional sense code:0x%02x\n", asc);
-
-               ascq=sense[13];
-               printf("additional sense code qualifier:0x%02x\n", ascq);
-
-               printf("field replaceable unit code:0x%02x\n", sense[14]);
-
-               if((asc==0x20)&&(ascq==0x00))
-                       printf("INVALID COMMAND OPERATION CODE\n");
-       }
-
-       printf("Sense data:\n");
-       for(i=0;i<sense_len;i++){
-               printf("0x%02x ", sense[i]);
-               if((i%8)==7)printf("\n");
-       }
-       printf("\n");
-}
-
-int scsi_inquiry(int fd)
-{
-       unsigned char cdb[]={0x12,0,0,0,0,0};
-
-       unsigned int data_size=96;
-       unsigned char data[data_size];
-
-       unsigned int sense_len=32;
-       unsigned char sense[sense_len];
-
-       int res, i;
-
-       cdb[3]=(data_size>>8)&0xff;
-       cdb[4]=data_size&0xff;
-
-
-       printf("Standard INQUIRY Data:\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;
-       }
-
-       /* Peripheral Qualifier */
-       printf("Peripheral Qualifier:%c%c%cb\n",
-               '0'+!!(data[0]&0x80),
-               '0'+!!(data[0]&0x40),
-               '0'+!!(data[0]&0x20));
-
-       /* Peripheral Device Type */
-       printf("Peripheral Device Type: 0x%02x (%s)\n",
-               data[0]&0x1f,
-               val_to_str(peripheral_device_types, data[0]&0x1f));
-
-       /* RMB */
-       printf("RMB: %s device\n", data[1]&0x80?"REMOVABLE":"NON-REMOVABLE");
-
-       /* SCSI Version */
-       printf("SCSI Version: 0x%02x (%s)\n",
-               data[2],
-               val_to_str(scsi_versions, data[2]));
-
-       /* NormACA, HiSUP, Response Data Format */
-       printf("NormACA:%d HiSup:%d ResponseDataFormat:%d\n",
-               !!(data[3]&0x20),
-               !!(data[3]&0x10),
-               data[3]&0x0f);
-
-       switch(data[3]&0x0f){
-       /*SPC-2/SPC-3/SPC-4*/
-       case 2:
-       /*SPC (not strictly correct but we print it like 2 anyway)*/
-       case 1:
-               /* SCCS ... */
-               printf("SCCS:%d ACC:%d TPGS:%c%cb 3PC:%d PROTECT:%d\n",
-                       !!(data[5]&0x80),
-                       !!(data[5]&0x40),
-                       '0'+!!(data[5]&0x20),
-                       '0'+!!(data[5]&0x10),
-                       !!(data[5]&0x08),
-                       !!(data[5]&0x01));
-
-               /* Encserv ... */
-               printf("Encserv:%d VS:%d MultiP:%d ADDR16:%d\n",
-                       !!(data[6]&0x40),
-                       !!(data[6]&0x20),
-                       !!(data[6]&0x10),
-                       !!(data[6]&0x01));
-
-               /* WBUS16 ... */
-               printf("WBUS16:%d SYNC:%d CmdQue:%d VS:%d\n",
-                       !!(data[7]&0x20),
-                       !!(data[7]&0x10),
-                       !!(data[7]&0x02),
-                       !!(data[7]&0x01));
-
-
-               /* T10 vendor Identification */
-               printf("Vendor:");
-               for(i=0;i<8;i++)printf("%c",data[8+i]);printf("\n");
-
-               /* Product Identification */
-               printf("Product:");
-               for(i=0;i<16;i++)printf("%c",data[16+i]);printf("\n");
-
-               /* Product Revision Level */
-               printf("Product Revision:");
-               for(i=0;i<4;i++)printf("%c",data[32+i]);printf("\n");
-
-               break;
-       }
-
-       return 0;
-}
-
-int scsi_inquiry_supported_vpd_pages(int fd)
-{
-       unsigned char cdb[]={0x12,0x01,0,0,0,0};
-
-       unsigned int data_size=0xff;
-       unsigned char data[data_size];
-
-       unsigned int sense_len=32;
-       unsigned char sense[sense_len];
-
-       int res, pl, i;
-
-       cdb[3]=(data_size>>8)&0xff;
-       cdb[4]=data_size&0xff;
-
-
-       printf("INQUIRY Supported VPD Pages:\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;
-       }
-
-       /* Page Length */
-       pl=data[3];
-
-       /* Pages */
-       for(i=4;i<(pl+4);i++){
-               printf("Page:%02xh (%s)\n",
-                       data[i],
-                       val_to_str(vpd_pages, data[i]));
-       }
-
-       return 0;
-}
-
-int scsi_inquiry_unit_serial_number(int fd)
-{
-       unsigned char cdb[]={0x12,0x01,0x80,0,0,0};
-
-       unsigned int data_size=0x00ff;
-       unsigned char data[data_size];
-
-       unsigned int sense_len=32;
-       unsigned char sense[sense_len];
-
-       int res, pl, i;
-
-       cdb[3]=(data_size>>8)&0xff;
-       cdb[4]=data_size&0xff;
-
-
-       printf("INQUIRY Unit Serial Number:\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;
-       }
-
-       /* Page Length */
-       pl=data[3];
-
-       /* Unit Serial Number */
-       printf("Unit Serial Number:");
-       for(i=4;i<(pl+4);i++)printf("%c",data[i]&0xff);printf("\n");
-
-       return 0;
-}
-
-int scsi_persistent_reserve_in_read_keys(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=0;
-       int res, i;
-       unsigned long prgeneration, additional_length;
-
-       cdb[1]=service_action;
-       cdb[7]=(data_size>>8)&0xff;
-       cdb[8]=data_size&0xff;
-
-
-       printf("PERSISTENT RESERVE IN: READ KEYS\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);
-
-       /* print the registered keys */
-       for(i=0;i<additional_length;i+=8){
-               printf("Key:%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                       data[i+8],
-                       data[i+9],
-                       data[i+10],
-                       data[i+11],
-                       data[i+12],
-                       data[i+13],
-                       data[i+14],
-                       data[i+15]);
-       }
-
-       return 0;
-}
-
-int scsi_persistent_reserve_in_read_reservation(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=1;
-       int res;
-       unsigned long prgeneration, additional_length;
-
-       cdb[1]=service_action;
-       cdb[7]=(data_size>>8)&0xff;
-       cdb[8]=data_size&0xff;
-
-
-       printf("PERSISTENT RESERVE IN: READ RESERVATION\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);
-
-       if(additional_length==16){
-               printf("Key:%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                       data[8],
-                       data[9],
-                       data[10],
-                       data[11],
-                       data[12],
-                       data[13],
-                       data[14],
-                       data[15]);
-               printf("Scope:%xh Type:%xh\n",data[21]>>4,data[21]&0x0f);
-       }
-
-       return 0;
-}
-
-int scsi_persistent_reserve_in_report_capabilities(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=2;
-       int res;
-       unsigned short length, type_mask;
-
-       cdb[1]=service_action;
-       cdb[7]=(data_size>>8)&0xff;
-       cdb[8]=data_size&0xff;
-
-
-       printf("PERSISTENT RESERVE IN: REPORT CAPABILITIES\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;
-       }
-
-       /* Length */
-       length=data[0];
-       length<<=8;length|=data[1];
-       printf("Length:%d\n", length);
-
-       /* CRH ... */
-       printf("CRH:%d SIP_C:%d ATP_C:%d PTPL_C:%d\n",
-               !!(data[2]&0x10),
-               !!(data[2]&0x08),
-               !!(data[2]&0x04),
-               !!(data[2]&0x01));
-
-       /* TMV ... */
-       printf("TMV:%d ALLOW_COMMANDS:%c%c%cb PTPL_A:%d\n",
-               !!(data[3]&0x80),
-               '0'+(!!(data[3]&0x40)),
-               '0'+(!!(data[3]&0x20)),
-               '0'+(!!(data[3]&0x10)),
-               !!(data[3]&0x01));
-
-       /* Persistent Reservation Type Mask */
-       type_mask=data[4];
-       type_mask<<=8;type_mask|=data[5];
-       printf("Persistent Reservation Type Mask:0x%04x\n", type_mask);
-       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("PERSISTENT 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("PERSISTENT 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("PERSISTENT 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("PERSISTENT 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("PERSISTENT 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("PERSISTENT 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;
-}