aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2011-06-22 15:13:59 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2011-06-22 15:13:59 +0000
commit857d1cc82d6c2d9a980a98bffe24062b0d0e3cd9 (patch)
tree67a5f438e6e0112ae48aff9d2557895789bf57c1
parent8002042f678a5f4ee782ebe3f832bb61a4055eff (diff)
downloadsg3_utils-857d1cc82d6c2d9a980a98bffe24062b0d0e3cd9.tar.gz
add sg_sanitize, initial cut
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@407 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--COVERAGE3
-rw-r--r--ChangeLog3
-rw-r--r--README27
-rw-r--r--README.freebsd3
-rw-r--r--README.solaris3
-rw-r--r--README.tru643
-rw-r--r--README.win323
-rw-r--r--doc/Makefile.am39
-rw-r--r--doc/Makefile.in39
-rw-r--r--doc/sg_format.810
-rw-r--r--doc/sg_sanitize.8186
-rw-r--r--src/Makefile.am46
-rw-r--r--src/Makefile.in20
-rw-r--r--src/sg_sanitize.c539
14 files changed, 840 insertions, 84 deletions
diff --git a/COVERAGE b/COVERAGE
index a68f7f30..04716682 100644
--- a/COVERAGE
+++ b/COVERAGE
@@ -53,6 +53,7 @@ REPORT SUPPORTED OPERATION CODES sg_opcodes
REPORT SUPPORTED TASK MANAGEMENT FUNCTIONS sg_opcodes
REPORT TARGET PORT GROUPS sg_rtpg, sg_stpg ++
REQUEST SENSE sg_requests, ++
+SANITIZE sg_sanitize
SEND DIAGNOSTIC sg_senddiag, sg_ses, ++
SET IDENTIFYING INFORMATION sg_ident, ++ (3)
SET TARGET PORT GROUPS sg_stpg, ++
@@ -95,4 +96,4 @@ SMART READ DATA examples/sg_sat_smart_rd_data
Doug Gilbert
-6th September 2010
+21st June 2011
diff --git a/ChangeLog b/ChangeLog
index 2e477828..873b5937 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,8 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.32 [20110615] [svn: r406]
+Changelog for sg3_utils-1.32 [20110622] [svn: r407]
+ - sg_sanitize: new utility for command added in sb3r27
- sg_sat_identify: add '--ident' to output WWN
- sg_ses: major rework of descriptor output
- add --index, --descriptor and --join options
diff --git a/README b/README
index 98c29c24..d15f67eb 100644
--- a/README
+++ b/README
@@ -202,15 +202,15 @@ Utilities
=========
Here is list in alphabetical order of utilities found in the 'src'
subdirectory of the sg3_utils package:
- - sginfo, sgm_dd, sgp_dd, sg_dd, sg_decode_sense, sg_emc_trespass,
- - sg_format, sg_get_config, sg_get_lba_status, sg_ident, sg_inq, sg_logs,
- - sg_luns, sg_map, sg_map26, sg_modes, sg_opcodes, sg_persist, sg_prevent,
- - sg_raw, sg_rbuf, sg_rdac, sg_read, sg_readcap, sg_read_block_limits,
- - sg_read_buffer, sg_read_long, sg_reassign, sg_referrals, sg_request,
- - sg_reset, sg_rmsn, sg_rtpg, sg_safte, sg_sat_identify, sg_sat_phy_event,
- sg_sat_set_features, sg_scan, sg_senddiag, sg_ses, sg_start, sg_stpg,
- sg_sync, sg_test_rwbuff, sg_turs, sg_unmap, sg_verify, sg_vpd,
- sg_write_buffer, sg_write_long, sg_write_same, sg_wr_mode
+ sginfo, sgm_dd, sgp_dd, sg_dd, sg_decode_sense, sg_emc_trespass,
+ sg_format, sg_get_config, sg_get_lba_status, sg_ident, sg_inq, sg_logs,
+ sg_luns, sg_map, sg_map26, sg_modes, sg_opcodes, sg_persist, sg_prevent,
+ sg_raw, sg_rbuf, sg_rdac, sg_read, sg_readcap, sg_read_block_limits,
+ sg_read_buffer, sg_read_long, sg_reassign, sg_referrals, sg_request,
+ sg_reset, sg_rmsn, sg_rtpg, sg_safte, sg_sanitize, sg_sat_identify,
+ sg_sat_phy_event, sg_sat_set_features, sg_scan, sg_senddiag, sg_ses,
+ sg_start, sg_stpg, sg_sync, sg_test_rwbuff, sg_turs, sg_unmap, sg_verify,
+ sg_vpd, sg_write_buffer, sg_write_long, sg_write_same, sg_wr_mode
Each of the above utilities depends on header files found in the 'include'
subdirectory and library code found in the 'lib' subdirectory. Associated
@@ -329,9 +329,10 @@ The more recent utilities that use "getopt_long" only are:
- sg_decode_sense, sg_format sg_get_config sg_get_lba_status sg_ident
sg_luns sg_map26 sg_persist sg_prevent sg_raw sg_read_block_limits
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests sg_rmsn
- sg_rtpg sg_safte sg_sat_identify sg_sat_phy_event sg_sat_set_features
- sg_scan(w) sg_ses sg_stpg sg_sync sg_test_rwbuf sg_unmap sg_verify
- sg_vpd sg_write_buffer sg_write_long sg_write_same sg_wr_mode
+ sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event
+ sg_sat_set_features sg_scan(w) sg_ses sg_stpg sg_sync sg_test_rwbuf
+ sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long sg_write_same
+ sg_wr_mode
Dangerous code
@@ -353,4 +354,4 @@ See http://sg.danny.cz/sg/tools.html
Doug Gilbert
-13th June 2011
+21st June 2011
diff --git a/README.freebsd b/README.freebsd
index 557902bd..f20c4b36 100644
--- a/README.freebsd
+++ b/README.freebsd
@@ -37,6 +37,7 @@ Here is a list of utilities that have been ported:
sg_rmsn
sg_rtpg
sg_safte
+ sg_sanitize
sg_sat_identify
sg_sat_phy_event
sg_sat_set_features
@@ -118,4 +119,4 @@ utilities.
Doug Gilbert
-25th February 2011
+21st June 2011
diff --git a/README.solaris b/README.solaris
index 7fa6e30a..7d92f1b8 100644
--- a/README.solaris
+++ b/README.solaris
@@ -35,6 +35,7 @@ Here is a list of utilities that have been ported:
sg_rmsn
sg_rtpg
sg_safte
+ sg_sanitize
sg_sat_identify
sg_sat_phy_event
sg_sat_set_features
@@ -135,4 +136,4 @@ disks to accept SCSI commands including the SCSI ATA PASS THROUGH commands.
Doug Gilbert
-5th December 2010
+21st June 2011
diff --git a/README.tru64 b/README.tru64
index e3b474d5..1537d6db 100644
--- a/README.tru64
+++ b/README.tru64
@@ -32,6 +32,7 @@ Here is a list of utilities that have been ported:
sg_rmsn
sg_rtpg
sg_safte
+ sg_sanitize
sg_sat_identify
sg_sat_phy_event
sg_sat_set_features
@@ -92,4 +93,4 @@ subdirectory. Currently only the Tru64 port uses it.
Doug Gilbert
-5th December 2010
+21st June 2011
diff --git a/README.win32 b/README.win32
index 4497a364..1b8b372d 100644
--- a/README.win32
+++ b/README.win32
@@ -47,6 +47,7 @@ Here is a list of utilities that have been ported:
sg_rmsn
sg_rtpg
sg_safte
+ sg_sanitize
sg_sat_identify
sg_sat_phy_event
sg_sat_set_features
@@ -209,4 +210,4 @@ mode" with the setmode() Windows command.
Doug Gilbert
-11th February 2011
+21st June 2011
diff --git a/doc/Makefile.am b/doc/Makefile.am
index fa6ecec0..caae58fb 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -16,9 +16,9 @@ man_MANS = \
sgp_dd.8 sg_persist.8 sg_prevent.8 sg_raw.8 sg_rbuf.8 sg_rdac.8 \
sg_read.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 \
- sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 sg_sat_identify.8 \
- sg_sat_phy_event.8 sg_sat_set_features.8 sg_scan.8 \
- sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
+ sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 sg_sanitize.8 \
+ sg_sat_identify.8 sg_sat_phy_event.8 sg_sat_set_features.8 \
+ sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
sg_test_rwbuf.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
@@ -41,7 +41,7 @@ man_MANS = \
sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 \
sg_read_block_limits.8 sg_read_buffer.8 sg_read_long.8 \
sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 sg_rtpg.8 \
- sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
+ sg_safte.8 sg_sanitize.8 sg_sat_identify.8 sg_sat_phy_event.8 \
sg_sat_set_features.8 sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 \
sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
@@ -64,8 +64,8 @@ man_MANS = \
sg_inq.8 sg_logs.8 sg_luns.8 sg_modes.8 sg_opcodes.8 \
sg_persist.8 sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 \
sg_read_block_limits.8 sg_read_buffer.8 sg_read_long.8 \
- sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
+ sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 sg_rtpg.8 \
+ sg_safte.8 sg_sanitize.8 sg_sat_identify.8 sg_sat_phy_event.8 \
sg_sat_set_features.8 sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 \
sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
@@ -89,10 +89,11 @@ man_MANS = \
sg_modes.8 sg_opcodes.8 sg_persist.8 sg_prevent.8 sg_raw.8 \
sg_rdac.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
- sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 \
- sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
- sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
+ sg_rtpg.8 sg_safte.8 sg_sanitize.8 sg_sat_identify.8 \
+ sg_sat_phy_event.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
+ sg_start.8 sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 \
+ sg_vpd.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+ sg_wr_mode.8
endif
@@ -107,10 +108,11 @@ man_MANS = \
sg_modes.8 sg_opcodes.8 sg_persist.8 sg_prevent.8 sg_raw.8 \
sg_rdac.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
- sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 \
- sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
- sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
+ sg_rtpg.8 sg_safte.8 sg_sanitize.8 sg_sat_identify.8 \
+ sg_sat_phy_event.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
+ sg_start.8 sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 \
+ sg_vpd.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+ sg_wr_mode.8
endif
@@ -125,10 +127,11 @@ man_MANS = \
sg_modes.8 sg_opcodes.8 sg_persist.8 sg_prevent.8 sg_raw.8 \
sg_rdac.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
- sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 \
- sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
- sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
+ sg_rtpg.8 sg_safte.8 sg_sanitize.8 sg_sat_identify.8 \
+ sg_sat_phy_event.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
+ sg_start.8 sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 \
+ sg_vpd.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+ sg_wr_mode.8
endif
diff --git a/doc/Makefile.in b/doc/Makefile.in
index e0c47634..2408f80b 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -193,10 +193,11 @@ top_srcdir = @top_srcdir@
@OS_FREEBSD_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 sg_prevent.8 sg_raw.8 \
@OS_FREEBSD_TRUE@ sg_rdac.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
@OS_FREEBSD_TRUE@ sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
-@OS_FREEBSD_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
-@OS_FREEBSD_TRUE@ sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 \
-@OS_FREEBSD_TRUE@ sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
-@OS_FREEBSD_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
+@OS_FREEBSD_TRUE@ sg_rtpg.8 sg_safte.8 sg_sanitize.8 sg_sat_identify.8 \
+@OS_FREEBSD_TRUE@ sg_sat_phy_event.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
+@OS_FREEBSD_TRUE@ sg_start.8 sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 \
+@OS_FREEBSD_TRUE@ sg_vpd.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+@OS_FREEBSD_TRUE@ sg_wr_mode.8
# sg_dd, sg_emc_trespass(?), sginfo, sg_map26, sg_map, sgm_dd, sgp_dd,
@@ -213,9 +214,9 @@ top_srcdir = @top_srcdir@
@OS_LINUX_TRUE@ sgp_dd.8 sg_persist.8 sg_prevent.8 sg_raw.8 sg_rbuf.8 sg_rdac.8 \
@OS_LINUX_TRUE@ sg_read.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
@OS_LINUX_TRUE@ sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 \
-@OS_LINUX_TRUE@ sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 sg_sat_identify.8 \
-@OS_LINUX_TRUE@ sg_sat_phy_event.8 sg_sat_set_features.8 sg_scan.8 \
-@OS_LINUX_TRUE@ sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
+@OS_LINUX_TRUE@ sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 sg_sanitize.8 \
+@OS_LINUX_TRUE@ sg_sat_identify.8 sg_sat_phy_event.8 sg_sat_set_features.8 \
+@OS_LINUX_TRUE@ sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
@OS_LINUX_TRUE@ sg_test_rwbuf.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
@OS_LINUX_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
@@ -227,10 +228,11 @@ top_srcdir = @top_srcdir@
@OS_OSF_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 sg_prevent.8 sg_raw.8 \
@OS_OSF_TRUE@ sg_rdac.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
@OS_OSF_TRUE@ sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
-@OS_OSF_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
-@OS_OSF_TRUE@ sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 \
-@OS_OSF_TRUE@ sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
-@OS_OSF_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
+@OS_OSF_TRUE@ sg_rtpg.8 sg_safte.8 sg_sanitize.8 sg_sat_identify.8 \
+@OS_OSF_TRUE@ sg_sat_phy_event.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
+@OS_OSF_TRUE@ sg_start.8 sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 \
+@OS_OSF_TRUE@ sg_vpd.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+@OS_OSF_TRUE@ sg_wr_mode.8
@OS_SOLARIS_TRUE@man_MANS = \
@OS_SOLARIS_TRUE@ sg3_utils.8 sg_decode_sense.8 \
@@ -240,10 +242,11 @@ top_srcdir = @top_srcdir@
@OS_SOLARIS_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 sg_prevent.8 sg_raw.8 \
@OS_SOLARIS_TRUE@ sg_rdac.8 sg_readcap.8 sg_read_block_limits.8 sg_read_buffer.8 \
@OS_SOLARIS_TRUE@ sg_read_long.8 sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
-@OS_SOLARIS_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
-@OS_SOLARIS_TRUE@ sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 \
-@OS_SOLARIS_TRUE@ sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
-@OS_SOLARIS_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
+@OS_SOLARIS_TRUE@ sg_rtpg.8 sg_safte.8 sg_sanitize.8 sg_sat_identify.8 \
+@OS_SOLARIS_TRUE@ sg_sat_phy_event.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
+@OS_SOLARIS_TRUE@ sg_start.8 sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 \
+@OS_SOLARIS_TRUE@ sg_vpd.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+@OS_SOLARIS_TRUE@ sg_wr_mode.8
@OS_WIN32_CYGWIN_TRUE@man_MANS = \
@OS_WIN32_CYGWIN_TRUE@ sg3_utils.8 sg_decode_sense.8 \
@@ -252,8 +255,8 @@ top_srcdir = @top_srcdir@
@OS_WIN32_CYGWIN_TRUE@ sg_inq.8 sg_logs.8 sg_luns.8 sg_modes.8 sg_opcodes.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_persist.8 sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_read_block_limits.8 sg_read_buffer.8 sg_read_long.8 \
-@OS_WIN32_CYGWIN_TRUE@ sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 \
-@OS_WIN32_CYGWIN_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
+@OS_WIN32_CYGWIN_TRUE@ sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 sg_rtpg.8 \
+@OS_WIN32_CYGWIN_TRUE@ sg_safte.8 sg_sanitize.8 sg_sat_identify.8 sg_sat_phy_event.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_sat_set_features.8 sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
@@ -266,7 +269,7 @@ top_srcdir = @top_srcdir@
@OS_WIN32_MINGW_TRUE@ sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 \
@OS_WIN32_MINGW_TRUE@ sg_read_block_limits.8 sg_read_buffer.8 sg_read_long.8 \
@OS_WIN32_MINGW_TRUE@ sg_reassign.8 sg_referrals.8 sg_requests.8 sg_rmsn.8 sg_rtpg.8 \
-@OS_WIN32_MINGW_TRUE@ sg_safte.8 sg_sat_identify.8 sg_sat_phy_event.8 \
+@OS_WIN32_MINGW_TRUE@ sg_safte.8 sg_sanitize.8 sg_sat_identify.8 sg_sat_phy_event.8 \
@OS_WIN32_MINGW_TRUE@ sg_sat_set_features.8 sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 \
@OS_WIN32_MINGW_TRUE@ sg_stpg.8 sg_sync.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
@OS_WIN32_MINGW_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_wr_mode.8
diff --git a/doc/sg_format.8 b/doc/sg_format.8
index 4afefb87..4babd6f8 100644
--- a/doc/sg_format.8
+++ b/doc/sg_format.8
@@ -1,4 +1,4 @@
-.TH SG_FORMAT "8" "September 2010" "sg3_utils\-1.30" SG3_UTILS
+.TH SG_FORMAT "8" "June 2011" "sg3_utils\-1.32" SG3_UTILS
.SH NAME
sg_format \- format or resize a SCSI disk (perhaps change its block size)
.SH SYNOPSIS
@@ -118,7 +118,7 @@ bit is set, the FOV bit must also be set hence sg_format does that.
.TP
\fB\-e\fR, \fB\-\-early\fR
this option is active when \fI\-\-format\fR is given. The default action of
-this utility is to poll the disk every 30 seconds to determine the progress
+this utility is to poll the disk every 60 seconds to determine the progress
of the format operation until it is finished. When this option is given this
utility will exit "early" as soon as the format has commenced. Then the
user can monitor the progress of the ongoing format operation with other
@@ -262,7 +262,7 @@ When the \fI\-\-format\fR option is given without the \fI\-\-wait\fR option
then the SCSI FORMAT UNIT command is issued with the IMMED bit set which
causes the SCSI command to return after it has started the format operation.
The \fI\-\-early\fR option will cause sg_format to exit at that point.
-Otherwise the \fIDEVICE\fR is polled every 30 seconds with TEST UNIT READY
+Otherwise the \fIDEVICE\fR is polled every 60 seconds with TEST UNIT READY
commands until it reports an "all clear" (i.e. the format operation has
completed). Normally these polling commands will result in a progress
indicator (expressed as a percentage) being output to the screen. If the user
@@ -334,7 +334,7 @@ are made:
.PP
Now a simple format, leaving the block count and size as they were previously.
The FORMAT UNIT command is executed in IMMED mode and the device is polled
-every 30 seconds to print out a progress indication:
+every 60 seconds to print out a progress indication:
.PP
sg_format \-\-format /dev/sdm
.PP
@@ -372,7 +372,7 @@ Written by Grant Grundler, James Bottomley and Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2005\-2010 Grant Grundler, James Bottomley and Douglas Gilbert
+Copyright \(co 2005\-2011 Grant Grundler, James Bottomley and Douglas Gilbert
.br
This software is distributed under the GPL version 2. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/doc/sg_sanitize.8 b/doc/sg_sanitize.8
new file mode 100644
index 00000000..ae2bc290
--- /dev/null
+++ b/doc/sg_sanitize.8
@@ -0,0 +1,186 @@
+.TH SG_SANITIZE "8" "June 2011" "sg3_utils\-1.32" SG3_UTILS
+.SH NAME
+sg_sanitize \- remove all use data from a SCSI disk
+.SH SYNOPSIS
+.B sg_sanitize
+[\fI\-\-block\fR] [\fI\-\-count=OC\fR] [\fI\-\-crypto\fR] [\fI\-\-early\fR]
+[\fI\-\-help\fR] [\fI\-\-invert\fR] [\fI\-\-ipl=LEN\fR] [\fI\-\-overwrite\fR]
+[\fI\-\-pattern=PF\fR] [\fI\-\-quick\fR] [\fI\-\-verbose\fR]
+[\fI\-\-version\fR] [\fI\-\-wait\fR]
+\fIDEVICE\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+This utility invokes the SCSI SANITIZE command. This command was first
+introduced in the SBC\-3 revision 27 draft. The purpose of the sanitize
+operation is to alter the information in the cache and on the medium of a
+logical unit (e.g. a disk) so that the recovery of user data is not
+possible. If that user data cannot be erased, or is in the process of
+being erased, then the sanitize operation prevents access to that user
+data.
+.PP
+Once a SCSI SANITIZE command has successfully started, then user data from
+that disk is no longer available. Even if the disk is power cycled, the
+sanitize operation will continue after power is re\-instated until it is
+complete.
+.PP
+This utility requires either the \fI\-\-block\fR, \fI\-\-crypto\fR or
+\fI\-\-overwrite\fR option. If the \fI\-\-quick\fR option is not given
+then the user if given 15 seconds to reconsider whether they wish to
+erase all the data on a disk. The disk's INQUIRY response strings
+are printed out just in case the wrong \fIDEVICE\fR has been given.
+.PP
+If the \fI\-\-early\fR option is given this utility will exit soon
+after starting the SANITIZE command with the IMMED bit set. The user can
+monitor the progress of the sanitize operation with
+the "sg_request \-\-num=9999 \-\-progress" which sends a REQUEST SENSE
+command every 30 seconds. Otherwise if the \fI\-\-wait\fR option is given
+then this utility will wait until the SANITIZE command completes (or fails)
+and that can be many hours.
+.PP
+If neither the \fI\-\-early\fR nor \fI\-\-wait\fR option is given then
+the SANITIZE command is started with the IMMED bit set. After that this
+utility sends a REQUEST SENSE command every 60 seconds until there are
+no more progress indications.
+.SH OPTIONS
+Arguments to long options are mandatory for short options as well.
+The options are arranged in alphabetical order based on the long
+option name.
+.TP
+\fB\-B\fR, \fB\-\-block\fR
+perform a "block erase" sanitize operation.
+.TP
+\fB\-c\fR, \fB\-\-count\fR=\fIOC\fR
+where \fIOC\fR is the "overwrite count" associated with the "overwrite"
+sanitize operation. \fIOC\fR can be a value between 1 and 31 and 1 is
+the default.
+.TP
+\fB\-C\fR, \fB\-\-crypto\fR
+perform a "cryptographic erase" sanitize operation.
+.TP
+\fB\-e\fR, \fB\-\-early\fR
+the default action of this utility is to poll the disk every 60 seconds to
+fetch the progress indication until the sanitize is finished. When this
+option is given this utility will exit "early" as soon as the sanitize
+has commenced. This option and \fI\-\-wait\fR cannot both be given.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print out the usage information then exit.
+.TP
+\fB\-i\fR, \fB\-\-ipl\fR=\fILEN\fR
+set the initialization pattern length to \fILEN\fR bytes. By default it is
+set to the length of the pattern file (\fIPF\fR). Only active when the
+\fI\-\-overwrite\fR option is also given. It is the number of bytes from
+the \fIPF\fR file that will be used as the initialization pattern. The
+minimum size is 1 byte and the maximum is the logical block size of the
+\fIDEVICE\fR (and not to exceed 65535). If \fILEN\fR exceeds the \fIPF\fR
+file size then the initialization pattern is padded with zeros.
+.TP
+\fB\-I\fR, \fB\-\-invert\fR
+set the INVERT bit in the overwrite service action parameter list. This
+only affects the "overwrite" sanitize operation. The default is a clear
+INVERT bit. When the INVERT bit is set then the initialization pattern
+is inverted between consecutive overwrite passes.
+.TP
+\fB\-O\fR, \fB\-\-overwrite\fR
+perform an "overwrite" sanitize operation. When this option is given
+then the \fI\-\-pattern=PF\fR option is required.
+.TP
+\fB\-p\fR, \fB\-\-pattern\fR=\fIPF\fR
+where \fIPF\fR is the filename of a file containing the initialization
+pattern required by an "overwrite" sanitize operation. The length of
+this file will be used as the length of the initialization pattern unless
+the \fI\-\-ipl=LEN\fR option is given. The length of the initialization
+pattern must be from 1 to the logical block size of the \fIDEVICE\fR.
+.TP
+\fB\-Q\fR, \fB\-\-quick\fR
+the default action (i.e. when the option is not given) is to give the user
+15 seconds to reconsider doing a sanitize operation on the \fIDEVICE\fR.
+When this option is given that step (i.e. the 15 second warning period)
+is skipped.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+increase the level of verbosity, (i.e. debug output).
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+print the version string and then exit.
+.TP
+\fB\-w\fR, \fB\-\-wait\fR
+the default action (i.e. without this option and the \fI\-\-early\fR option)
+is to start the SANITIZE command with the IMMED bit set then poll for the
+progress indication with the REQUEST SENSE command until the sanitize
+operation is complete (or fails). When this option is given (and the
+\fI\-\-early\fR option is not given) then the SANITIZE command is started
+with the IMMED bit clear. For a large disk this might take hours. [A
+cryptographic erase operation could potentially be very quick.]
+.SH NOTES
+The SCSI SANITIZE command is closely related to the ATA SANITIZE command,
+both are relatively new with the ATA command being the first one defined.
+It is likely that a SCSI to ATA Translation (SAT) definition will soon
+appear for the SCSI SANITIZE command (most likely in SAT\-3).
+.PP
+The SCSI SANITIZE command is related to the SCSI FORMAT UNIT command. It
+is likely that a block erase sanitize operation would take a similar
+amount of time as a format on the same disk (e.g. 9 hours for a 2 Terabyte
+disk). The primary goal of a format is the configuration of the disk at
+the end of a format (e.g. different logical block size or protection
+information added). Removal of user data is only a side effect of a format.
+With the SCSI SANITIZE command, removal of user data is the primary goal.
+If a sanitize operation is interrupted (e.g. the disk is power cycled)
+then after power up any remaining user data will not be available and the
+sanitize operation will continue. When a format is interrupted (e.g. the
+disk is power cycled) the drafts say very little about the state of the
+disk. In practice some of the original user data may remain and the format
+may need to be restarted.
+.SH EXAMPLES
+These examples use Linux device names. For suitable device names in
+other supported Operating Systems see the sg3_utils(8) man page.
+.PP
+As a precaution if this utility is called with no options then apart from
+printing a usage message, nothing happens:
+.PP
+ sg_sanitize /dev/sdm
+.PP
+To do a "block erase" sanitize the \fI\-\-block\fR option is required.
+The user will be given a 15 second period to reconsider, the SCSI SANITIZE
+command will be started with the IMMED bit set, then this utility will
+poll for a progress indication with a REQUEST SENSE command until the
+sanitize operation is finished:
+.PP
+ sg_sanitize \-\-block /dev/sdm
+.PP
+To start a "block erase" sanitize and return from this utility once it is
+started (but not yet completed) use the \fI\-\-early\fR option:
+.PP
+ sg_sanitize \-\-block \-\-early /dev/sdm
+.PP
+If the 15 second reconsideration time is not required add the
+\fI\-\-quick\fR option:
+.PP
+ sg_sanitize \-\-block \-\-quick \-\-early /dev/sdm
+.PP
+To do an "overwrite" sanitize a pattern file is required:
+.PP
+ sg_sanitize \-\-overwrite \-\-pattern=rand.img /dev/sdm
+.PP
+If the length of that "rand.img" is 512 bytes (a typically logical block
+size) then to use only the first 17 bytes (repeatedly) in the "overwrite"
+sanitize operation:
+.PP
+ sg_sanitize \-\-overwrite \-\-pattern=rand.img \-\-ipl=17 /dev/sdm
+.PP
+.SH EXIT STATUS
+The exit status of sg_sanitize is 0 when it is successful. Otherwise see
+the sg3_utils(8) man page. Unless the \fI\-\-wait\fR option is given, the
+exit status may not reflect the success of otherwise of the format.
+.SH AUTHORS
+Written by Douglas Gilbert.
+.SH "REPORTING BUGS"
+Report bugs to <dgilbert at interlog dot com>.
+.SH COPYRIGHT
+Copyright \(co 2011 Douglas Gilbert
+.br
+This software is distributed under a FreeBSD license. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.SH "SEE ALSO"
+.B sg_requests(8), sg_format(8)
diff --git a/src/Makefile.am b/src/Makefile.am
index b45ff5e1..bf4425cd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,10 +13,11 @@ bin_PROGRAMS = \
sg_map sgm_dd sg_modes sg_opcodes sgp_dd sg_persist sg_prevent \
sg_raw sg_rbuf sg_rdac sg_read sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals \
- sg_requests sg_reset sg_rmsn sg_rtpg sg_safte sg_sat_identify \
- sg_sat_phy_event sg_sat_set_features sg_scan sg_senddiag sg_ses \
- sg_start sg_stpg sg_sync sg_test_rwbuf sg_turs sg_unmap sg_verify \
- sg_vpd sg_write_buffer sg_write_long sg_write_same sg_wr_mode
+ sg_requests sg_reset sg_rmsn sg_rtpg sg_safte sg_sanitize \
+ sg_sat_identify sg_sat_phy_event sg_sat_set_features sg_scan \
+ sg_senddiag sg_ses sg_start sg_stpg sg_sync sg_test_rwbuf sg_turs \
+ sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long \
+ sg_write_same sg_wr_mode
distclean-local:
rm -f sg_scan.c
@@ -34,10 +35,10 @@ bin_PROGRAMS = \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
- sg_rmsn sg_rtpg sg_safte sg_sat_identify sg_sat_phy_event \
- sg_sat_set_features sg_scan sg_senddiag sg_ses sg_start sg_stpg \
- sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
- sg_write_long sg_write_same sg_wr_mode
+ sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \
+ sg_sat_phy_event sg_sat_set_features sg_scan sg_senddiag sg_ses \
+ sg_start sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd \
+ sg_write_buffer sg_write_long sg_write_same sg_wr_mode
distclean-local:
rm -f sg_scan.c
@@ -55,10 +56,10 @@ bin_PROGRAMS = \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
- sg_rmsn sg_rtpg sg_safte sg_sat_identify sg_sat_phy_event \
- sg_sat_set_features sg_scan sg_senddiag sg_ses sg_start sg_stpg \
- sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
- sg_write_long sg_write_same sg_wr_mode
+ sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \
+ sg_sat_phy_event sg_sat_set_features sg_scan sg_senddiag sg_ses \
+ sg_start sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd \
+ sg_write_buffer sg_write_long sg_write_same sg_wr_mode
distclean-local:
rm -f sg_scan.c
@@ -76,9 +77,9 @@ bin_PROGRAMS = \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
- sg_rmsn sg_rtpg sg_safte sg_sat_identify sg_sat_phy_event \
- sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg \
- sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
+ sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \
+ sg_sat_phy_event sg_sat_set_features sg_senddiag sg_ses sg_start \
+ sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
sg_write_long sg_write_same sg_wr_mode
endif
@@ -91,9 +92,9 @@ bin_PROGRAMS = \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
- sg_rmsn sg_rtpg sg_safte sg_sat_identify sg_sat_phy_event \
- sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg \
- sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
+ sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \
+ sg_sat_phy_event sg_sat_set_features sg_senddiag sg_ses sg_start \
+ sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
sg_write_long sg_write_same sg_wr_mode
endif
@@ -106,9 +107,9 @@ bin_PROGRAMS = \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
- sg_rmsn sg_rtpg sg_safte sg_sat_identify sg_sat_phy_event \
- sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg \
- sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
+ sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \
+ sg_sat_phy_event sg_sat_set_features sg_senddiag sg_ses sg_start \
+ sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \
sg_write_long sg_write_same sg_wr_mode
endif
@@ -219,6 +220,9 @@ sg_rtpg_LDADD = ../lib/libsgutils2.la @os_libs@
sg_safte_SOURCES = sg_safte.c
sg_safte_LDADD = ../lib/libsgutils2.la @os_libs@
+sg_sanitize_SOURCES = sg_sanitize.c
+sg_sanitize_LDADD = ../lib/libsgutils2.la @os_libs@
+
sg_sat_identify_SOURCES = sg_sat_identify.c
sg_sat_identify_LDADD = ../lib/libsgutils2.la @os_libs@
diff --git a/src/Makefile.in b/src/Makefile.in
index 8bd80843..264e975b 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -58,6 +58,7 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_rtpg$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_safte$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_sanitize$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_sat_phy_event$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_sat_set_features$(EXEEXT) \
@@ -99,6 +100,7 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_rtpg$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_safte$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_sanitize$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_sat_phy_event$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_sat_set_features$(EXEEXT) \
@@ -140,6 +142,7 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_rtpg$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_safte$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_sanitize$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_sat_phy_event$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_sat_set_features$(EXEEXT) \
@@ -180,6 +183,7 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_rtpg$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_safte$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_sanitize$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_sat_phy_event$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_sat_set_features$(EXEEXT) \
@@ -230,6 +234,7 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_rtpg$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_safte$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_sanitize$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_sat_phy_event$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_sat_set_features$(EXEEXT) \
@@ -261,7 +266,7 @@ host_triplet = @host@
@OS_FREEBSD_TRUE@ sg_reassign$(EXEEXT) sg_referrals$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_requests$(EXEEXT) sg_rmsn$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_rtpg$(EXEEXT) sg_safte$(EXEEXT) \
-@OS_FREEBSD_TRUE@ sg_sat_identify$(EXEEXT) \
+@OS_FREEBSD_TRUE@ sg_sanitize$(EXEEXT) sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_sat_phy_event$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_senddiag$(EXEEXT) sg_ses$(EXEEXT) \
@@ -376,6 +381,9 @@ sg_rtpg_DEPENDENCIES = ../lib/libsgutils2.la
am_sg_safte_OBJECTS = sg_safte.$(OBJEXT)
sg_safte_OBJECTS = $(am_sg_safte_OBJECTS)
sg_safte_DEPENDENCIES = ../lib/libsgutils2.la
+am_sg_sanitize_OBJECTS = sg_sanitize.$(OBJEXT)
+sg_sanitize_OBJECTS = $(am_sg_sanitize_OBJECTS)
+sg_sanitize_DEPENDENCIES = ../lib/libsgutils2.la
am_sg_sat_identify_OBJECTS = sg_sat_identify.$(OBJEXT)
sg_sat_identify_OBJECTS = $(am_sg_sat_identify_OBJECTS)
sg_sat_identify_DEPENDENCIES = ../lib/libsgutils2.la
@@ -464,7 +472,7 @@ SOURCES = $(sg_dd_SOURCES) $(sg_decode_sense_SOURCES) \
$(sg_read_long_SOURCES) $(sg_readcap_SOURCES) \
$(sg_reassign_SOURCES) $(sg_referrals_SOURCES) \
$(sg_requests_SOURCES) $(sg_reset_SOURCES) $(sg_rmsn_SOURCES) \
- $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) \
+ $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) $(sg_sanitize_SOURCES) \
$(sg_sat_identify_SOURCES) $(sg_sat_phy_event_SOURCES) \
$(sg_sat_set_features_SOURCES) $(sg_scan_SOURCES) \
$(sg_senddiag_SOURCES) $(sg_ses_SOURCES) $(sg_start_SOURCES) \
@@ -486,7 +494,7 @@ DIST_SOURCES = $(sg_dd_SOURCES) $(sg_decode_sense_SOURCES) \
$(sg_read_long_SOURCES) $(sg_readcap_SOURCES) \
$(sg_reassign_SOURCES) $(sg_referrals_SOURCES) \
$(sg_requests_SOURCES) $(sg_reset_SOURCES) $(sg_rmsn_SOURCES) \
- $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) \
+ $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) $(sg_sanitize_SOURCES) \
$(sg_sat_identify_SOURCES) $(sg_sat_phy_event_SOURCES) \
$(sg_sat_set_features_SOURCES) $(sg_scan_SOURCES) \
$(sg_senddiag_SOURCES) $(sg_ses_SOURCES) $(sg_start_SOURCES) \
@@ -683,6 +691,8 @@ sg_rtpg_SOURCES = sg_rtpg.c
sg_rtpg_LDADD = ../lib/libsgutils2.la @os_libs@
sg_safte_SOURCES = sg_safte.c
sg_safte_LDADD = ../lib/libsgutils2.la @os_libs@
+sg_sanitize_SOURCES = sg_sanitize.c
+sg_sanitize_LDADD = ../lib/libsgutils2.la @os_libs@
sg_sat_identify_SOURCES = sg_sat_identify.c
sg_sat_identify_LDADD = ../lib/libsgutils2.la @os_libs@
sg_sat_phy_event_SOURCES = sg_sat_phy_event.c
@@ -889,6 +899,9 @@ sg_rtpg$(EXEEXT): $(sg_rtpg_OBJECTS) $(sg_rtpg_DEPENDENCIES)
sg_safte$(EXEEXT): $(sg_safte_OBJECTS) $(sg_safte_DEPENDENCIES)
@rm -f sg_safte$(EXEEXT)
$(LINK) $(sg_safte_OBJECTS) $(sg_safte_LDADD) $(LIBS)
+sg_sanitize$(EXEEXT): $(sg_sanitize_OBJECTS) $(sg_sanitize_DEPENDENCIES)
+ @rm -f sg_sanitize$(EXEEXT)
+ $(LINK) $(sg_sanitize_OBJECTS) $(sg_sanitize_LDADD) $(LIBS)
sg_sat_identify$(EXEEXT): $(sg_sat_identify_OBJECTS) $(sg_sat_identify_DEPENDENCIES)
@rm -f sg_sat_identify$(EXEEXT)
$(LINK) $(sg_sat_identify_OBJECTS) $(sg_sat_identify_LDADD) $(LIBS)
@@ -991,6 +1004,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rmsn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rtpg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_safte.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_sanitize.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_sat_identify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_sat_phy_event.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_sat_set_features.Po@am__quote@
diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c
new file mode 100644
index 00000000..fc6b68f5
--- /dev/null
+++ b/src/sg_sanitize.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.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_pt.h"
+#include "sg_cmds_basic.h"
+#include "sg_cmds_extra.h"
+
+static char * version_str = "0.90 20110622";
+
+/* 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_sanitize: "
+
+#define SANITIZE_OP 0x48
+#define SANITIZE_OP_LEN 10
+#define DEF_REQS_RESP_LEN 252
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
+#define MAX_XFER_LEN 65535
+#define EBUFF_SZ 256
+
+#define SHORT_TIMEOUT 20 /* 20 seconds unless immed=0 ... */
+#define LONG_TIMEOUT (15 * 3600) /* 15 hours ! */
+ /* Seagate ST32000444SS 2TB disk takes 9.5 hours to format */
+#define POLL_DURATION_SECS 60
+
+
+static struct option long_options[] = {
+ {"block", no_argument, 0, 'B'},
+ {"count", required_argument, 0, 'c'},
+ {"crypto", no_argument, 0, 'C'},
+ {"early", no_argument, 0, 'e'},
+ {"help", no_argument, 0, 'h'},
+ {"invert", no_argument, 0, 'I'},
+ {"ipl", required_argument, 0, 'i'},
+ {"overwrite", no_argument, 0, 'O'},
+ {"pattern", required_argument, 0, 'p'},
+ {"quick", no_argument, 0, 'Q'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {"wait", no_argument, 0, 'w'},
+ {0, 0, 0, 0},
+};
+
+struct opts_t {
+ int block;
+ int count;
+ int crypto;
+ int early;
+ int invert;
+ int ipl; /* initialization pattern length */
+ int overwrite;
+ int quick;
+ int verbose;
+ int wait;
+ const char * pattern_fn;
+};
+
+
+
+static void
+usage()
+{
+ fprintf(stderr, "Usage: "
+ "sg_sanitize [--block] [--count=OC] [--crypto] [--early] "
+ "[--help]\n"
+ " [--invert] [--ipl=LEN] [--overwrite] "
+ "[--pattern=PF]\n"
+ " [--quick] [--verbose] [--version] [--wait] "
+ "DEVICE\n"
+ " where:\n"
+ " --block|-B do BLOCK ERASE sanitize\n"
+ " --count=OC|-c OC OC is overwrite count field (from 1 "
+ "(def) to 31)\n"
+ " --crypto|-C do CRYPTOGRAPHIC ERASE sanitize\n"
+ " --early|-e exit once sanitize started (IMMED set "
+ "in cdb)\n"
+ " user can monitor progress with REQUEST "
+ "SENSE\n"
+ " --help|-h print out usage message\n"
+ " --invert|-I set INVERT bit in OVERWRITE parameter "
+ "list\n"
+ " --ipl=LEN|-i LEN initialization pattern length (in "
+ "bytes)\n"
+ " --overwrite|-O do OVERWRITE sanitize\n"
+ " --pattern=PF|-p PF PF is file containing initialization "
+ "pattern\n"
+ " for OVERWRITE\n"
+ " --quick|-Q start sanitize without pause for user\n"
+ " intervention (i.e. no time to "
+ "reconsider)\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string then exit\n"
+ " --wait|-w wait for command to finish (could "
+ "take hours)\n\n"
+ "Performs a SCSI SANITIZE command.\n <<<WARNING>>>: all data "
+ "on DEVICE will lost.\nDefault action is to give user time to "
+ "reconsider; then execute SANITIZE\ncommand with IMMED bit set; "
+ "then use REQUEST SENSE command every 60\nseconds to poll for a "
+ "progress indication; then exit when there is no\nmore progress "
+ "indication.\n"
+ );
+}
+
+/* Invoke SCSI SANITIZE command. Returns 0 if successful, otherwise error */
+static int
+do_sanitize(int sg_fd, const struct opts_t * op, const void * param_lstp,
+ int param_lst_len)
+{
+ int k, ret, res, sense_cat, immed;
+ unsigned char sanCmdBlk[SANITIZE_OP_LEN];
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ struct sg_pt_base * ptvp;
+
+ if (op->early || op->wait)
+ immed = op->early ? 1 : 0;
+ else
+ immed = 1;
+ memset(sanCmdBlk, 0, sizeof(sanCmdBlk));
+ sanCmdBlk[0] = SANITIZE_OP;
+ if (op->overwrite)
+ sanCmdBlk[1] = 1;
+ else if (op->block)
+ sanCmdBlk[1] = 2;
+ else if (op->crypto)
+ sanCmdBlk[1] = 3;
+ else
+ return SG_LIB_SYNTAX_ERROR;
+ if (immed)
+ sanCmdBlk[1] |= 0x80;
+ sanCmdBlk[7] = ((param_lst_len >> 8) & 0xff);
+ sanCmdBlk[8] = (param_lst_len & 0xff);
+
+ if (op->verbose > 1) {
+ fprintf(stderr, " Sanitize cmd: ");
+ for (k = 0; k < SANITIZE_OP_LEN; ++k)
+ fprintf(stderr, "%02x ", sanCmdBlk[k]);
+ }
+ if ((op->verbose > 2) && (param_lst_len > 0)) {
+ fprintf(stderr, " Parameter list contents:\n");
+ dStrHex((const char *)param_lstp, param_lst_len, 1);
+ }
+ ptvp = construct_scsi_pt_obj();
+ if (NULL == ptvp) {
+ fprintf(sg_warnings_strm, "Sanitize: out of memory\n");
+ return -1;
+ }
+ set_scsi_pt_cdb(ptvp, sanCmdBlk, sizeof(sanCmdBlk));
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ set_scsi_pt_data_out(ptvp, (unsigned char *)param_lstp, param_lst_len);
+ res = do_scsi_pt(ptvp, sg_fd, (immed ? SHORT_TIMEOUT : LONG_TIMEOUT),
+ op->verbose);
+ ret = sg_cmds_process_resp(ptvp, "Sanitize", res, 0, sense_b,
+ 1 /*noisy */, op->verbose, &sense_cat);
+ if (-1 == ret)
+ ;
+ else if (-2 == ret) {
+ switch (sense_cat) {
+ case SG_LIB_CAT_NOT_READY:
+ case SG_LIB_CAT_UNIT_ATTENTION:
+ case SG_LIB_CAT_INVALID_OP:
+ case SG_LIB_CAT_ILLEGAL_REQ:
+ case SG_LIB_CAT_ABORTED_COMMAND:
+ ret = sense_cat;
+ break;
+ case SG_LIB_CAT_RECOVERED:
+ case SG_LIB_CAT_NO_SENSE:
+ ret = 0;
+ break;
+ case SG_LIB_CAT_MEDIUM_HARD:
+ {
+ int valid, slen;
+ uint64_t ull = 0;
+
+ slen = get_scsi_pt_sense_len(ptvp);
+ valid = sg_get_sense_info_fld(sense_b, slen, &ull);
+ if (valid)
+ fprintf(stderr, "Medium or hardware error starting at "
+ "lba=%"PRIu64" [0x%"PRIx64"]\n", ull, ull);
+ }
+ ret = sense_cat;
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ } else
+ ret = 0;
+
+ destruct_scsi_pt_obj(ptvp);
+ return ret;
+}
+
+
+int
+main(int argc, char * argv[])
+{
+ int sg_fd, k, res, c, infd, progress, vb, n, desc, resp_len;
+ int got_stdin = 0;
+ int param_lst_len = 0;
+ const char * device_name = NULL;
+ char ebuff[EBUFF_SZ];
+ char pdt_name[32];
+ unsigned char requestSenseBuff[DEF_REQS_RESP_LEN];
+ unsigned char * wBuff = NULL;
+ int ret = -1;
+ struct opts_t opts;
+ struct stat a_stat;
+ struct sg_simple_inquiry_resp inq_out;
+
+ memset(&opts, 0, sizeof(opts));
+ opts.count = 1;
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "Bc:Cehi:IOp:QvVw", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ ++opts.block;
+ break;
+ case 'c':
+ opts.count = sg_get_num(optarg);
+ if ((opts.count < 1) || (opts.count > 31)) {
+ fprintf(stderr, "bad argument to '--count', expect 1 to "
+ "31\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
+ case 'C':
+ ++opts.crypto;
+ break;
+ case 'e':
+ ++opts.early;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'i':
+ opts.ipl = sg_get_num(optarg);
+ if ((opts.ipl < 1) || (opts.ipl > 65535)) {
+ fprintf(stderr, "bad argument to '--ipl', expect 1 to "
+ "65535\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
+ case 'I':
+ ++opts.invert;
+ break;
+ case 'O':
+ ++opts.overwrite;
+ break;
+ case 'p':
+ opts.pattern_fn = optarg;
+ break;
+ case 'Q':
+ ++opts.quick;
+ break;
+ case 'v':
+ ++opts.verbose;
+ break;
+ case 'V':
+ fprintf(stderr, ME "version: %s\n", version_str);
+ return 0;
+ case 'w':
+ ++opts.wait;
+ break;
+ default:
+ fprintf(stderr, "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)
+ fprintf(stderr, "Unexpected extra argument: %s\n",
+ argv[optind]);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+ if (NULL == device_name) {
+ fprintf(stderr, "missing device name!\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ vb = opts.verbose;
+ n = !!opts.block + !!opts.crypto + !!opts.overwrite;
+ if (1 != n) {
+ fprintf(stderr, "one and only one of '--block', '--crypto' or "
+ "'--overwrite' please\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (opts.overwrite) {
+ if (NULL == opts.pattern_fn) {
+ fprintf(stderr, "'--overwrite' requires '--pattern=PF' "
+ "option\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ got_stdin = (0 == strcmp(opts.pattern_fn, "-")) ? 1 : 0;
+ if (! got_stdin) {
+ memset(&a_stat, 0, sizeof(a_stat));
+ if (stat(opts.pattern_fn, &a_stat) < 0) {
+ if (vb)
+ fprintf(stderr, "unable to stat(%s): %s\n",
+ opts.pattern_fn, safe_strerror(errno));
+ return SG_LIB_FILE_ERROR;
+ }
+ if (opts.ipl <= 0) {
+ opts.ipl = (int)a_stat.st_size;
+ if (opts.ipl > MAX_XFER_LEN) {
+ fprintf(stderr, "pattern file length exceeds 65535 "
+ "bytes, need '--ipl=LEN' option\n");
+ return SG_LIB_FILE_ERROR;
+ }
+ }
+ }
+ if (opts.ipl < 1) {
+ fprintf(stderr, "'--overwrite' requires '--ipl=LEN' "
+ "option if can't get PF length\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ }
+
+ sg_fd = sg_cmds_open_device(device_name, 0 /* rw */, vb);
+ if (sg_fd < 0) {
+ fprintf(stderr, ME "open error: %s: %s\n", device_name,
+ safe_strerror(-sg_fd));
+ return SG_LIB_FILE_ERROR;
+ }
+
+ if (sg_simple_inquiry(sg_fd, &inq_out, 1, vb)) {
+ fprintf(stderr, "%s doesn't respond to a SCSI INQUIRY\n",
+ device_name);
+ ret = SG_LIB_CAT_OTHER;
+ goto err_out;
+ }
+ printf(" %.8s %.16s %.4s peripheral_type: %s [0x%x]\n",
+ inq_out.vendor, inq_out.product, inq_out.revision,
+ sg_get_pdt_str(inq_out.peripheral_type, sizeof(pdt_name),
+ pdt_name),
+ inq_out.peripheral_type);
+
+
+ if (opts.overwrite) {
+ param_lst_len = opts.ipl + 4;
+ wBuff = (unsigned char*)calloc(opts.ipl + 4, 1);
+ if (NULL == wBuff) {
+ fprintf(stderr, "unable to allocate %d bytes of memory with "
+ "calloc()\n", opts.ipl + 4);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ if (got_stdin) {
+ infd = STDIN_FILENO;
+ if (sg_set_binary_mode(STDIN_FILENO) < 0)
+ perror("sg_set_binary_mode");
+ } else {
+ if ((infd = open(opts.pattern_fn, O_RDONLY)) < 0) {
+ snprintf(ebuff, EBUFF_SZ,
+ ME "could not open %s for reading", opts.pattern_fn);
+ perror(ebuff);
+ ret = SG_LIB_FILE_ERROR;
+ goto err_out;
+ } else if (sg_set_binary_mode(infd) < 0)
+ perror("sg_set_binary_mode");
+ }
+ res = read(infd, wBuff + 4, opts.ipl);
+ if (res < 0) {
+ snprintf(ebuff, EBUFF_SZ, ME "couldn't read from %s",
+ opts.pattern_fn);
+ perror(ebuff);
+ if (! got_stdin)
+ close(infd);
+ ret = SG_LIB_FILE_ERROR;
+ goto err_out;
+ }
+ if (res < opts.ipl) {
+ fprintf(stderr, "tried to read %d bytes from %s, got %d "
+ "bytes\n", opts.ipl, opts.pattern_fn, res);
+ fprintf(stderr, " so pad with 0x0 bytes and continue\n");
+ }
+ if (! got_stdin)
+ close(infd);
+
+ wBuff[0] = opts.count;
+ if (opts.invert)
+ wBuff[0] |= 0x80;
+ wBuff[2] = ((opts.ipl >> 8) & 0xff);
+ wBuff[3] = (opts.ipl & 0xff);
+ }
+
+ if (0 == opts.quick) {
+ 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);
+ }
+
+ ret = do_sanitize(sg_fd, &opts, wBuff, param_lst_len);
+ if (ret) {
+ switch (ret) {
+ case SG_LIB_CAT_NOT_READY:
+ fprintf(stderr, "Sanitize failed, device not ready\n");
+ break;
+ case SG_LIB_CAT_UNIT_ATTENTION:
+ fprintf(stderr, "Sanitize, unit attention\n");
+ break;
+ case SG_LIB_CAT_ABORTED_COMMAND:
+ fprintf(stderr, "Sanitize, aborted command\n");
+ break;
+ case SG_LIB_CAT_INVALID_OP:
+ fprintf(stderr, "Sanitize command not supported\n");
+ break;
+ case SG_LIB_CAT_ILLEGAL_REQ:
+ fprintf(stderr, "bad field in Sanitize cdb, option "
+ "probably not supported\n");
+ break;
+ case SG_LIB_CAT_MEDIUM_HARD:
+ fprintf(stderr, "Sanitize command reported medium or "
+ "hardware error\n");
+ break;
+ default:
+ fprintf(stderr, "Sanitize command failed\n");
+ break;
+ }
+ }
+
+ if ((0 == ret) && (0 == opts.early) && (0 == opts.wait)) {
+ for (k = 0, desc = 1 ;; ++k) {
+ sleep_for(POLL_DURATION_SECS);
+ memset(requestSenseBuff, 0x0, sizeof(requestSenseBuff));
+ res = sg_ll_request_sense(sg_fd, desc, requestSenseBuff,
+ sizeof(requestSenseBuff), 1, vb);
+ if (res) {
+ ret = res;
+ if (SG_LIB_CAT_INVALID_OP == res)
+ fprintf(stderr, "Request Sense command not supported\n");
+ else if (SG_LIB_CAT_ILLEGAL_REQ == res) {
+ fprintf(stderr, "bad field in Request Sense cdb\n");
+ if (1 == desc) {
+ fprintf(stderr, "Descriptor type sense may not be "
+ "supported, try again with fixed type\n");
+ desc = 0;
+ continue;
+ }
+ }
+ else if (SG_LIB_CAT_ABORTED_COMMAND == res)
+ fprintf(stderr, "Request Sense, aborted command\n");
+ else {
+ fprintf(stderr, "Request Sense command unexpectedly "
+ "failed\n");
+ if (0 == vb)
+ fprintf(stderr, " try the '-v' option for "
+ "more information\n");
+ }
+ break;
+ }
+ /* "Additional sense length" same in descriptor and fixed */
+ resp_len = requestSenseBuff[7] + 8;
+ if (vb > 2) {
+ fprintf(stderr, "Parameter data in hex\n");
+ dStrHex((const char *)requestSenseBuff, resp_len, 1);
+ }
+ progress = -1;
+ sg_get_sense_progress_fld(requestSenseBuff, resp_len,
+ &progress);
+ if (progress < 0) {
+ ret = res;
+ if (vb > 1)
+ fprintf(stderr, "No progress indication found, "
+ "iteration %d\n", k + 1);
+ /* N.B. exits first time there isn't a progress indication */
+ break;
+ } else
+ printf("Progress indication: %d%% done\n",
+ (progress * 100) / 65536);
+ }
+ }
+
+err_out:
+ if (wBuff)
+ free(wBuff);
+ res = sg_cmds_close_device(sg_fd);
+ if (res < 0) {
+ fprintf(stderr, "close error: %s\n", safe_strerror(-res));
+ if (0 == ret)
+ return SG_LIB_FILE_ERROR;
+ }
+ return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+}