aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2022-06-25 04:05:14 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2022-06-25 04:05:14 +0000
commit2e225c87784735360e9619766efe06782179a86a (patch)
tree1df2832c733c55207261b829ec7f0146287afe82 /src
parenta3eb530bb4b93949287f19a2b6fb418901f1f699 (diff)
downloadsg3_utils-2e225c87784735360e9619766efe06782179a86a.tar.gz
sg_rem_rest_elem: new utility for removing or restoring elements; bug fixes
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@955 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/Makefile.in78
-rw-r--r--src/sg_decode_sense.c105
-rw-r--r--src/sg_format.c85
-rw-r--r--src/sg_get_elem_status.c33
-rw-r--r--src/sg_get_lba_status.c242
-rw-r--r--src/sg_opcodes.c81
-rw-r--r--src/sg_rem_rest_elem.c317
-rw-r--r--src/sg_rep_zones.c121
-rw-r--r--src/sg_requests.c17
-rw-r--r--src/sg_sanitize.c32
-rw-r--r--src/sg_unmap.c45
-rw-r--r--src/sg_vpd.c2
-rw-r--r--src/sg_vpd_vendor.c2
-rw-r--r--src/sg_zone.c64
15 files changed, 817 insertions, 419 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 676f61fa..034f171d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,9 +4,9 @@ bin_PROGRAMS = \
sg_get_config sg_get_elem_status sg_get_lba_status sg_ident sg_inq \
sg_logs sg_luns sg_modes sg_opcodes sg_persist sg_prevent sg_raw \
sg_rdac sg_read_attr sg_read_block_limits sg_read_buffer \
- sg_read_long sg_readcap sg_reassign sg_referrals sg_rep_density \
- sg_rep_pip sg_rep_zones sg_requests sg_reset_wp sg_rmsn sg_rtpg \
- sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \
+ sg_read_long sg_readcap sg_reassign sg_referrals sg_rem_rest_elem \
+ sg_rep_density sg_rep_pip sg_rep_zones sg_requests sg_reset_wp \
+ sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \
sg_sat_read_gplog sg_sat_set_features sg_seek sg_senddiag sg_ses \
sg_ses_microcode sg_start sg_stpg sg_stream_ctl sg_sync sg_timestamp \
sg_turs sg_unmap sg_verify sg_vpd sg_wr_mode sg_write_buffer \
@@ -131,16 +131,18 @@ sg_read_long_LDADD = ../lib/libsgutils2.la
sg_reassign_LDADD = ../lib/libsgutils2.la
-sg_requests_LDADD = ../lib/libsgutils2.la
-
sg_referrals_LDADD = ../lib/libsgutils2.la
+sg_rem_rest_elem_LDADD = ../lib/libsgutils2.la
+
sg_rep_density_LDADD = ../lib/libsgutils2.la
sg_rep_pip_LDADD = ../lib/libsgutils2.la
sg_rep_zones_LDADD = ../lib/libsgutils2.la
+sg_requests_LDADD = ../lib/libsgutils2.la
+
sg_reset_wp_LDADD = ../lib/libsgutils2.la
sg_rmsn_LDADD = ../lib/libsgutils2.la
diff --git a/src/Makefile.in b/src/Makefile.in
index 8e7c9a7f..a71b2ca7 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -97,8 +97,9 @@ bin_PROGRAMS = sg_bg_ctl$(EXEEXT) sg_compare_and_write$(EXEEXT) \
sg_raw$(EXEEXT) sg_rdac$(EXEEXT) sg_read_attr$(EXEEXT) \
sg_read_block_limits$(EXEEXT) sg_read_buffer$(EXEEXT) \
sg_read_long$(EXEEXT) sg_readcap$(EXEEXT) sg_reassign$(EXEEXT) \
- sg_referrals$(EXEEXT) sg_rep_density$(EXEEXT) \
- sg_rep_pip$(EXEEXT) sg_rep_zones$(EXEEXT) sg_requests$(EXEEXT) \
+ sg_referrals$(EXEEXT) sg_rem_rest_elem$(EXEEXT) \
+ sg_rep_density$(EXEEXT) sg_rep_pip$(EXEEXT) \
+ sg_rep_zones$(EXEEXT) sg_requests$(EXEEXT) \
sg_reset_wp$(EXEEXT) sg_rmsn$(EXEEXT) sg_rtpg$(EXEEXT) \
sg_safte$(EXEEXT) sg_sanitize$(EXEEXT) \
sg_sat_identify$(EXEEXT) sg_sat_phy_event$(EXEEXT) \
@@ -246,6 +247,9 @@ sg_reassign_DEPENDENCIES = ../lib/libsgutils2.la
sg_referrals_SOURCES = sg_referrals.c
sg_referrals_OBJECTS = sg_referrals.$(OBJEXT)
sg_referrals_DEPENDENCIES = ../lib/libsgutils2.la
+sg_rem_rest_elem_SOURCES = sg_rem_rest_elem.c
+sg_rem_rest_elem_OBJECTS = sg_rem_rest_elem.$(OBJEXT)
+sg_rem_rest_elem_DEPENDENCIES = ../lib/libsgutils2.la
sg_rep_density_SOURCES = sg_rep_density.c
sg_rep_density_OBJECTS = sg_rep_density.$(OBJEXT)
sg_rep_density_DEPENDENCIES = ../lib/libsgutils2.la
@@ -408,13 +412,13 @@ am__depfiles_remade = ./$(DEPDIR)/sg_bg_ctl.Po \
./$(DEPDIR)/sg_read_block_limits.Po \
./$(DEPDIR)/sg_read_buffer.Po ./$(DEPDIR)/sg_read_long.Po \
./$(DEPDIR)/sg_readcap.Po ./$(DEPDIR)/sg_reassign.Po \
- ./$(DEPDIR)/sg_referrals.Po ./$(DEPDIR)/sg_rep_density.Po \
- ./$(DEPDIR)/sg_rep_pip.Po ./$(DEPDIR)/sg_rep_zones.Po \
- ./$(DEPDIR)/sg_requests.Po ./$(DEPDIR)/sg_reset.Po \
- ./$(DEPDIR)/sg_reset_wp.Po ./$(DEPDIR)/sg_rmsn.Po \
- ./$(DEPDIR)/sg_rtpg.Po ./$(DEPDIR)/sg_safte.Po \
- ./$(DEPDIR)/sg_sanitize.Po ./$(DEPDIR)/sg_sat_identify.Po \
- ./$(DEPDIR)/sg_sat_phy_event.Po \
+ ./$(DEPDIR)/sg_referrals.Po ./$(DEPDIR)/sg_rem_rest_elem.Po \
+ ./$(DEPDIR)/sg_rep_density.Po ./$(DEPDIR)/sg_rep_pip.Po \
+ ./$(DEPDIR)/sg_rep_zones.Po ./$(DEPDIR)/sg_requests.Po \
+ ./$(DEPDIR)/sg_reset.Po ./$(DEPDIR)/sg_reset_wp.Po \
+ ./$(DEPDIR)/sg_rmsn.Po ./$(DEPDIR)/sg_rtpg.Po \
+ ./$(DEPDIR)/sg_safte.Po ./$(DEPDIR)/sg_sanitize.Po \
+ ./$(DEPDIR)/sg_sat_identify.Po ./$(DEPDIR)/sg_sat_phy_event.Po \
./$(DEPDIR)/sg_sat_read_gplog.Po \
./$(DEPDIR)/sg_sat_set_features.Po \
./$(DEPDIR)/sg_scan_linux.Po ./$(DEPDIR)/sg_scan_win32.Po \
@@ -458,17 +462,18 @@ SOURCES = sg_bg_ctl.c sg_compare_and_write.c sg_copy_results.c sg_dd.c \
sg_map26.c sg_modes.c sg_opcodes.c sg_persist.c sg_prevent.c \
sg_raw.c sg_rbuf.c sg_rdac.c sg_read.c sg_read_attr.c \
sg_read_block_limits.c sg_read_buffer.c sg_read_long.c \
- sg_readcap.c sg_reassign.c sg_referrals.c sg_rep_density.c \
- sg_rep_pip.c sg_rep_zones.c sg_requests.c sg_reset.c \
- sg_reset_wp.c sg_rmsn.c sg_rtpg.c sg_safte.c sg_sanitize.c \
- sg_sat_identify.c sg_sat_phy_event.c sg_sat_read_gplog.c \
- sg_sat_set_features.c $(sg_scan_SOURCES) sg_seek.c \
- sg_senddiag.c sg_ses.c sg_ses_microcode.c sg_start.c sg_stpg.c \
- sg_stream_ctl.c sg_sync.c sg_test_rwbuf.c sg_timestamp.c \
- sg_turs.c sg_unmap.c sg_verify.c $(sg_vpd_SOURCES) \
- sg_wr_mode.c sg_write_buffer.c sg_write_long.c sg_write_same.c \
- sg_write_verify.c sg_write_x.c sg_xcopy.c sg_z_act_query.c \
- sg_zone.c sginfo.c sgm_dd.c sgp_dd.c
+ sg_readcap.c sg_reassign.c sg_referrals.c sg_rem_rest_elem.c \
+ sg_rep_density.c sg_rep_pip.c sg_rep_zones.c sg_requests.c \
+ sg_reset.c sg_reset_wp.c sg_rmsn.c sg_rtpg.c sg_safte.c \
+ sg_sanitize.c sg_sat_identify.c sg_sat_phy_event.c \
+ sg_sat_read_gplog.c sg_sat_set_features.c $(sg_scan_SOURCES) \
+ sg_seek.c sg_senddiag.c sg_ses.c sg_ses_microcode.c sg_start.c \
+ sg_stpg.c sg_stream_ctl.c sg_sync.c sg_test_rwbuf.c \
+ sg_timestamp.c sg_turs.c sg_unmap.c sg_verify.c \
+ $(sg_vpd_SOURCES) sg_wr_mode.c sg_write_buffer.c \
+ sg_write_long.c sg_write_same.c sg_write_verify.c sg_write_x.c \
+ sg_xcopy.c sg_z_act_query.c sg_zone.c sginfo.c sgm_dd.c \
+ sgp_dd.c
DIST_SOURCES = sg_bg_ctl.c sg_compare_and_write.c sg_copy_results.c \
sg_dd.c sg_decode_sense.c sg_emc_trespass.c sg_format.c \
sg_get_config.c sg_get_elem_status.c sg_get_lba_status.c \
@@ -476,17 +481,18 @@ DIST_SOURCES = sg_bg_ctl.c sg_compare_and_write.c sg_copy_results.c \
sg_map26.c sg_modes.c sg_opcodes.c sg_persist.c sg_prevent.c \
sg_raw.c sg_rbuf.c sg_rdac.c sg_read.c sg_read_attr.c \
sg_read_block_limits.c sg_read_buffer.c sg_read_long.c \
- sg_readcap.c sg_reassign.c sg_referrals.c sg_rep_density.c \
- sg_rep_pip.c sg_rep_zones.c sg_requests.c sg_reset.c \
- sg_reset_wp.c sg_rmsn.c sg_rtpg.c sg_safte.c sg_sanitize.c \
- sg_sat_identify.c sg_sat_phy_event.c sg_sat_read_gplog.c \
- sg_sat_set_features.c $(am__sg_scan_SOURCES_DIST) sg_seek.c \
- sg_senddiag.c sg_ses.c sg_ses_microcode.c sg_start.c sg_stpg.c \
- sg_stream_ctl.c sg_sync.c sg_test_rwbuf.c sg_timestamp.c \
- sg_turs.c sg_unmap.c sg_verify.c $(sg_vpd_SOURCES) \
- sg_wr_mode.c sg_write_buffer.c sg_write_long.c sg_write_same.c \
- sg_write_verify.c sg_write_x.c sg_xcopy.c sg_z_act_query.c \
- sg_zone.c sginfo.c sgm_dd.c sgp_dd.c
+ sg_readcap.c sg_reassign.c sg_referrals.c sg_rem_rest_elem.c \
+ sg_rep_density.c sg_rep_pip.c sg_rep_zones.c sg_requests.c \
+ sg_reset.c sg_reset_wp.c sg_rmsn.c sg_rtpg.c sg_safte.c \
+ sg_sanitize.c sg_sat_identify.c sg_sat_phy_event.c \
+ sg_sat_read_gplog.c sg_sat_set_features.c \
+ $(am__sg_scan_SOURCES_DIST) sg_seek.c sg_senddiag.c sg_ses.c \
+ sg_ses_microcode.c sg_start.c sg_stpg.c sg_stream_ctl.c \
+ sg_sync.c sg_test_rwbuf.c sg_timestamp.c sg_turs.c sg_unmap.c \
+ sg_verify.c $(sg_vpd_SOURCES) sg_wr_mode.c sg_write_buffer.c \
+ sg_write_long.c sg_write_same.c sg_write_verify.c sg_write_x.c \
+ sg_xcopy.c sg_z_act_query.c sg_zone.c sginfo.c sgm_dd.c \
+ sgp_dd.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -691,11 +697,12 @@ sg_read_block_limits_LDADD = ../lib/libsgutils2.la
sg_read_buffer_LDADD = ../lib/libsgutils2.la
sg_read_long_LDADD = ../lib/libsgutils2.la
sg_reassign_LDADD = ../lib/libsgutils2.la
-sg_requests_LDADD = ../lib/libsgutils2.la
sg_referrals_LDADD = ../lib/libsgutils2.la
+sg_rem_rest_elem_LDADD = ../lib/libsgutils2.la
sg_rep_density_LDADD = ../lib/libsgutils2.la
sg_rep_pip_LDADD = ../lib/libsgutils2.la
sg_rep_zones_LDADD = ../lib/libsgutils2.la
+sg_requests_LDADD = ../lib/libsgutils2.la
sg_reset_wp_LDADD = ../lib/libsgutils2.la
sg_rmsn_LDADD = ../lib/libsgutils2.la
sg_rtpg_LDADD = ../lib/libsgutils2.la
@@ -939,6 +946,10 @@ sg_referrals$(EXEEXT): $(sg_referrals_OBJECTS) $(sg_referrals_DEPENDENCIES) $(EX
@rm -f sg_referrals$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(sg_referrals_OBJECTS) $(sg_referrals_LDADD) $(LIBS)
+sg_rem_rest_elem$(EXEEXT): $(sg_rem_rest_elem_OBJECTS) $(sg_rem_rest_elem_DEPENDENCIES) $(EXTRA_sg_rem_rest_elem_DEPENDENCIES)
+ @rm -f sg_rem_rest_elem$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(sg_rem_rest_elem_OBJECTS) $(sg_rem_rest_elem_LDADD) $(LIBS)
+
sg_rep_density$(EXEEXT): $(sg_rep_density_OBJECTS) $(sg_rep_density_DEPENDENCIES) $(EXTRA_sg_rep_density_DEPENDENCIES)
@rm -f sg_rep_density$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(sg_rep_density_OBJECTS) $(sg_rep_density_LDADD) $(LIBS)
@@ -1141,6 +1152,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_readcap.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_reassign.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_referrals.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rem_rest_elem.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rep_density.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rep_pip.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rep_zones.Po@am__quote@ # am--include-marker
@@ -1376,6 +1388,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/sg_readcap.Po
-rm -f ./$(DEPDIR)/sg_reassign.Po
-rm -f ./$(DEPDIR)/sg_referrals.Po
+ -rm -f ./$(DEPDIR)/sg_rem_rest_elem.Po
-rm -f ./$(DEPDIR)/sg_rep_density.Po
-rm -f ./$(DEPDIR)/sg_rep_pip.Po
-rm -f ./$(DEPDIR)/sg_rep_zones.Po
@@ -1496,6 +1509,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/sg_readcap.Po
-rm -f ./$(DEPDIR)/sg_reassign.Po
-rm -f ./$(DEPDIR)/sg_referrals.Po
+ -rm -f ./$(DEPDIR)/sg_rem_rest_elem.Po
-rm -f ./$(DEPDIR)/sg_rep_density.Po
-rm -f ./$(DEPDIR)/sg_rep_pip.Po
-rm -f ./$(DEPDIR)/sg_rep_zones.Po
diff --git a/src/sg_decode_sense.c b/src/sg_decode_sense.c
index 76e5f6f9..160544be 100644
--- a/src/sg_decode_sense.c
+++ b/src/sg_decode_sense.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2021 Douglas Gilbert.
+ * Copyright (c) 2010-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.
@@ -30,7 +30,9 @@
#include "sg_unaligned.h"
-static const char * version_str = "1.25 20211119";
+static const char * version_str = "1.27 20220624";
+
+#define MY_NAME "sg_decode_sense"
#define MAX_SENSE_LEN 4096 /* max descriptor format actually: 255+8 */
@@ -44,6 +46,7 @@ static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"hex", no_argument, 0, 'H'},
{"in", required_argument, 0, 'i'}, /* don't advertise */
+ {"json", optional_argument, 0, 'j'},
{"inhex", required_argument, 0, 'i'}, /* same as --file */
{"nodecode", no_argument, 0, 'N'},
{"nospace", no_argument, 0, 'n'},
@@ -73,6 +76,7 @@ struct opts_t {
int verbose;
const char * wfname;
const char * no_space_str;
+ sgj_state json_st;
uint8_t sense[MAX_SENSE_LEN + 4];
};
@@ -85,10 +89,10 @@ usage()
pr2serr("Usage: sg_decode_sense [--binary=BFN] [--cdb] [--err=ES] "
"[--file=HFN]\n"
" [--help] [--hex] [--inhex=HFN] "
- "[--nodecode]\n"
- " [--nospace] [--status=SS] [--verbose] "
- "[--version]\n"
- " [--write=WFN] H1 H2 H3 ...\n"
+ "[--json[=JO]]\n"
+ " [--nodecode] [--nospace] [--status=SS] "
+ "[--verbose]\n"
+ " [--version] [--write=WFN] H1 H2 H3 ...\n"
" where:\n"
" --binary=BFN|-b BFN BFN is a file name to read sense "
"data in\n"
@@ -106,8 +110,16 @@ usage()
" --hex|-H used together with --write=WFN, to "
"write out\n"
" C language style ASCII hex (instead "
- "of binary)\n"
+ "of binary).\n"
+ " Otherwise don't decode, output incoming "
+ "data in\n"
+ " hex (used '-HH' or '-HHH' for different "
+ "formats)\n"
" --inhex=HFN|-i HFN same as action as --file=HFN\n"
+ " --json[=JO]|-j[JO] output in JSON instead of human "
+ "readable text.\n"
+ " Optional argument JO see sg3_utils "
+ "manpage\n"
" --nodecode|-N do not decode, may be neither sense "
"nor cdb\n"
" --nospace|-n no spaces or other separators between "
@@ -138,7 +150,7 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
char *endptr;
while (1) {
- c = getopt_long(argc, argv, "b:ce:f:hHi:nNs:vVw:", long_options,
+ c = getopt_long(argc, argv, "b:ce:f:hHi:j::nNs:vVw:", long_options,
NULL);
if (c == -1)
break;
@@ -178,6 +190,9 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
case '?':
op->do_help = true;
return 0;
+ case 'H':
+ op->hex_count++;
+ break;
case 'i':
if (op->fname) {
pr2serr("expect only one '--binary=BFN', '--file=HFN' or "
@@ -187,8 +202,12 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
op->file_given = true;
op->fname = optarg;
break;
- case 'H':
- op->hex_count++;
+ case 'j':
+ if (! sgj_init_state(&op->json_st, optarg)) {
+ pr2serr("bad argument to --json= option, unrecognized "
+ "character '%c'\n", op->json_st.first_bad_char);
+ return SG_LIB_SYNTAX_ERROR;
+ }
break;
case 'n':
op->no_space = true;
@@ -298,6 +317,7 @@ write2wfn(FILE * fp, struct opts_t * op)
int
main(int argc, char *argv[])
{
+ bool as_json;
int k, err, blen;
int ret = 0;
unsigned int ui;
@@ -305,6 +325,9 @@ main(int argc, char *argv[])
struct opts_t * op;
FILE * fp = NULL;
const char * cp;
+ sgj_state * jsp;
+ sgj_opaque_p jop = NULL;
+ sgj_opaque_p jo2p;
char b[2048];
struct opts_t opts;
@@ -341,6 +364,10 @@ main(int argc, char *argv[])
usage();
return 0;
}
+ as_json = op->json_st.pr_as_json;
+ jsp = &op->json_st;
+ if (as_json)
+ jop = sgj_start(MY_NAME, version_str, argc, argv, jsp);
if (op->err_given) {
char d[128];
@@ -368,29 +395,35 @@ main(int argc, char *argv[])
isxdigit((uint8_t)cp[k + 1]); k += 2) {
if (1 != sscanf(cp + k, "%2x", &ui)) {
pr2serr("bad no_space hex string: %s\n", cp);
- return SG_LIB_SYNTAX_ERROR;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
op->sense[op->sense_len++] = (uint8_t)ui;
}
}
if ((0 == op->sense_len) && (! op->do_binary) && (! op->file_given)) {
- if (op->do_status)
- return 0;
+ if (op->do_status) {
+ ret = 0;
+ goto fini;
+ }
pr2serr(">> Need sense/cdb/arbitrary data on the command line or "
"in a file\n\n");
usage();
- return SG_LIB_SYNTAX_ERROR;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
if (op->sense_len && (op->do_binary || op->file_given)) {
pr2serr(">> Need sense data on command line or in a file, not "
"both\n\n");
- return SG_LIB_CONTRADICT;
+ ret = SG_LIB_CONTRADICT;
+ goto fini;
}
if (op->do_binary && op->file_given) {
pr2serr(">> Either a binary file or a ASCII hexadecimal, file not "
"both\n\n");
- return SG_LIB_CONTRADICT;
+ ret = SG_LIB_CONTRADICT;
+ goto fini;
}
if (op->do_binary) {
@@ -399,13 +432,15 @@ main(int argc, char *argv[])
err = errno;
pr2serr("unable to open file: %s: %s\n", op->fname,
safe_strerror(err));
- return sg_convert_errno(err);
+ ret = sg_convert_errno(err);
+ goto fini;
}
s = fread(op->sense, 1, MAX_SENSE_LEN, fp);
fclose(fp);
if (0 == s) {
pr2serr("read nothing from file: %s\n", op->fname);
- return SG_LIB_SYNTAX_ERROR;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
op->sense_len = s;
} else if (op->file_given) {
@@ -413,7 +448,7 @@ main(int argc, char *argv[])
&op->sense_len, MAX_SENSE_LEN);
if (ret) {
pr2serr("unable to decode ASCII hex from file: %s\n", op->fname);
- return ret;
+ goto fini;
}
}
@@ -463,11 +498,39 @@ main(int argc, char *argv[])
sg_get_opcode_sa_name(opcode, sa, 0, blen, b);
printf("%s\n", b);
} else {
- sg_get_sense_str(NULL, op->sense, op->sense_len,
- op->verbose, blen, b);
+ if (as_json)
+ sgj_get_sense(jsp, jop, op->sense, op->sense_len);
+ else
+ sg_get_sense_str(NULL, op->sense, op->sense_len,
+ op->verbose, blen, b);
printf("%s\n", b);
}
}
fini:
+ if (as_json) {
+
+#if 0
+// <<<< testing
+// uint8_t dd[] = {0x1, 0x0, 0x0, 0x6, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+
+uint8_t dd[] = {0x01, 0x00, 0x00, 0x16, 0x11, 0x22, 0x33, 0x44 , 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
+ 0xdd, 0xee, 0xff, 0xed, 0xcb, 0xa9, 0x87, 0x65 , 0x43, 0x21};
+
+// uint8_t dd[] = {0x2, 0x1, 0x0, 0x14,
+// 0x41, 0x42, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20,
+// 0x58, 0x59, 0x5a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
+
+// uint8_t dd[] = {0x01, 0x03, 0x00, 0x08, 0x51, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
+// uint8_t dd[] = {0x01, 0x03, 0x00, 0x10, 0x61, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xee, 0xdd};
+
+jo2p = sgj_new_named_object(jsp, jop, "designation_descriptor");
+sgj_get_designation_descriptor(jsp, jo2p, dd, sizeof(dd));
+// <<<< end of testing
+#endif
+
+ if (0 == op->hex_count)
+ sgj_pr2file(&op->json_st, NULL, ret, stdout);
+ sgj_finish(jsp);
+ }
return ret;
}
diff --git a/src/sg_format.c b/src/sg_format.c
index 6c963af2..8703b1d5 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -40,7 +40,7 @@
#include "sg_pr2serr.h"
#include "sg_pt.h"
-static const char * version_str = "1.66 20220211";
+static const char * version_str = "1.67 20220607";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -58,17 +58,6 @@ static const char * version_str = "1.66 20220211";
true -> request sense */
#define MAX_BUFF_SZ 252
-#if defined(MSC_VER) || defined(__MINGW32__)
-#define HAVE_MS_SLEEP
-#endif
-
-#ifdef HAVE_MS_SLEEP
-#include <windows.h>
-#define sleep_for(seconds) Sleep( (seconds) * 1000)
-#else
-#define sleep_for(seconds) sleep(seconds)
-#endif
-
/* FORMAT UNIT (SBC) and FORMAT MEDIUM (SSC) share the same opcode */
#define SG_FORMAT_MEDIUM_CMD 0x4
#define SG_FORMAT_MEDIUM_CMDLEN 6
@@ -508,7 +497,7 @@ scsi_format_unit(int fd, const struct opts_t * op)
POLL_DURATION_SECS;
if (! op->poll_type) {
for(first = true; ; first = false) {
- sleep_for(poll_wait_secs);
+ sg_sleep_secs(poll_wait_secs);
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
true, (vb > 1) ? (vb - 1) : 0);
@@ -537,7 +526,7 @@ scsi_format_unit(int fd, const struct opts_t * op)
return sg_convert_errno(ENOMEM);
}
for(first = true; ; first = false) {
- sleep_for(poll_wait_secs);
+ sg_sleep_secs(poll_wait_secs);
memset(reqSense, 0x0, MAX_BUFF_SZ);
res = sg_ll_request_sense(fd, false, reqSense,
MAX_BUFF_SZ, false,
@@ -629,7 +618,7 @@ scsi_format_medium(int fd, const struct opts_t * op)
}
if (! op->poll_type) {
for(first = true; ; first = false) {
- sleep_for(POLL_DURATION_SECS);
+ sg_sleep_secs(POLL_DURATION_SECS);
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
true, (vb > 1) ? (vb - 1) : 0);
@@ -658,7 +647,7 @@ scsi_format_medium(int fd, const struct opts_t * op)
return sg_convert_errno(ENOMEM);
}
for(first = true; ; first = false) {
- sleep_for(POLL_DURATION_SECS);
+ sg_sleep_secs(POLL_DURATION_SECS);
memset(reqSense, 0x0, MAX_BUFF_SZ);
res = sg_ll_request_sense(fd, false, reqSense,
MAX_BUFF_SZ, false,
@@ -748,7 +737,7 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
}
if (! op->poll_type) {
for(first = true; ; first = false) {
- sleep_for(POLL_DURATION_SECS);
+ sg_sleep_secs(POLL_DURATION_SECS);
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
true, (vb > 1) ? (vb - 1) : 0);
@@ -777,7 +766,7 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
return sg_convert_errno(ENOMEM);
}
for(first = true; ; first = false) {
- sleep_for(POLL_DURATION_SECS);
+ sg_sleep_secs(POLL_DURATION_SECS);
memset(reqSense, 0x0, MAX_BUFF_SZ);
res = sg_ll_request_sense(fd, false, reqSense,
MAX_BUFF_SZ, false,
@@ -1680,24 +1669,8 @@ again_sp_false:
if (op->format) {
format_only:
- if (op->quick)
- goto skip_f_unit_reconsider;
- printf("\nA FORMAT UNIT will commence in 15 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA FORMAT UNIT will commence in 10 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA FORMAT UNIT will commence in 5 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
-skip_f_unit_reconsider:
+ if (! op->quick)
+ sg_warn_and_wait("FORMAT UNIT", op->device_name, true);
res = scsi_format_unit(fd, op);
ret = res;
if (res) {
@@ -1712,24 +1685,8 @@ skip_f_unit_reconsider:
format_med:
if (! op->poll_type_given) /* SSC-5 specifies REQUEST SENSE polling */
op->poll_type = true;
- if (op->quick)
- goto skip_f_med_reconsider;
- printf("\nA FORMAT MEDIUM will commence in 15 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA FORMAT MEDIUM will commence in 10 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA FORMAT MEDIUM will commence in 5 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
-skip_f_med_reconsider:
+ if (! op->quick)
+ sg_warn_and_wait("FORMAT MEDIUM", op->device_name, true);
res = scsi_format_medium(fd, op);
ret = res;
if (res) {
@@ -1740,24 +1697,8 @@ skip_f_med_reconsider:
goto out;
format_with_pre:
- if (op->quick)
- goto skip_f_with_pre_reconsider;
- printf("\nA FORMAT WITH PRESET will commence in 15 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA FORMAT WITH PRESET will commence in 10 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA FORMAT WITH PRESET will commence in 5 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n",
- op->device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
-skip_f_with_pre_reconsider:
+ if (! op->quick)
+ sg_warn_and_wait("FORMAT WITH PRESET", op->device_name, true);
res = scsi_format_with_preset(fd, op);
ret = res;
if (res) {
diff --git a/src/sg_get_elem_status.c b/src/sg_get_elem_status.c
index 47e18a99..fc46608a 100644
--- a/src/sg_get_elem_status.c
+++ b/src/sg_get_elem_status.c
@@ -37,11 +37,10 @@
* given SCSI device.
*/
-static const char * version_str = "1.10 20220527"; /* sbc5r01 */
+static const char * version_str = "1.11 20220616"; /* sbc5r01 */
#define MY_NAME "sg_get_elem_status"
-
#ifndef UINT32_MAX
#define UINT32_MAX ((uint32_t)-1)
#endif
@@ -549,12 +548,12 @@ start_response:
goto fini;
}
- sgj_pr_twin_vi(jsp, jop, 0, "Number of descriptors",
- SGJ_SEP_COLON_1_SPACE, num_desc);
- sgj_pr_twin_vi(jsp, jop, 0, "Number of descriptors returned",
- SGJ_SEP_COLON_1_SPACE, num_desc_ret);
- sgj_pr_twin_vi(jsp, jop, 0, "Identifier of element being depopulated",
- SGJ_SEP_COLON_1_SPACE, id_elem_depop);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Number of descriptors",
+ SGJ_SEP_COLON_1_SPACE, num_desc);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Number of descriptors returned",
+ SGJ_SEP_COLON_1_SPACE, num_desc_ret);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Identifier of element being depopulated",
+ SGJ_SEP_COLON_1_SPACE, id_elem_depop);
if (rlen < 64) {
sgj_pr_hr(jsp, "No complete physical element status descriptors "
"available\n");
@@ -575,18 +574,18 @@ start_response:
decode_elem_status_desc(bp, &a_ped);
if (jsp->pr_as_json) {
jo2p = sgj_new_unattached_object(jsp);
- sgj_add_name_pair_ihex(jsp, jo2p, "element_identifier",
- (int64_t)a_ped.elem_id);
+ sgj_add_nv_ihex(jsp, jo2p, "element_identifier",
+ (int64_t)a_ped.elem_id);
cp = (1 == a_ped.phys_elem_type) ? "storage" : "reserved";
- sgj_add_name_pair_istr(jsp, jo2p, "physical_element_type",
- a_ped.phys_elem_type, "meaning", cp);
+ sgj_add_nv_istr(jsp, jo2p, "physical_element_type",
+ a_ped.phys_elem_type, "meaning", cp);
j = a_ped.phys_elem_health;
fetch_health_str(j, b, blen);
- sgj_add_name_pair_istr(jsp, jo2p, "physical_element_health", j,
- "meaning", b);
- sgj_add_name_pair_ihex(jsp, jo2p, "associated_capacity",
- (int64_t)a_ped.assoc_cap);
- sgj_add_val_o(jsp, jap, NULL /* name */, jo2p);
+ sgj_add_nv_istr(jsp, jo2p, "physical_element_health", j,
+ "meaning", b);
+ sgj_add_nv_ihex(jsp, jo2p, "associated_capacity",
+ (int64_t)a_ped.assoc_cap);
+ sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
} else if (do_brief) {
sgj_pr_hr(jsp, "%u: %u,%u\n", a_ped.elem_id, a_ped.phys_elem_type,
a_ped.phys_elem_health);
diff --git a/src/sg_get_lba_status.c b/src/sg_get_lba_status.c
index 6a905793..1612aaac 100644
--- a/src/sg_get_lba_status.c
+++ b/src/sg_get_lba_status.c
@@ -35,14 +35,16 @@
* device.
*/
-static const char * version_str = "1.25 20220520"; /* sbc4r15 */
+static const char * version_str = "1.27 20220616"; /* sbc5r01 */
+
+#define MY_NAME "sg_get_lba_status"
#ifndef UINT32_MAX
#define UINT32_MAX ((uint32_t)-1)
#endif
#define MAX_GLBAS_BUFF_LEN (1024 * 1024)
-#define DEF_GLBAS_BUFF_LEN 24
+#define DEF_GLBAS_BUFF_LEN 1024
#define MIN_MAXLEN 16
static uint8_t glbasFixedBuff[DEF_GLBAS_BUFF_LEN];
@@ -52,12 +54,14 @@ static struct option long_options[] = {
{"16", no_argument, 0, 'S'},
{"32", no_argument, 0, 'T'},
{"brief", no_argument, 0, 'b'},
+ {"blockhex", no_argument, 0, 'B'},
{"element-id", required_argument, 0, 'e'},
{"element_id", required_argument, 0, 'e'},
{"help", no_argument, 0, 'h'},
{"hex", no_argument, 0, 'H'},
{"in", required_argument, 0, 'i'}, /* silent, same as --inhex= */
{"inhex", required_argument, 0, 'i'},
+ {"json", optional_argument, 0, 'j'},
{"lba", required_argument, 0, 'l'},
{"maxlen", required_argument, 0, 'm'},
{"raw", no_argument, 0, 'r'},
@@ -74,17 +78,20 @@ static struct option long_options[] = {
static void
usage()
{
- pr2serr("Usage: sg_get_lba_status [--16] [--32][--brief] "
- "[--element-id=EI]\n"
- " [--help] [--hex] [--inhex=FN] "
- "[--lba=LBA]\n"
- " [--maxlen=LEN] [--raw] [--readonly]\n"
+ pr2serr("Usage: sg_get_lba_status [--16] [--32] [--blockhex] "
+ "[--brief]\n"
+ " [--element-id=EI] [--help] [--hex] "
+ "[--inhex=FN]\n"
+ " [--lba=LBA] [--maxlen=LEN] [--raw] "
+ "[--readonly]\n"
" [--report-type=RT] [--scan-len=SL] "
"[--verbose]\n"
" [--version] DEVICE\n"
" where:\n"
" --16|-S use GET LBA STATUS(16) cdb (def)\n"
" --32|-T use GET LBA STATUS(32) cdb\n"
+ " --blockhex|-B outputs the (number of) blocks field "
+ " in hex\n"
" --brief|-b a descriptor per line:\n"
" <lba_hex blocks_hex p_status "
"add_status>\n"
@@ -98,6 +105,8 @@ usage()
"DEVICE,\n"
" assumed to be ASCII hex or, if --raw, "
"in binary\n"
+ " --json[=JO]|-j[JO] output in JSON instead of human "
+ "readable text\n"
" --lba=LBA|-l LBA starting LBA (logical block address) "
"(def: 0)\n"
" --maxlen=LEN|-m LEN max response length (allocation "
@@ -122,8 +131,10 @@ usage()
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n\n"
"Performs a SCSI GET LBA STATUS(16) or GET LBA STATUS(32) "
- "command (SBC-3 and\nSBC-4). If --inhex=FN is given then "
- "contents of FN is assumed to be a response\nto this command.\n"
+ "command (SBC-3 and\nSBC-4). The --element-id=EI and the "
+ "--scan-len=SL fields are only active\non the 32 byte cdb "
+ "variant. If --inhex=FN is given then contents of FN is\n"
+ "assumed to be a response to this command.\n"
);
}
@@ -159,6 +170,49 @@ decode_lba_status_desc(const uint8_t * bp, uint64_t * slbap,
return bp[12] & 0xf;
}
+static char *
+get_prov_status_str(int ps, char * b, int blen)
+{
+ switch (ps) {
+ case 0:
+ sg_scnpr(b, blen, "mapped (or unknown)");
+ break;
+ case 1:
+ sg_scnpr(b, blen, "deallocated");
+ break;
+ case 2:
+ sg_scnpr(b, blen, "anchored");
+ break;
+ case 3:
+ sg_scnpr(b, blen, "mapped"); /* sbc4r12 */
+ break;
+ case 4:
+ sg_scnpr(b, blen, "unknown"); /* sbc4r12 */
+ break;
+ default:
+ sg_scnpr(b, blen, "unknown provisioning status: %d", ps);
+ break;
+ }
+ return b;
+}
+
+static char *
+get_add_status_str(int as, char * b, int blen)
+{
+ switch (as) {
+ case 0:
+ sg_scnpr(b, blen, "%s", "");
+ break;
+ case 1:
+ sg_scnpr(b, blen, "may contain unrecovered errors");
+ break;
+ default:
+ sg_scnpr(b, blen, "unknown additional status: %d", as);
+ break;
+ }
+ return b;
+}
+
int
main(int argc, char * argv[])
@@ -170,8 +224,9 @@ main(int argc, char * argv[])
bool o_readonly = false;
bool verbose_given = false;
bool version_given = false;
- int k, j, res, c, rlen, num_descs, completion_cond, in_len;
+ int k, j, res, c, n, rlen, num_descs, completion_cond, in_len;
int sg_fd = -1;
+ int blockhex = 0;
int do_brief = 0;
int do_hex = 0;
int ret = 0;
@@ -190,12 +245,22 @@ main(int argc, char * argv[])
const uint8_t * bp;
uint8_t * glbasBuffp = glbasFixedBuff;
uint8_t * free_glbasBuffp = NULL;
+ sgj_opaque_p jop = NULL;
+ sgj_opaque_p jo2p = NULL;
+ sgj_opaque_p jap = NULL;
+ sgj_state json_st = {0};
+ sgj_state * jsp = &json_st;
+ char b[144];
+ static const size_t blen = sizeof(b);
+ static const char * prov_stat_s = "Provisoning status";
+ static const char * add_stat_s = "Additional status";
+ static const char * compl_cond_s = "Completion condition";
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "be:hi:Hl:m:rRs:St:TvV", long_options,
- &option_index);
+ c = getopt_long(argc, argv, "bBe:hi:j::Hl:m:rRs:St:TvV",
+ long_options, &option_index);
if (c == -1)
break;
@@ -203,6 +268,9 @@ main(int argc, char * argv[])
case 'b':
++do_brief;
break;
+ case 'B':
+ ++blockhex;
+ break;
case 'e':
ll = sg_get_llnum(optarg);
if ((ll < 0) || (ll > UINT32_MAX)) {
@@ -221,6 +289,13 @@ main(int argc, char * argv[])
case 'i':
in_fn = optarg;
break;
+ case 'j':
+ if (! sgj_init_state(&json_st, optarg)) {
+ pr2serr("bad argument to --json= option, unrecognized "
+ "character '%c'\n", json_st.first_bad_char);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
case 'l':
ll = sg_get_llnum(optarg);
if (-1 == ll) {
@@ -318,6 +393,8 @@ main(int argc, char * argv[])
pr2serr("version: %s\n", version_str);
return 0;
}
+ if (jsp->pr_as_json)
+ jop = sgj_start(MY_NAME, version_str, argc, argv, jsp);
if (maxlen > DEF_GLBAS_BUFF_LEN) {
glbasBuffp = (uint8_t *)sg_memalign(maxlen, 0, &free_glbasBuffp,
@@ -416,10 +493,10 @@ start_response:
goto fini;
}
if (do_hex) {
- if (do_hex > 2)
- hex2stdout(glbasBuffp, k, -1);
- else
- hex2stdout(glbasBuffp, k, (2 == do_hex) ? 0 : 1);
+ if (do_hex > 2)
+ hex2stdout(glbasBuffp, k, -1);
+ else
+ hex2stdout(glbasBuffp, k, (2 == do_hex) ? 0 : 1);
goto fini;
}
if (maxlen < 4) {
@@ -438,9 +515,9 @@ start_response:
rlen = maxlen;
if (do_brief > 1) {
- if (rlen < 24) {
- pr2serr("Need maxlen and response length to be at least 24, "
- "have %d bytes\n", rlen);
+ if (rlen > DEF_GLBAS_BUFF_LEN) {
+ pr2serr("Need maxlen and response length to be at least %d, "
+ "have %d bytes\n", DEF_GLBAS_BUFF_LEN, rlen);
ret = SG_LIB_CAT_OTHER;
goto fini;
}
@@ -462,92 +539,111 @@ start_response:
ret = SG_LIB_CAT_OTHER;
goto fini;
}
- printf("%d\n", res);
+ sgj_pr_hr(jsp,"p_status: %d add_status: 0x%x\n", res,
+ (unsigned int)add_status);
+ if (jsp->pr_as_json) {
+ sgj_add_nv_i(jsp, jop, prov_stat_s, res);
+ sgj_add_nv_i(jsp, jop, add_stat_s, add_status);
+ }
goto fini;
}
if (rlen < 24) {
- printf("No complete LBA status descriptors available\n");
+ sgj_pr_hr(jsp, "No complete LBA status descriptors available\n");
goto fini;
}
num_descs = (rlen - 8) / 16;
completion_cond = (*(glbasBuffp + 7) >> 1) & 7; /* added sbc4r14 */
if (do_brief)
- printf("Completion condition=%d\n", completion_cond);
+ sgj_pr_hr_js_vi(jsp, jop, 0, compl_cond_s,
+ SGJ_SEP_EQUAL_NO_SPACE, completion_cond);
else {
switch (completion_cond) {
case 0:
- printf("No indication of the completion condition\n");
+ snprintf(b, blen, "No indication of the completion condition");
break;
case 1:
- printf("Command completed due to meeting allocation length "
- "(--maxlen=LEN (def 24))\n");
+ snprintf(b, blen, "Command completed due to meeting allocation "
+ "length");
break;
case 2:
- printf("Command completed due to meeting scan length "
- "(--scan-len=SL)\n");
+ snprintf(b, blen, "Command completed due to meeting scan length");
break;
case 3:
- printf("Command completed due to meeting capacity of "
- "medium\n");
+ snprintf(b, blen, "Command completed due to meeting capacity of "
+ "medium");
break;
default:
- printf("Command completion is reserved [%d]\n",
+ snprintf(b, blen, "Command completion is reserved [%d]",
completion_cond);
break;
}
+ sgj_pr_hr(jsp, "%s\n", b);
+ sgj_add_nv_istr(jsp, jop, compl_cond_s, completion_cond,
+ NULL /* "meaning" */, b);
}
- printf("RTP=%d\n", *(glbasBuffp + 7) & 0x1); /* added sbc4r12 */
+ sgj_pr_hr_js_vi(jsp, jop, 0, "RTP", SGJ_SEP_EQUAL_NO_SPACE,
+ *(glbasBuffp + 7) & 0x1); /* added sbc4r12 */
if (verbose)
pr2serr("%d complete LBA status descriptors found\n", num_descs);
+ if (jsp->pr_as_json)
+ jap = sgj_new_named_array(jsp, jop, "lba_status_descriptor");
+
for (bp = glbasBuffp + 8, k = 0; k < num_descs; bp += 16, ++k) {
res = decode_lba_status_desc(bp, &d_lba, &d_blocks, &add_status);
if ((res < 0) || (res > 15))
pr2serr("descriptor %d: bad LBA status descriptor returned "
"%d\n", k + 1, res);
+ if (jsp->pr_as_json)
+ jo2p = sgj_new_unattached_object(jsp);
if (do_brief) {
- printf("0x");
+ n = 0;
+ n += sg_scnpr(b + n, blen - n, "0x");
for (j = 0; j < 8; ++j)
- printf("%02x", bp[j]);
- printf(" 0x%x %d %d\n", (unsigned int)d_blocks, res,
- add_status);
+ n += sg_scnpr(b + n, blen - n, "%02x", bp[j]);
+ if ((0 == blockhex) || (1 == (blockhex % 2)))
+ n += sg_scnpr(b + n, blen - n, " 0x%x %d %d",
+ (unsigned int)d_blocks, res, add_status);
+ else
+ n += sg_scnpr(b + n, blen - n, " %u %d %d",
+ (unsigned int)d_blocks, res, add_status);
+ sgj_pr_hr(jsp, "%s\n", b);
+ sgj_add_nv_ihex(jsp, jo2p, "lba", d_lba);
+ sgj_add_nv_ihex(jsp, jo2p, "blocks", d_blocks);
+ sgj_add_nv_i(jsp, jo2p, prov_stat_s, res);
+ sgj_add_nv_i(jsp, jo2p, add_stat_s, add_status);
} else {
- printf("[%d] LBA: 0x", k + 1);
- for (j = 0; j < 8; ++j)
- printf("%02x", bp[j]);
- printf(" blocks: %10u", (unsigned int)d_blocks);
- switch (res) {
- case 0:
- printf(" mapped (or unknown)");
- break;
- case 1:
- printf(" deallocated");
- break;
- case 2:
- printf(" anchored");
- break;
- case 3:
- printf(" mapped"); /* sbc4r12 */
- break;
- case 4:
- printf(" unknown"); /* sbc4r12 */
- break;
- default:
- printf(" Provisioning status: %d", res);
- break;
- }
- switch (add_status) {
- case 0:
- printf("\n");
- break;
- case 1:
- printf(" [may return unrecovered errors]\n");
- break;
- default:
- printf(" [add_status: 0x%x]\n", (unsigned int)add_status);
- break;
+ if (jsp->pr_as_json) {
+ sgj_add_nv_ihex(jsp, jo2p, "lba", d_lba);
+ sgj_add_nv_ihex(jsp, jo2p, "blocks", d_blocks);
+ sgj_add_nv_istr(jsp, jo2p, prov_stat_s, res, NULL,
+ get_prov_status_str(res, b, blen));
+ sgj_add_nv_istr(jsp, jo2p, add_stat_s, add_status, NULL,
+ get_add_status_str(add_status, b, blen));
+ } else {
+ char c[64];
+
+ n = 0;
+ n += sg_scnpr(b + n, blen - n, "[%d] LBA: 0x", k + 1);
+ for (j = 0; j < 8; ++j)
+ n += sg_scnpr(b + n, blen - n, "%02x", bp[j]);
+ if (1 == (blockhex % 2)) {
+
+ snprintf(c, sizeof(c), "0x%x", d_blocks);
+ n += sg_scnpr(b + n, blen - n, " blocks: %10s", c);
+ } else
+ n += sg_scnpr(b + n, blen - n, " blocks: %10u",
+ (unsigned int)d_blocks);
+ get_prov_status_str(res, c, sizeof(c));
+ n += sg_scnpr(b + n, blen - n, " %s", c);
+ get_add_status_str(add_status, c, sizeof(c));
+ if (strlen(c) > 0)
+ n += sg_scnpr(b + n, blen - n, " [%s]", c);
+ sgj_pr_hr(jsp, "%s\n", b);
}
}
+ if (jsp->pr_as_json)
+ sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
}
if ((num_descs * 16) + 8 < rlen)
pr2serr("incomplete trailing LBA status descriptors found\n");
@@ -581,5 +677,11 @@ fini:
pr2serr("Some error occurred, try again with '-v' or '-vv' for "
"more information\n");
}
- return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+ ret = (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+ if (jsp->pr_as_json) {
+ if (0 == do_hex)
+ sgj_pr2file(jsp, NULL, ret, stdout);
+ sgj_finish(jsp);
+ }
+ return ret;
}
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index 9d6f6c06..4eaa5bae 100644
--- a/src/sg_opcodes.c
+++ b/src/sg_opcodes.c
@@ -33,7 +33,7 @@
#include "sg_pt.h"
-static const char * version_str = "0.82 20220528"; /* spc6r06 */
+static const char * version_str = "0.83 20220616"; /* spc6r06 */
#define MY_NAME "sg_opcodes"
@@ -852,22 +852,22 @@ list_all_codes(uint8_t * rsoc_buff, int rsoc_len, struct opts_t * op,
}
if (jsp->pr_as_json) {
snprintf(b, blen, "0x%x", opcode);
- sgj_add_val_s(jsp, jop, "operation_code", b);
+ sgj_add_nv_s(jsp, jop, "operation_code", b);
if (sa_v) {
snprintf(b, blen, "0x%x", serv_act);
- sgj_add_val_s(jsp, jop, "service_action", b);
+ sgj_add_nv_s(jsp, jop, "service_action", b);
}
if (name_buff[0])
- sgj_add_val_s(jsp, jop, "name", name_buff);
- sgj_add_val_i(jsp, jop, "rwcdlp", (byt5 >> 6) & 0x1);
- sgj_add_val_i(jsp, jop, "mlu", (byt5 >> 4) & 0x3);
- sgj_add_val_i(jsp, jop, "cdlp", (byt5 >> 2) & 0x3);
- sgj_add_val_i(jsp, jop, "ctdp", (byt5 >> 1) & 0x1);
- sgj_add_val_i(jsp, jop, "servactv", byt5 & 0x1);
- sgj_add_val_i(jsp, jop, "cdb_length",
- sg_get_unaligned_be16(bp + 6));
-
- sgj_add_val_o(jsp, jap, NULL /* implies an array add */, jop);
+ sgj_add_nv_s(jsp, jop, "name", name_buff);
+ sgj_add_nv_i(jsp, jop, "rwcdlp", (byt5 >> 6) & 0x1);
+ sgj_add_nv_i(jsp, jop, "mlu", (byt5 >> 4) & 0x3);
+ sgj_add_nv_i(jsp, jop, "cdlp", (byt5 >> 2) & 0x3);
+ sgj_add_nv_i(jsp, jop, "ctdp", (byt5 >> 1) & 0x1);
+ sgj_add_nv_i(jsp, jop, "servactv", byt5 & 0x1);
+ sgj_add_nv_i(jsp, jop, "cdb_length",
+ sg_get_unaligned_be16(bp + 6));
+
+ sgj_add_nv_o(jsp, jap, NULL /* implies an array add */, jop);
}
if (op->do_mask && ptvp) {
@@ -903,8 +903,8 @@ list_all_codes(uint8_t * rsoc_buff, int rsoc_len, struct opts_t * op,
l = strlen(b2p);
if ((l > 0) && (' ' == b2p[l - 1]))
b2p[l - 1] = '\0';
- sgj_add_val_i(jsp, jo2p, "cdb_size", cdb_sz);
- sgj_add_val_s(jsp, jo2p, "cdb_usage_data", b2p);
+ sgj_add_nv_i(jsp, jo2p, "cdb_size", cdb_sz);
+ sgj_add_nv_s(jsp, jo2p, "cdb_usage_data", b2p);
}
}
} else
@@ -942,9 +942,9 @@ decode_cmd_timeout_desc(uint8_t * dp, int max_b_len, char * b,
else
snprintf(b, max_b_len, "nominal timeout: %u secs, ", timeout);
if (jsp->pr_as_json) {
- sgj_add_val_i(jsp, jsp->userp, "command_specific", dp[3]);
- sgj_add_val_i(jsp, jsp->userp,
- "nominal_command_processing_timeout", timeout);
+ sgj_add_nv_i(jsp, jsp->userp, "command_specific", dp[3]);
+ sgj_add_nv_i(jsp, jsp->userp, "nominal_command_processing_timeout",
+ timeout);
}
len = strlen(b);
max_b_len -= len;
@@ -955,8 +955,7 @@ decode_cmd_timeout_desc(uint8_t * dp, int max_b_len, char * b,
else
snprintf(b, max_b_len, "recommended timeout: %u secs", timeout);
if (jsp->pr_as_json)
- sgj_add_val_i(jsp, jsp->userp,
- "recommended_command_timeout", timeout);
+ sgj_add_nv_i(jsp, jsp->userp, "recommended_command_timeout", timeout);
return;
}
@@ -1072,25 +1071,25 @@ list_one(uint8_t * rsoc_buff, int cd_len, int rep_opts,
int l;
snprintf(b, blen, "0x%x", op->opcode);
- sgj_add_val_s(jsp, jop, "operation_code", b);
+ sgj_add_nv_s(jsp, jop, "operation_code", b);
if (rep_opts > 1) {
snprintf(b, blen, "0x%x", op->servact);
- sgj_add_val_s(jsp, jop, "service_action", b);
+ sgj_add_nv_s(jsp, jop, "service_action", b);
}
- sgj_add_val_i(jsp, jop, "rwcdlp", rwcdlp);
- sgj_add_val_i(jsp, jop, "ctdp", ctdp);
- sgj_add_val_i(jsp, jop, "mlu", mlu);
- sgj_add_val_i(jsp, jop, "cdlp", cdlp);
- sgj_add_val_i(jsp, jop, "support", support);
- sgj_add_val_s(jsp, jop, "support_str", cp);
- sgj_add_val_i(jsp, jop, "cdb_size", cd_len);
+ sgj_add_nv_i(jsp, jop, "rwcdlp", rwcdlp);
+ sgj_add_nv_i(jsp, jop, "ctdp", ctdp);
+ sgj_add_nv_i(jsp, jop, "mlu", mlu);
+ sgj_add_nv_i(jsp, jop, "cdlp", cdlp);
+ sgj_add_nv_i(jsp, jop, "support", support);
+ sgj_add_nv_s(jsp, jop, "support_str", cp);
+ sgj_add_nv_i(jsp, jop, "cdb_size", cd_len);
n = 0;
for (k = 0; k < cd_len; ++k)
n += sg_scnpr(b + n, blen - n, "%.2x ", rsoc_buff[k + 4]);
l = strlen(b);
if ((l > 0) && (' ' == b[l - 1]))
b[l - 1] = '\0';
- sgj_add_val_s(jsp, jop, "cdb_usage_data", b);
+ sgj_add_nv_s(jsp, jop, "cdb_usage_data", b);
}
if (ctdp) {
jsp->userp = sgj_new_named_object(jsp, jsp->basep,
@@ -1370,17 +1369,17 @@ start_response:
goto fini;
}
if (jsp->pr_as_json) {
- sgj_add_val_b(jsp, jop, "ats", rsoc_buff[0] & 0x80);
- sgj_add_val_b(jsp, jop, "atss", rsoc_buff[0] & 0x40);
- sgj_add_val_b(jsp, jop, "cacas", rsoc_buff[0] & 0x20);
- sgj_add_val_b(jsp, jop, "ctss", rsoc_buff[0] & 0x10);
- sgj_add_val_b(jsp, jop, "lurs", rsoc_buff[0] & 0x8);
- sgj_add_val_b(jsp, jop, "qts", rsoc_buff[0] & 0x4);
- sgj_add_val_b(jsp, jop, "trs", rsoc_buff[0] & 0x2);
- sgj_add_val_b(jsp, jop, "ws", rsoc_buff[0] & 0x1);
- sgj_add_val_b(jsp, jop, "qaes", rsoc_buff[1] & 0x4);
- sgj_add_val_b(jsp, jop, "qtss", rsoc_buff[1] & 0x2);
- sgj_add_val_b(jsp, jop, "itnrs", rsoc_buff[1] & 0x1);
+ sgj_add_nv_b(jsp, jop, "ats", rsoc_buff[0] & 0x80);
+ sgj_add_nv_b(jsp, jop, "atss", rsoc_buff[0] & 0x40);
+ sgj_add_nv_b(jsp, jop, "cacas", rsoc_buff[0] & 0x20);
+ sgj_add_nv_b(jsp, jop, "ctss", rsoc_buff[0] & 0x10);
+ sgj_add_nv_b(jsp, jop, "lurs", rsoc_buff[0] & 0x8);
+ sgj_add_nv_b(jsp, jop, "qts", rsoc_buff[0] & 0x4);
+ sgj_add_nv_b(jsp, jop, "trs", rsoc_buff[0] & 0x2);
+ sgj_add_nv_b(jsp, jop, "ws", rsoc_buff[0] & 0x1);
+ sgj_add_nv_b(jsp, jop, "qaes", rsoc_buff[1] & 0x4);
+ sgj_add_nv_b(jsp, jop, "qtss", rsoc_buff[1] & 0x2);
+ sgj_add_nv_b(jsp, jop, "itnrs", rsoc_buff[1] & 0x1);
if (! jsp->pr_output)
goto fini;
}
diff --git a/src/sg_rem_rest_elem.c b/src/sg_rem_rest_elem.c
new file mode 100644
index 00000000..46af7287
--- /dev/null
+++ b/src/sg_rem_rest_elem.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 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.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <ctype.h>
+#include <getopt.h>
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sg_lib.h"
+#include "sg_lib_data.h"
+#include "sg_pt.h"
+#include "sg_cmds_basic.h"
+#include "sg_unaligned.h"
+#include "sg_pr2serr.h"
+
+/* A utility program originally written for the Linux OS SCSI subsystem.
+ *
+ * This program issues one of the following SCSI commands:
+ * - REMOVE ELEMENT AND TRUNCATE
+ * - RESTORE ELEMENTS AND REBUILD
+ */
+
+static const char * version_str = "1.00 20220610";
+
+#define REMOVE_ELEM_SA 0x18
+#define RESTORE_ELEMS_SA 0x19
+
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
+#define DEF_PT_TIMEOUT 60 /* 60 seconds */
+
+
+static struct option long_options[] = {
+ {"capacity", required_argument, 0, 'c'},
+ {"element", required_argument, 0, 'e'},
+ {"help", no_argument, 0, 'h'},
+ {"quick", no_argument, 0, 'q'},
+ {"remove", no_argument, 0, 'r'},
+ {"restore", no_argument, 0, 'R'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0},
+};
+
+static const char * remove_cmd_s = "Remove element and truncate";
+static const char * restore_cmd_s = "Restore elements and rebuild";
+
+
+static void
+usage()
+{
+ pr2serr("Usage: "
+ "sg_rem_rest_elem [--capacity=RC] [--element=EID] [--help] "
+ "[--quick]\n"
+ " [--remove] [--restore] [--verbose] "
+ "[--version]\n"
+ " DEVICE\n");
+ pr2serr(" where:\n"
+ " --capacity=RC|-c RC RC is requested capacity (unit: "
+ "block; def: 0)\n"
+ " --element=EID|-e EID EID is the element identifier to "
+ "remove;\n"
+ " default is 0 which is an invalid "
+ "EID\n"
+ " --help|-h print out usage message\n"
+ " --quick|-q bypass 15 second warn and wait\n"
+ " --remove|-r issue REMOVE ELEMENT AND TRUNCATE "
+ "command\n"
+ " --restore|-R issue RESTORE ELEMENTS AND REBUILD "
+ "command\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string and exit\n\n"
+ "Performs a SCSI REMOVE ELEMENT AND TRUNCATE or RESTORE "
+ "ELEMENTS AND\nREBUILD command. Either the --remove or "
+ "--restore option needs to be given.\n");
+}
+
+/* Return of 0 -> success, various SG_LIB_CAT_* positive values or -1 ->
+ * other errors */
+static int
+sg_ll_rem_rest_elem(int sg_fd, int sa, uint64_t req_cap, uint32_t e_id,
+ bool noisy, int verbose)
+{
+ int ret, res, sense_cat;
+ struct sg_pt_base * ptvp;
+ uint8_t sai16_cdb[16] =
+ {SG_SERVICE_ACTION_IN_16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0};
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
+ const char * cmd_name;
+
+ sai16_cdb[1] = 0x1f & sa;
+ if (REMOVE_ELEM_SA == sa) {
+ sg_put_unaligned_be64(req_cap, sai16_cdb + 2);
+ sg_put_unaligned_be32(e_id, sai16_cdb + 10);
+ cmd_name = remove_cmd_s;
+ } else
+ cmd_name = restore_cmd_s;
+ if (verbose) {
+ char d[128];
+
+ pr2serr(" %s cdb: %s\n", cmd_name,
+ sg_get_command_str(sai16_cdb, 16, false, sizeof(d), d));
+ }
+
+ ptvp = construct_scsi_pt_obj();
+ if (NULL == ptvp) {
+ pr2serr("%s: out of memory\n", cmd_name);
+ return -1;
+ }
+ set_scsi_pt_cdb(ptvp, sai16_cdb, sizeof(sai16_cdb));
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
+ ret = sg_cmds_process_resp(ptvp, cmd_name, res, noisy,
+ verbose, &sense_cat);
+ if (-1 == ret) {
+ if (get_scsi_pt_transport_err(ptvp))
+ ret = SG_LIB_TRANSPORT_ERROR;
+ else
+ ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
+ } else if (-2 == ret) {
+ switch (sense_cat) {
+ case SG_LIB_CAT_RECOVERED:
+ case SG_LIB_CAT_NO_SENSE:
+ ret = 0;
+ break;
+ default:
+ ret = sense_cat;
+ break;
+ }
+ } else
+ ret = 0;
+ destruct_scsi_pt_obj(ptvp);
+ return ret;
+}
+
+
+int
+main(int argc, char * argv[])
+{
+ bool quick = false;
+ bool reat = false;
+ bool resar = false;
+ bool verbose_given = false;
+ bool version_given = false;
+ int res, c;
+ int sg_fd = -1;
+ int verbose = 0;
+ int ret = 0;
+ int sa = 0;
+ uint32_t e_id = 0;
+ uint64_t req_cap = 0;
+ int64_t ll;
+ const char * device_name = NULL;
+ const char * cmd_name;
+
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "c:e:hqrRvV", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'c':
+ ll = sg_get_llnum(optarg);
+ if (-1 == ll) {
+ pr2serr("--capacity= expects a numeric argument\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ req_cap = (uint64_t)ll;
+ break;
+ case 'e':
+ ll = sg_get_llnum(optarg);
+ if ((ll < 0) || (ll > UINT32_MAX)) {
+ pr2serr("bad argument to '--element=EID'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (0 == ll)
+ pr2serr("Warning: 0 is an invalid element identifier\n");
+ e_id = (uint64_t)ll;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'q':
+ quick = true;
+ break;
+ case 'r':
+ reat = true;
+ sa = REMOVE_ELEM_SA;
+ break;
+ case 'R':
+ resar = true;
+ sa = RESTORE_ELEMS_SA;
+ break;
+ case 'v':
+ verbose_given = true;
+ ++verbose;
+ break;
+ case 'V':
+ version_given = true;
+ break;
+ default:
+ pr2serr("unrecognised option code 0x%x ??\n", c);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+ if (optind < argc) {
+ if (NULL == device_name) {
+ device_name = argv[optind];
+ ++optind;
+ }
+ if (optind < argc) {
+ for (; optind < argc; ++optind)
+ pr2serr("Unexpected extra argument: %s\n",
+ argv[optind]);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+
+#ifdef DEBUG
+ pr2serr("In DEBUG mode, ");
+ if (verbose_given && version_given) {
+ pr2serr("but override: '-vV' given, zero verbose and continue\n");
+ verbose_given = false;
+ version_given = false;
+ verbose = 0;
+ } else if (! verbose_given) {
+ pr2serr("set '-vv'\n");
+ verbose = 2;
+ } else
+ pr2serr("keep verbose=%d\n", verbose);
+#else
+ if (verbose_given && version_given)
+ pr2serr("Not in DEBUG mode, so '-vV' has no special action\n");
+#endif
+ if (version_given) {
+ pr2serr("version: %s\n", version_str);
+ return 0;
+ }
+
+ if (1 != ((int)reat + (int)resar)) {
+ pr2serr("One, and only one, of these options needs to be given:\n"
+ " --remove or --restore\n\n");
+ usage();
+ return SG_LIB_CONTRADICT;
+ }
+ cmd_name = reat ? remove_cmd_s : restore_cmd_s;
+
+ if (NULL == device_name) {
+ pr2serr("missing device name!\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ sg_fd = sg_cmds_open_device(device_name, false /* rw */, verbose);
+ if (sg_fd < 0) {
+ int err = -sg_fd;
+ if (verbose)
+ pr2serr("open error: %s: %s\n", device_name,
+ safe_strerror(err));
+ ret = sg_convert_errno(err);
+ goto fini;
+ }
+ if (! quick)
+ sg_warn_and_wait(cmd_name, device_name, false);
+
+ res = sg_ll_rem_rest_elem(sg_fd, sa, req_cap, e_id, true, verbose);
+ ret = res;
+ if (res) {
+ if (SG_LIB_CAT_INVALID_OP == res)
+ pr2serr("%s command not supported\n", cmd_name);
+ else {
+ char b[80];
+
+ sg_get_category_sense_str(res, sizeof(b), b, verbose);
+ pr2serr("%s command: %s\n", cmd_name, b);
+ }
+ }
+
+fini:
+ if (sg_fd >= 0) {
+ res = sg_cmds_close_device(sg_fd);
+ if (res < 0) {
+ pr2serr("close error: %s\n", safe_strerror(-res));
+ if (0 == ret)
+ ret = sg_convert_errno(-res);
+ }
+ }
+ if (0 == verbose) {
+ if (! sg_if_can2stderr("sg_rem_rest_elem failed: ", ret))
+ pr2serr("Some error occurred, try again with '-v' or '-vv' for "
+ "more information\n");
+ }
+ return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+}
diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c
index 0866cd8d..a8d4cbc9 100644
--- a/src/sg_rep_zones.c
+++ b/src/sg_rep_zones.c
@@ -40,7 +40,7 @@
* Based on zbc2r12.pdf
*/
-static const char * version_str = "1.38 20220511";
+static const char * version_str = "1.39 20220616";
#define MY_NAME "sg_rep_zones"
@@ -395,28 +395,28 @@ prt_a_zn_desc(const uint8_t *bp, const struct opts_t * op,
zc = (bp[1] >> 4) & 0xf;
sg_get_zone_type_str(zt, sizeof(b), b);
sgj_pr_hr(jsp, " Zone type: %s\n", b);
- sgj_add_name_pair_istr(jsp, jop, "zone_type", zt, meaning_s, b);
+ sgj_add_nv_istr(jsp, jop, "zone_type", zt, meaning_s, b);
zone_condition_str(zc, b, sizeof(b), op->vb);
sgj_pr_hr(jsp, " Zone condition: %s\n", b);
- sgj_add_name_pair_istr(jsp, jop, "zone_condition", zc, meaning_s, b);
- sgj_pr_twin_vi(jsp, jop, 3, "PUEP", SGJ_SEP_COLON_1_SPACE,
- !!(bp[1] & 0x4));
- sgj_pr_twin_vi(jsp, jop, 3, "NON_SEQ", SGJ_SEP_COLON_1_SPACE,
- !!(bp[1] & 0x2));
- sgj_pr_twin_vi(jsp, jop, 3, "RESET", SGJ_SEP_COLON_1_SPACE,
- !!(bp[1] & 0x1));
+ sgj_add_nv_istr(jsp, jop, "zone_condition", zc, meaning_s, b);
+ sgj_pr_hr_js_vi(jsp, jop, 3, "PUEP", SGJ_SEP_COLON_1_SPACE,
+ !!(bp[1] & 0x4));
+ sgj_pr_hr_js_vi(jsp, jop, 3, "NON_SEQ", SGJ_SEP_COLON_1_SPACE,
+ !!(bp[1] & 0x2));
+ sgj_pr_hr_js_vi(jsp, jop, 3, "RESET", SGJ_SEP_COLON_1_SPACE,
+ !!(bp[1] & 0x1));
len = sg_get_unaligned_be64(bp + 8);
sgj_pr_hr(jsp, " Zone Length: 0x%" PRIx64 "\n", len);
- sgj_add_name_pair_ihex(jsp, jop, "zone_length", (int64_t)len);
+ sgj_add_nv_ihex(jsp, jop, "zone_length", (int64_t)len);
lba = sg_get_unaligned_be64(bp + 16);
sgj_pr_hr(jsp, " Zone start LBA: 0x%" PRIx64 "\n", lba);
- sgj_add_name_pair_ihex(jsp, jop, "zone_start_lba", (int64_t)lba);
+ sgj_add_nv_ihex(jsp, jop, "zone_start_lba", (int64_t)lba);
wp = sg_get_unaligned_be64(bp + 24);
if (sg_all_ffs((const uint8_t *)&wp, sizeof(wp)))
sgj_pr_hr(jsp, " Write pointer LBA: -1\n");
else
sgj_pr_hr(jsp, " Write pointer LBA: 0x%" PRIx64 "\n", wp);
- sgj_add_name_pair_ihex(jsp, jop, "write_pointer_lba", (int64_t)wp);
+ sgj_add_nv_ihex(jsp, jop, "write_pointer_lba", (int64_t)wp);
return lba + len;
}
@@ -457,12 +457,12 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len,
"granularity";
sgj_pr_hr(jsp, " Same=%d: %s\n", same, same_desc_arr[same]);
- sgj_add_name_pair_istr(jsp, jop, "same", same, meaning_s,
- same_desc_arr[same]);
+ sgj_add_nv_istr(jsp, jop, "same", same, meaning_s,
+ same_desc_arr[same]);
sgj_pr_hr(jsp, " Maximum LBA: 0x%" PRIx64 "\n\n", mx_lba);
- sgj_add_name_pair_ihex(jsp, jop, "maximum_lba", mx_lba);
+ sgj_add_nv_ihex(jsp, jop, "maximum_lba", mx_lba);
sgj_pr_hr(jsp, " %s: 0x%" PRIx64 "\n\n", rzslbag_s, rzslbag);
- sgj_add_name_pair_ihex(jsp, jop, rzslbag_s, rzslbag);
+ sgj_add_nv_ihex(jsp, jop, rzslbag_s, rzslbag);
}
if (op->do_num > 0)
num_zd = (num_zd > op->do_num) ? op->do_num : num_zd;
@@ -483,7 +483,7 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len,
}
sgj_pr_hr(jsp, "From last descriptor in this response:\n");
sgj_pr_hr(jsp, " %s%d\n", zn_dnum_s, num_zd - 1);
- sgj_add_val_i(jsp, jop, "zone_descriptor_index", num_zd - 1);
+ sgj_add_nv_i(jsp, jop, "zone_descriptor_index", num_zd - 1);
ul = prt_a_zn_desc(bp, op, jsp, jop);
if (ul > mx_lba)
sgj_pr_hr(jsp, " >> This zone seems to be the last one\n");
@@ -514,15 +514,14 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len,
else
sgj_pr_hr(jsp, "0x%" PRIx64 "\n", wp);
jo2p = sgj_new_unattached_object(jsp);
- sgj_add_name_pair_ihex(jsp, jo2p, "write_pointer_lba",
- (int64_t)wp);
- sgj_add_val_o(jsp, jap, NULL /* name */, jo2p);
+ sgj_add_nv_ihex(jsp, jo2p, "write_pointer_lba", (int64_t)wp);
+ sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
}
continue;
}
jo2p = sgj_new_unattached_object(jsp);
prt_a_zn_desc(bp, op, jsp, jo2p);
- sgj_add_val_o(jsp, jap, NULL /* name */, jo2p);
+ sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
}
if ((op->do_num == 0) && (! op->wp_only) && (! op->do_hex)) {
if ((64 + (REPORT_ZONES_DESC_LEN * (uint32_t)num_zd)) < decod_len)
@@ -554,12 +553,12 @@ decode_rep_realms(const uint8_t * rzBuff, int act_len,
nr_locator = sg_get_unaligned_be64(rzBuff + 12);
else
nr_locator = 0;
- sgj_pr_twin_vi(jsp, jop, 0, "Realms_count", SGJ_SEP_EQUAL_NO_SPACE,
- realms_count);
- sgj_pr_twin_vi(jsp, jop, 0, "Realms_descriptor_length",
- SGJ_SEP_EQUAL_NO_SPACE, r_desc_len);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Realms_count", SGJ_SEP_EQUAL_NO_SPACE,
+ realms_count);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Realms_descriptor_length",
+ SGJ_SEP_EQUAL_NO_SPACE, r_desc_len);
sgj_pr_hr(jsp, "Next_realm_locator=0x%" PRIx64 "\n", nr_locator);
- sgj_add_name_pair_ihex(jsp, jop, "Next_realm_locator", nr_locator);
+ sgj_add_nv_ihex(jsp, jop, "Next_realm_locator", nr_locator);
if ((realms_count < 1) || (act_len < (64 + 16)) || (r_desc_len < 16)) {
if (op->vb) {
pr2serr("%s: exiting early because ", __func__);
@@ -598,17 +597,17 @@ decode_rep_realms(const uint8_t * rzBuff, int act_len,
sgj_opaque_p jo2p;
jo2p = sgj_new_unattached_object(jsp);
- sgj_pr_twin_vi(jsp, jo2p, 1, "Realms_id", SGJ_SEP_EQUAL_NO_SPACE,
- sg_get_unaligned_be32(bp + 0));
+ sgj_pr_hr_js_vi(jsp, jo2p, 1, "Realms_id", SGJ_SEP_EQUAL_NO_SPACE,
+ sg_get_unaligned_be32(bp + 0));
if (op->do_hex) {
hex2stdout(bp, r_desc_len, -1);
continue;
}
restrictions = sg_get_unaligned_be16(bp + 4);
sgj_pr_hr(jsp, " realm_restrictions=0x%hu\n", restrictions);
- sgj_add_name_pair_ihex(jsp, jo2p, "realm_restrictions", restrictions);
- sgj_pr_twin_vi(jsp, jo2p, 3, "active_zone_domain_id",
- SGJ_SEP_EQUAL_NO_SPACE, bp[7]);
+ sgj_add_nv_ihex(jsp, jo2p, "realm_restrictions", restrictions);
+ sgj_pr_hr_js_vi(jsp, jo2p, 3, "active_zone_domain_id",
+ SGJ_SEP_EQUAL_NO_SPACE, bp[7]);
ja2p = sgj_new_named_array(jsp, jo2p,
"realm_start_end_descriptors_list");
@@ -618,18 +617,16 @@ decode_rep_realms(const uint8_t * rzBuff, int act_len,
jo3p = sgj_new_unattached_object(jsp);
sgj_pr_hr(jsp, " zone_domain=%u\n", j);
- sgj_add_val_i(jsp, jo3p, "corresponding_zone_domain_id", j);
+ sgj_add_nv_i(jsp, jo3p, "corresponding_zone_domain_id", j);
lba = sg_get_unaligned_be64(zp + 0);
sgj_pr_hr(jsp, " starting_lba=0x%" PRIx64 "\n", lba);
- sgj_add_name_pair_ihex(jsp, jo3p, "realm_starting_lba",
- (int64_t)lba);
+ sgj_add_nv_ihex(jsp, jo3p, "realm_starting_lba", (int64_t)lba);
lba = sg_get_unaligned_be64(zp + 8);
sgj_pr_hr(jsp, " ending_lba=0x%" PRIx64 "\n", lba);
- sgj_add_name_pair_ihex(jsp, jo3p, "realm_ending_lba",
- (int64_t)lba);
- sgj_add_val_o(jsp, ja2p, NULL /* name */, jo3p);
+ sgj_add_nv_ihex(jsp, jo3p, "realm_ending_lba", (int64_t)lba);
+ sgj_add_nv_o(jsp, ja2p, NULL /* name */, jo3p);
}
- sgj_add_val_o(jsp, jap, NULL /* name */, jo2p);
+ sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
}
return 0;
}
@@ -658,16 +655,16 @@ decode_rep_zdomains(const uint8_t * rzBuff, int act_len,
zd_locator = sg_get_unaligned_be64(rzBuff + 16);
else
zd_locator = 0;
- sgj_pr_twin_vi(jsp, jop, 0, "Zone_domains_returned_list_length=",
- SGJ_SEP_EQUAL_NO_SPACE, zd_ret_len);
- sgj_pr_twin_vi(jsp, jop, 0, "Zone_domains_supported",
- SGJ_SEP_EQUAL_NO_SPACE, zdoms_sup);
- sgj_pr_twin_vi(jsp, jop, 0, "Zone_domains_reported",
- SGJ_SEP_EQUAL_NO_SPACE, zdoms_rep);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Zone_domains_returned_list_length=",
+ SGJ_SEP_EQUAL_NO_SPACE, zd_ret_len);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Zone_domains_supported",
+ SGJ_SEP_EQUAL_NO_SPACE, zdoms_sup);
+ sgj_pr_hr_js_vi(jsp, jop, 0, "Zone_domains_reported",
+ SGJ_SEP_EQUAL_NO_SPACE, zdoms_rep);
sgj_pr_hr(jsp, "Reporting_options=0x%x\n", zd_rep_opts);
- sgj_add_name_pair_ihex(jsp, jop, "Reporting_options", zd_rep_opts);
+ sgj_add_nv_ihex(jsp, jop, "Reporting_options", zd_rep_opts);
sgj_pr_hr(jsp, "Zone_domain_locator=0x%" PRIx64 "\n", zd_locator);
- sgj_add_name_pair_ihex(jsp, jop, "Zone_domain_locator", zd_locator);
+ sgj_add_nv_ihex(jsp, jop, "Zone_domain_locator", zd_locator);
der_zdoms = zd_len / 96;
if (op->vb > 1)
@@ -680,24 +677,24 @@ decode_rep_zdomains(const uint8_t * rzBuff, int act_len,
sgj_opaque_p jo2p;
jo2p = sgj_new_unattached_object(jsp);
- sgj_pr_twin_vi(jsp, jo2p, 3, "zone_domain",
- SGJ_SEP_EQUAL_NO_SPACE, bp[0]);
+ sgj_pr_hr_js_vi(jsp, jo2p, 3, "zone_domain",
+ SGJ_SEP_EQUAL_NO_SPACE, bp[0]);
lba = sg_get_unaligned_be64(bp + 16);
sgj_pr_hr(jsp, " zone_count=%" PRIu64 "\n", lba);
- sgj_add_name_pair_ihex(jsp, jo2p, "zone_count", lba);
+ sgj_add_nv_ihex(jsp, jo2p, "zone_count", lba);
lba = sg_get_unaligned_be64(bp + 24);
sgj_pr_hr(jsp, " starting_lba=0x%" PRIx64 "\n", lba);
- sgj_add_name_pair_ihex(jsp, jo2p, "starting_lba", lba);
+ sgj_add_nv_ihex(jsp, jo2p, "starting_lba", lba);
lba = sg_get_unaligned_be64(bp + 32);
sgj_pr_hr(jsp, " ending_lba=0x%" PRIx64 "\n", lba);
- sgj_add_name_pair_ihex(jsp, jo2p, "ending_lba", lba);
+ sgj_add_nv_ihex(jsp, jo2p, "ending_lba", lba);
sgj_pr_hr(jsp, " zone_domain_zone_type=0x%x\n", bp[40]);
- sgj_add_name_pair_ihex(jsp, jo2p, "zone_domain_zone_type", bp[40]);
- sgj_pr_twin_vi(jsp, jo2p, 5, "VZDZT", SGJ_SEP_EQUAL_NO_SPACE,
- !!(0x2 & bp[42]));
- sgj_pr_twin_vi(jsp, jo2p, 5, "SRB", SGJ_SEP_EQUAL_NO_SPACE,
- !!(0x1 & bp[42]));
- sgj_add_val_o(jsp, jap, NULL /* name */, jo2p);
+ sgj_add_nv_ihex(jsp, jo2p, "zone_domain_zone_type", bp[40]);
+ sgj_pr_hr_js_vi(jsp, jo2p, 5, "VZDZT", SGJ_SEP_EQUAL_NO_SPACE,
+ !!(0x2 & bp[42]));
+ sgj_pr_hr_js_vi(jsp, jo2p, 5, "SRB", SGJ_SEP_EQUAL_NO_SPACE,
+ !!(0x1 & bp[42]));
+ sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
}
return 0;
}
@@ -774,8 +771,8 @@ find_report_zones(int sg_fd, uint8_t * rzBuff, const char * cmd_name,
} else {
sgj_pr_hr(jsp, "Condition met at:\n");
sgj_pr_hr(jsp, " %s: %d\n", zn_dnum_s, zn_dnum);
- sgj_add_val_b(jsp, jo2p, "met", true);
- sgj_add_val_i(jsp, jo2p, "zone_descriptor_index", zn_dnum);
+ sgj_add_nv_b(jsp, jo2p, "met", true);
+ sgj_add_nv_i(jsp, jo2p, "zone_descriptor_index", zn_dnum);
prt_a_zn_desc(bp, op, jsp, jo2p);
}
} else {
@@ -783,8 +780,8 @@ find_report_zones(int sg_fd, uint8_t * rzBuff, const char * cmd_name,
memset(b, 0xff, 64);
hex2stdout((const uint8_t *)b, 64, -1);
} else {
- sgj_add_val_b(jsp, jo2p, "met", false);
- sgj_add_val_i(jsp, jo2p, "zone_descriptor_index", zn_dnum);
+ sgj_add_nv_b(jsp, jo2p, "met", false);
+ sgj_add_nv_i(jsp, jo2p, "zone_descriptor_index", zn_dnum);
if (num_rem < 1)
sgj_pr_hr(jsp, "Condition NOT met, checked %d zones; "
"next %s%u\n", op->do_num, zn_dnum_s, zn_dnum);
@@ -1340,7 +1337,7 @@ main(int argc, char * argv[])
else if (op->do_realms)
cmd_name = "Report realms";
if (as_json)
- sgj_add_val_s(jsp, jop, "scsi_command_name", cmd_name);
+ sgj_add_nv_s(jsp, jop, "scsi_command_name", cmd_name);
if ((op->serv_act != REPORT_ZONES_SA) && op->do_partial) {
pr2serr("Can only use --partial with REPORT ZONES\n");
return SG_LIB_SYNTAX_ERROR;
diff --git a/src/sg_requests.c b/src/sg_requests.c
index ee0c0388..903c7ce8 100644
--- a/src/sg_requests.c
+++ b/src/sg_requests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2021 Douglas Gilbert.
+ * Copyright (c) 2004-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.
@@ -34,7 +34,7 @@
* This program issues the SCSI command REQUEST SENSE to the given SCSI device.
*/
-static const char * version_str = "1.39 20211114";
+static const char * version_str = "1.40 20220607";
#define MAX_REQS_RESP_LEN 255
#define DEF_REQS_RESP_LEN 252
@@ -45,17 +45,6 @@ static const char * version_str = "1.39 20211114";
#define REQUEST_SENSE_CMD 0x3
#define REQUEST_SENSE_CMDLEN 6
-/* Not all environments support the Unix sleep() */
-#if defined(MSC_VER) || defined(__MINGW32__)
-#define HAVE_MS_SLEEP
-#endif
-#ifdef HAVE_MS_SLEEP
-#include <windows.h>
-#define sleep_for(seconds) Sleep( (seconds) * 1000)
-#else
-#define sleep_for(seconds) sleep(seconds)
-#endif
-
#define ME "sg_requests: "
@@ -309,7 +298,7 @@ main(int argc, char * argv[])
for (k = 0; k < num_rs; ++k) {
act_din_len = 0;
if (k > 0)
- sleep_for(30);
+ sg_sleep_secs(30);
set_scsi_pt_cdb(ptvp, rs_cdb, sizeof(rs_cdb));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
memset(rsBuff, 0x0, sizeof(rsBuff));
diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c
index 41db4bba..74c33f2f 100644
--- a/src/sg_sanitize.c
+++ b/src/sg_sanitize.c
@@ -33,19 +33,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.18 20220127";
-
-/* Not all environments support the Unix sleep() */
-#if defined(MSC_VER) || defined(__MINGW32__)
-#define HAVE_MS_SLEEP
-#endif
-#ifdef HAVE_MS_SLEEP
-#include <windows.h>
-#define sleep_for(seconds) Sleep( (seconds) * 1000)
-#else
-#define sleep_for(seconds) sleep(seconds)
-#endif
-
+static const char * version_str = "1.19 20220608";
#define ME "sg_sanitize: "
@@ -720,20 +708,8 @@ main(int argc, char * argv[])
sg_put_unaligned_be16((uint16_t)op->ipl, wBuff + 2);
}
- if ((! op->quick) && (! op->fail)) {
- printf("\nA SANITIZE will commence in 15 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n", device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA SANITIZE will commence in 10 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n", device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nA SANITIZE will commence in 5 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n", device_name);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- }
+ if ((! op->quick) && (! op->fail))
+ sg_warn_and_wait("SANITIZE", device_name, true);
ret = do_sanitize(sg_fd, op, wBuff, param_lst_len);
if (ret) {
@@ -747,7 +723,7 @@ main(int argc, char * argv[])
pr2serr("Due to --dry-run option, leave poll loop\n");
break;
}
- sleep_for(POLL_DURATION_SECS);
+ sg_sleep_secs(POLL_DURATION_SECS);
memset(rsBuff, 0x0, sizeof(rsBuff));
res = sg_ll_request_sense(sg_fd, op->desc, rsBuff, sizeof(rsBuff),
1, vb);
diff --git a/src/sg_unmap.c b/src/sg_unmap.c
index 2deb71ad..c24c676a 100644
--- a/src/sg_unmap.c
+++ b/src/sg_unmap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2018 Douglas Gilbert.
+ * Copyright (c) 2009-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.
@@ -29,16 +29,6 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-#if defined(MSC_VER) || defined(__MINGW32__)
-#define HAVE_MS_SLEEP
-#endif
-
-#ifdef HAVE_MS_SLEEP
-#include <windows.h>
-#define sleep_for(seconds) Sleep( (seconds) * 1000)
-#else
-#define sleep_for(seconds) sleep(seconds)
-#endif
/* A utility program originally written for the Linux OS SCSI subsystem.
*
@@ -46,7 +36,7 @@
* logical blocks. Note that DATA MAY BE LOST.
*/
-static const char * version_str = "1.17 20180628";
+static const char * version_str = "1.18 20220608";
#define DEF_TIMEOUT_SECS 60
@@ -676,25 +666,14 @@ main(int argc, char * argv[])
printf("%s is: %.8s %.16s %.4s\n", device_name,
inq_resp.vendor, inq_resp.product, inq_resp.revision);
- sleep_for(3);
+ sg_sleep_secs(3);
if (to_end_of_device)
- snprintf(b, sizeof(b), "LBA 0x%" PRIx64 " to end of %s "
- "(0x%" PRIx64 ")", all_start, device_name, all_last);
+ snprintf(b, sizeof(b), "%s from LBA 0x%" PRIx64 " to end "
+ "(0x%" PRIx64 ")", device_name, all_start, all_last);
else
- snprintf(b, sizeof(b), "LBA 0x%" PRIx64 " to 0x%" PRIx64
- " on %s", all_start, all_last, device_name);
- printf("\nAn UNMAP (a.k.a. trim) will commence in 15 seconds\n");
- printf(" ALL data from %s will be LOST\n", b);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nAn UNMAP will commence in 10 seconds\n");
- printf(" ALL data from %s will be LOST\n", b);
- printf(" Press control-C to abort\n");
- sleep_for(5);
- printf("\nAn UNMAP (a.k.a. trim) will commence in 5 seconds\n");
- printf(" ALL data from %s will be LOST\n", b);
- printf(" Press control-C to abort\n");
- sleep_for(7);
+ snprintf(b, sizeof(b), "%s from LBA 0x%" PRIx64 " to 0x%"
+ PRIx64, device_name, all_start, all_last);
+ sg_warn_and_wait("UNMAP (a.k.a. trim)", b, false);
}
if (dry_run) {
pr2serr("Doing dry-run, would have unmapped from LBA 0x%" PRIx64
@@ -757,19 +736,19 @@ retry:
if (! do_force) {
printf("%s is: %.8s %.16s %.4s\n", device_name,
inq_resp.vendor, inq_resp.product, inq_resp.revision);
- sleep_for(3);
+ sg_sleep_secs(3);
printf("\nAn UNMAP (a.k.a. trim) will commence in 15 seconds\n");
printf(" Some data will be LOST\n");
printf(" Press control-C to abort\n");
- sleep_for(5);
+ sg_sleep_secs(5);
printf("\nAn UNMAP will commence in 10 seconds\n");
printf(" Some data will be LOST\n");
printf(" Press control-C to abort\n");
- sleep_for(5);
+ sg_sleep_secs(5);
printf("\nAn UNMAP (a.k.a. trim) will commence in 5 seconds\n");
printf(" Some data will be LOST\n");
printf(" Press control-C to abort\n");
- sleep_for(7);
+ sg_sleep_secs(7);
}
res = sg_ll_unmap_v2(sg_fd, anchor, grpnum, timeout, param_arr,
param_len, true, vb);
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 9350dbc6..20f74b5c 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -40,7 +40,7 @@
*/
-static const char * version_str = "1.70 20220218"; /* spc6r06 + sbc5r01 */
+static const char * version_str = "1.71 20220608"; /* spc6r06 + sbc5r01 */
/* standard VPD pages, in ascending page number order */
#define VPD_SUPPORTED_VPDS 0x0
diff --git a/src/sg_vpd_vendor.c b/src/sg_vpd_vendor.c
index d79ccc7d..a1a1a501 100644
--- a/src/sg_vpd_vendor.c
+++ b/src/sg_vpd_vendor.c
@@ -1558,6 +1558,6 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
return 0;
}
} else
- pr2serr("Vendor VPD page=0x%x failed to fetch", op->vpd_pn);
+ pr2serr("Vendor VPD page=0x%x failed to fetch\n", op->vpd_pn);
return res;
}
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;