diff options
Diffstat (limited to 'src/sg_zone.c')
-rw-r--r-- | src/sg_zone.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/src/sg_zone.c b/src/sg_zone.c index ff4dc366..e4540143 100644 --- a/src/sg_zone.c +++ b/src/sg_zone.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021 Douglas Gilbert. + * Copyright (c) 2014-2022 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. @@ -32,12 +32,15 @@ /* A utility program originally written for the Linux OS SCSI subsystem. * - * - * This program issues a SCSI CLOSE ZONE, FINISH ZONE or OPEN ZONE command - * to the given SCSI device. Based on zbc-r04c.pdf . + * This program issues one of the following SCSI commands: + * - CLOSE ZONE + * - FINISH ZONE + * - OPEN ZONE + * - REMOVE ELEMENT AND MODIFY ZONES + * - SEQUENTIALIZE ZONE */ -static const char * version_str = "1.17 20211114"; +static const char * version_str = "1.18 20220609"; #define SG_ZONING_OUT_CMDLEN 16 #define CLOSE_ZONE_SA 0x1 @@ -58,6 +61,7 @@ static struct option long_options[] = { {"finish", no_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, {"open", no_argument, 0, 'o'}, + {"quick", no_argument, 0, 'q'}, {"remove", no_argument, 0, 'r'}, {"reset-all", no_argument, 0, 'R'}, /* same as --all */ {"reset_all", no_argument, 0, 'R'}, @@ -68,14 +72,14 @@ static struct option long_options[] = { {0, 0, 0, 0}, }; -/* Indexed by service action */ +/* Indexed by service action of opcode 0x94 (Zone out) unless noted */ static const char * sa_name_arr[] = { "no SA=0", /* 0x0 */ "Close zone", "Finish zone", "Open zone", "-", "-", "-", "-", - "Zone activate", /* 0x8 */ + "-", "-", "-", "-", "-", "-", "-", @@ -84,7 +88,7 @@ static const char * sa_name_arr[] = { "-", "-", "-", "-", "-", "-", "-", "-", "-", - "Remove element and modify zones", /* 0x1a */ + "Remove element and modify zones", /* service action in(16), 0x1a */ }; @@ -94,10 +98,9 @@ usage() pr2serr("Usage: " "sg_zone [--all] [--close] [--count=ZC] [--element=EID] " "[--finish]\n" - " [--help] [--open] [--remove] " - "[--sequentialize] " - "[--verbose]\n" - " [--version] [--zone=ID] DEVICE\n"); + " [--help] [--open] [--quick] [--remove] " + "[--sequentialize]\n" + " [--verbose] [--version] [--zone=ID] DEVICE\n"); pr2serr(" where:\n" " --all|-a sets the ALL flag in the cdb\n" " --close|-c issue CLOSE ZONE command\n" @@ -109,6 +112,8 @@ usage() " --finish|-f issue FINISH ZONE command\n" " --help|-h print out usage message\n" " --open|-o issue OPEN ZONE command\n" + " --quick|-q bypass 15 second warn and wait " + "(for --remove)\n" " --remove|-r issue REMOVE ELEMENT AND MODIFY ZONES " "command\n" " --sequentialize|-S issue SEQUENTIALIZE ZONE command\n" @@ -116,11 +121,10 @@ usage() " --version|-V print version string and exit\n" " --zone=ID|-z ID ID is the starting LBA of the zone " "(def: 0)\n\n" - "Performs a SCSI OPEN ZONE, CLOSE ZONE, FINISH ZONE or " - "SEQUENTIALIZE\nZONE command. ID is decimal by default, for hex " - "use a leading '0x'\nor a trailing 'h'. Either --close, " - "--finish, --open, --remove or\n--sequentialize option needs to " - "be given.\n"); + "Performs a SCSI OPEN ZONE, CLOSE ZONE, FINISH ZONE, " + "REMOVE ELEMENT AND\nMODIFY ZONES or SEQUENTIALIZE ZONE " + "command. Either --close, --finish,\n--open, --remove or " + "--sequentialize option needs to be given.\n"); } /* Invokes the zone out command indicated by 'sa' (ZBC). Return of 0 @@ -139,7 +143,7 @@ sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, uint16_t zc, bool all, zo_cdb[1] = 0x1f & sa; if (REM_ELEM_MOD_ZONES_SA == sa) { /* zid carries element identifier */ zo_cdb[0] = SG_SERVICE_ACTION_IN_16; /* N.B. changing opcode */ - sg_put_unaligned_be32((uint32_t)zid, zo_cdb + 10); + sg_put_unaligned_be32((uint32_t)zid, zo_cdb + 10); /* element id */ } else { sg_put_unaligned_be64(zid, zo_cdb + 2); sg_put_unaligned_be16(zc, zo_cdb + 12); @@ -194,7 +198,9 @@ main(int argc, char * argv[]) bool close = false; bool finish = false; bool open = false; + bool quick = false; bool reamz = false; + bool element_id_given = false; bool sequentialize = false; bool verbose_given = false; bool version_given = false; @@ -212,7 +218,7 @@ main(int argc, char * argv[]) while (1) { int option_index = 0; - c = getopt_long(argc, argv, "acC:e:fhorRSvVz:", long_options, + c = getopt_long(argc, argv, "acC:e:fhoqrRSvVz:", long_options, &option_index); if (c == -1) break; @@ -243,7 +249,8 @@ main(int argc, char * argv[]) } if (0 == ll) pr2serr("Warning: 0 is an invalid element identifier\n"); - zid = (uint64_t)ll; + zid = (uint64_t)ll; /* putting element_id in zid */ + element_id_given = true; break; case 'f': finish = true; @@ -257,6 +264,9 @@ main(int argc, char * argv[]) open = true; sa = OPEN_ZONE_SA; break; + case 'q': + quick = true; + break; case 'r': reamz = true; sa = REM_ELEM_MOD_ZONES_SA; @@ -323,8 +333,15 @@ main(int argc, char * argv[]) if (1 != ((int)close + (int)finish + (int)open + (int)sequentialize + (int)reamz)) { - pr2serr("one of these options: --close, --finish, --open " - "--sequentialize and\n--remove must be given\n"); + pr2serr("One, and only one, of these options needs to be given:\n" + " --close, --finish, --open, --remove or --sequentialize " + "\n\n"); + usage(); + return SG_LIB_CONTRADICT; + } + if (element_id_given && (! reamz)) { + pr2serr("The --element=EID option should only be used with the " + "--remove option\n\n"); usage(); return SG_LIB_CONTRADICT; } @@ -345,6 +362,9 @@ main(int argc, char * argv[]) ret = sg_convert_errno(err); goto fini; } + if (reamz && (! quick)) + sg_warn_and_wait(sa_name_arr[REM_ELEM_MOD_ZONES_SA], device_name, + false); res = sg_ll_zone_out(sg_fd, sa, zid, zc, all, true, verbose); ret = res; |