aboutsummaryrefslogtreecommitdiff
path: root/src/sg_zone.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sg_zone.c')
-rw-r--r--src/sg_zone.c64
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;