Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
DDPT(8)				     DDPT			       DDPT(8)

NAME
       ddpt  -	copies data between files and storage devices. Support for de-
       vices that understand the SCSI command set.

SYNOPSIS
       ddpt [bpt=BPT[,OBPC]] [bs=BS]  [cdbsz=IO_CDBSZ]	[cdl=CDL]  [coe={0|1}]
       [coe_limit=CL] [conv=CONVS] [count=COUNT] [ddpt=VERS] [delay=MS[,W_MS]]
       [ibs=IBS]    [id_usage=LIU]    if=IFILE	 [iflag=FLAGS]	 [intio={0|1}]
       [iseek=SKIP] [ito=ITO] [list_id=LID] [obs=OBS] [of=OFILE]  [of2=OFILE2]
       [oflag=FLAGS]   [oseek=SEEK]   [prio=PRIO]   [protect=RDP[,WRP]]	  [re-
       tries=RETR]  [rtf=RTF]  [rtype=RTYPE]  [seek=SEEK]  [skip=SKIP]	 [sta-
       tus=STAT]  [to=TO]  [verbose=VERB]  [--dry-run]	[--flexible]  [--help]
       [--job=JF]  [--odx]  [--prefetch]  [--progress]	[--quiet]  [--verbose]
       [--verify] [--version] [--wscan]	[--xcopy] [ddpt] [JF]

       For comparison here is the synopsis for GNU's dd	command:

       dd  [bs=BS]  [cbs=CBS]  [conv=CONVS] [count=COUNT] [ibs=IBS] [if=IFILE]
       [iflag=FLAGS]   [obs=OBS]    [of=OFILE]	  [oflag=FLAGS]	   [seek=SEEK]
       [skip=SKIP] [status=STAT] [--help] [--version]

DESCRIPTION
       Copies  data  between  files or simply reads data from a	file. Alterna-
       tively if the --verify option is	given, the IFILE  and  OFILE  contents
       are  compared, stopping if an inequality	is found. This utility is spe-
       cialized	for "files" that are storage devices,  especially  those  that
       can  use	 the SCSI command sets (e.g. SATA and SAS disks). It can issue
       SCSI commands in	pass-through ("pt") mode. Similar syntax and semantics
       to the Unix dd(1) command.

       For comparison, the SYNOPSIS section above shows	both the ddpt  command
       line operands and options followed by GNU's dd(1) command line operands
       and options. Broadly speaking ddpt can be considered a super-set	of dd.
       See  the	 section on DD DIFFERENCES for significant differences between
       ddpt and	dd.

       This utility either does	direct copies, based on	read-write  sequences,
       or  offloaded  copies.  In an offloaded copy the	data being copied does
       not necessarily pass through the	memory of the the machine  originating
       the  copy  operation;  this  can	 save a	significant amount of time and
       lessen CPU usage.

       When doing a direct copy, this utility breaks the  copy	into  segments
       since  computer	RAM  is	typically a scarce resource. First it reads in
       BPT*IBS bytes from IFILE	(or less if near the end of the	copy)  into  a
       copy  buffer.  In the absence of	the various operand and	flags that by-
       pass the	write operation, the copy buffer is then written out to	OFILE.
       The copy	process	continues working its way along	IFILE and OFILE	 until
       either  COUNT is	exhausted, an end of file is detected, or an error oc-
       curs. If	IBS and	OBS are	different, ddpt	restricts  the	value  of  OBS
       such  that the copy buffer is an	integral number	of output blocks (i.e.
       (((IBS *	BPT) % OBS) == 0) ). In	the following descriptions,  "segment"
       refers to all or	part of	a copy buffer.

       The  term  "pt  device" is used for a pass-through device to which SCSI
       commands	like READ(10), WRITE(10) or POPULATE TOKEN may be sent.	 A  pt
       device may only be able to process SCSI commands	in which case the "pt"
       flag  is	 assumed.  The	ability	to recognize such a pt only device may
       vary depending on the operating system  (e.g.  in  Linux	 /dev/sg2  and
       /dev/bsg/3:0:1:0	 are  recognized). However if a	device can process ei-
       ther normal UNIX	read()/	write()	calls or  pass-through	SCSI  commands
       then  the default is to use UNIX	read()/write() calls. That default can
       be overridden by	using the "pt"	flag  (e.g.  "if=/dev/sdc  iflag=pt").
       When  pt	 access	is specified any partition information is ignored.  So
       "if=/dev/sdc2 iflag=pt skip=3" will start at logical block address 3 of
       '/dev/sdc'. As a	protection measure ddpt	will only accept that  if  the
       force flag is also given	(i.e. 'iflag=pt,force').

       This  utility supports two types	of offloaded copies. Both are based on
       the EXTENDED COPY (XCOPY	or xcopy) family of SCSI commands.  The	 first
       uses the	XCOPY(LID1) command to do a disk to disk copy. LID1 stands for
       List  IDentifier	length of 1 byte and the commands are described	in the
       SPC-4 and earlier SPC-3 and SPC-2 standards. The	SPC-4  standard	 (ANSI
       INCITS  513-2015)  added	 the  XCOPY(LID4) sub-family of	copy offloaded
       commands. Now SPC-5 drafts have dropped the LID1	variants  and  removed
       the LID4	suffix on the remaining	XCOPY family of	commands. To differen-
       tiate,  this  man page will continue to use the LID1 and	LID4 suffixes.
       There is	a subset of XCOPY(LID4), specialized  for  offloaded  disk  to
       disk copies, that is known by the market	name: ODX. In the descriptions
       below  "xcopy" refers to	copies based on	XCOPY(LID1) while "odx"	refers
       to either full or partial ODX copies.  See the XCOPY and	 ODX  sections
       below for more information.

       The  syntax  of the dd command is somewhat unique in Unix and ddpt fol-
       lows in a similar fashion. Operands (i.e. those with the	 <name>=<some-
       thing> structure) are shown in OPERANDS section.	The more familiar Unix
       options	(i.e. those starting with one or two hyphens) are shown	in the
       OPTIONS section.	Then there are a few arguments which are command  line
       entities	 that are neither operands nor options,	see the	ARGUMENTS sec-
       tion.

OPERANDS
       The operands are	listed alphabetically (by <name>) below. The <name> is
       the part	that is	to the left of the equal sign. All <names> start  with
       a lower case alphabetical character.

       bpt=BPT[,OBPC]
	      where  BPT  is  Blocks Per Transfer. A direct copy is made up of
	      multiple transfers, each first reading BPT  input	 blocks	 (i.e.
	      BPT  *  IBS bytes) from IFILE into the copy buffer and then from
	      that copy	buffer writing (BPT * IBS)  /  OBS  output  blocks  to
	      OFILE.  This continues until the copy is finished, with the last
	      transfer being potentially shorter. The default BPT value	varies
	      depending	on IBS.	When IBS < 8, BPT is 8192; when	IBS < 64,  BPT
	      is  1024;	 when  IBS < 1024, BPT is 128; when IBS	< 8192,	BPT is
	      16; when IBS < 32768, BPT	is 4; else BPT defaults	to 1.  If  BPT
	      is given as 0 it is treated as the default value.	 For "bs=512",
	      BPT  defaults to 128 so that 64 KiB (or less) is read from IFILE
	      into the copy buffer. This operand is treated differently	in ODX
	      and is typically only needed for testing;	see ODX	section.
	      The optional OBPC	(Output	Blocks Per  Check)  argument  controls
	      the granularity of sparse	writes,	write sparing and trim checks.
	      The default granularity is the size of the copy buffer (i.e. BPT
	      *	IBS bytes). That can be	reduced	by specifying OBPC. The	finest
	      granularity  is  when  OBPC  is 1	which implies the unit of each
	      check is OBS bytes.  When	OBPC is	0, or not given,  the  default
	      granularity  is used. Large OBPC values are rounded down so that
	      OBPC*OBS does not	exceed the size	of the copy buffer.
	      odx: may be used to limit	the  data  represented	by  each  ROD.
	      Mainly for testing.
	      If BPT is	too large on Linux, the	obscure	"Invalid argument" er-
	      ror value	(EINVAL) is returned.

       bs=BS  where  BS	is the IFILE and OFILE block size in bytes.  Conflicts
	      with either the "ibs=" or	"obs=" operands. The value  of	BS  is
	      placed  in IBS and OBS.  If IFILE	or OFILE is a "pt" device then
	      BS must be the logical block size	of the device. See the DD DIF-
	      FERENCES section below. The default is 512 bytes unless overrid-
	      den by the DDPT_DEF_BS environment  variable.  Note  that	 newer
	      disks  use 4096 byte blocks with perhaps larger block sizes com-
	      ing in the future. CD/DVD/BD media use a logical block  size  of
	      2048 bytes.

       cdbsz=IO_CDBSZ
	      size  of	SCSI  READ  and/or  WRITE  (VERIFY) command descriptor
	      blocks (cdb) in bytes. IO_CDBSZ may be one number	or two numbers
	      separated	by a comma.  The acceptable numbers are	0, 6, 10,  12,
	      16 or 32.	The default 0 will usually be set to 10	internally un-
	      less  the	 (first	 and last) LBAs	cannot fit in 32 bits in which
	      case the 16 byte variant of each command is used.	If one	number
	      is  given	it applies both	to the IFILE and IFILE.	If two numbers
	      are given, the first applies to the IFILE	(i.e.  the  READ  com-
	      mand) and	the second applies to the OFILE.
	      If  IFILE	 or  OFILE  is not a SCSI pass-through device then the
	      corresponding IO_CDBSZ value is ignored.

       cdl=CDL
	      allows setting of	command	duration limits. CDL is	either a  sin-
	      gle  value  or  two values separated by a	comma. If one value is
	      given,  it  applies  to  both  IFILE  and	 OFILE	(if  they  are
	      pass-through  devices).  If  two values are given, the first ap-
	      plies to IFILE while the second applies to OFILE.	The value  may
	      be  from	0  to  7 where 0 is the	default	and means there	are no
	      command duration limits. Command duration	limits are  only  sup-
	      ported  by 16 and	32 byte	READ and WRITE commands	(and the WRITE
	      SCATTERED	command	which is not used by  this  utility).  If  the
	      cdbsz  operand is	not given and would have a value less than 16,
	      then if CDL is greater than 0, the cdbsz is increased to 16.
	      Command duration limits can be accesses and changed in the  Com-
	      mand  duration  limit A and B mode pages,	plus the Command dura-
	      tion limit T2A and T2B mode pages. The  sdparm  utility  may  be
	      used to access and change	these mode pages.

       coe={0|1}
	      set  to  1 for continue on error.	Applies	to errors on input and
	      output for pt devices but	only on	input from  block  devices  or
	      regular  files. Errors on	other files will stop ddpt. Default is
	      0	which implies stop on any error. See the 'coe' flag  for  more
	      information.

       coe_limit=CL
	      where CL is the maximum number of	consecutive bad	blocks stepped
	      over due to "coe=1" on reads before the copy terminates. The de-
	      fault  is	 0 which is implies no limit. This operand is meant to
	      stop the copy soon after	unrecorded  media  is  detected	 while
	      still  offering  "continue  on error" capability for infrequent,
	      randomly distributed errors.

       conv=CONVS
	      see the CONVERSIONS section below.

       count=COUNT
	      copy COUNT input blocks from IFILE to OFILE. If this operand  is
	      not  given (or COUNT is '-1') then the COUNT may be deduced from
	      either IFILE or OFILE. See the COUNT section below.
	      If a 'hard' gather list is given to skip=SKIP or a 'hard'	 scat-
	      ter list is given	to seek=SEEK then typically count=COUNT	should
	      not  be  supplied.  This is because a 'hard' scatter gather list
	      implies a	transfer count.	If both	are given then ddpt will  exit
	      if they are unequal, the force flag can be used to override this
	      action. See the SCATTER GATHER LISTS section below for a discus-
	      sion of 'hard' and 'soft'	scatter	gather lists.

       ddpt=VERS
	      causes a syntax error while parsing the command line if the cur-
	      rent  version  of	 the  ddpt utility is less than	VERS. VERS can
	      take one of two forms: starting with a digit in  which  case  is
	      should  have  the	 form "<major_vn>.<minor_vn>" or starting with
	      the letter "r" followed by "<svn.rev>". The latter case  is  the
	      subversion  revision  number.  Both  numbers can be found	in the
	      output of	the --version option. The purpose of this  operand  is
	      to be placed in job files	so that	they are not run on older ver-
	      sions of this utility

       delay=MS[,W_MS]
	      after each segment is copied (typically every (IBS * BPT)	bytes)
	      a	 delay	(sleep)	 of  MS	milliseconds is	performed. The default
	      value for	MS is 0	which implies no delay.	If W_MS	is  given  and
	      greater  than  0 (its default value) then	there is an additional
	      delay of W_MS milliseconds associated with each actual write op-
	      eration that is performed.  If MS	is greater than	0  then	 there
	      is  not  a  delay	 before	 the  first copy segment (or after the
	      last); if	W_MS is	greater	than 0 then there is not a  delay  be-
	      fore  the	 first	write  segment.	These delays can be used for a
	      bandwidth	limiting.
	      odx: the MS delay	is implemented in the same fashion after  each
	      ROD  is  copied,	apart from the last. If	W_MS is	greater	than 0
	      then that	delay occurs before each WUT command, apart  from  the
	      first.

       ibs=IBS
	      where IBS	is the IFILE block size	in bytes. The default value is
	      BS  or its default (512).	Conflicts the "bs=" operand (i.e. giv-
	      ing both "bs=512 ibs=512"	is considered a	syntax error).

       id_usage=LIU
	      xcopy: SCSI EXTENDED COPY	parameter list LIST ID USAGE field  is
	      set  to  LIU.  The default value is 0 or 2 . LIU can be a	number
	      between 0	and 3 inclusive	or a string. The strings  can  be  ei-
	      ther: 'hold' for 0, 'discard' for	2 or 'disable' for 3.

       if=IFILE
	      read  from  IFILE.  If  IFILE  is	'-' then stdin is read.	Starts
	      reading at the beginning of IFILE	unless SKIP is given.
	      This operand must	be given (apart	from one  odx  case  and  when
	      iflag=00 or iflag=ff is given).
	      odx: the rtf=RTF operand may replace the if=IFILE	operand	as in-
	      put. See the ODX section.

       iflag=FLAGS
	      where  FLAGS is a	comma separated	list of	one or more flags out-
	      lined in the FLAGS section below.	 These	flags  are  associated
	      with IFILE and are mostly	ignored	when IFILE is stdin.

       intio={0|1}
	      set to 1 for allow signals (SIGINT, SIGPIPE and SIGUSR1 (or SIG-
	      INFO))  to  be  received	during IO from IFILE or	IO to OFILE or
	      OFILE2.  Default is 0 which causes these signals	to  be	masked
	      during  IO operations with a check for signals prior each	IO. As
	      long as IO operations don't lock up (e.g.	SCSI  READ  and	 WRITE
	      commands)	the default is the safer option. Even if IO operations
	      do lock up it is best to let the kernel take care	of that.

       iseek=SKIP
	      in its simplest form, SKIP is a single number: start reading af-
	      ter  SKIP	 blocks	 (each	of IBS bytes) from the start of	IFILE.
	      Default is block 0 (i.e. start of	file). This operand is a  syn-
	      onym for skip=SKIP, see its description.

       ito=ITO
	      odx:  ITO	is the inactivity timeout whose	units are seconds. The
	      default value is 0 which means the copy manager  will  take  the
	      default inactivity timeout value from the	Block Device ROD Token
	      Limits  descriptor  in the Third Party Copy VPD page. ITO	is ig-
	      nored if it it exceeds the maximum inactivity timeout  value  in
	      the same descriptor (unless the force flag is given).

       list_id=LID
	      LID  is  the xcopy LIST IDENTIFIER field or the STR_ID field for
	      the WRITE	STREAM command.	Fo xcopy it is used  to	 associate  an
	      originating  xcopy  command  with	follow-up commands such	as RE-
	      CEIVE ROD	TOKEN INFORMATION. If given, the LID should not	 clash
	      with any other xcopy LID currently in use	on this	I_T nexus.
	      xcopy:  LID  is  a 1 byte	(8 bit)	value whose default value is 1
	      or, if id_usage=disable, 0 . LID must not	exceed 255.
	      odx: LID is a 4 byte (32 bit) value whose	default	value  is  257
	      (i.e.  0x101) and, if a second default is	needed,	258 (0x102) is
	      used.  If	 a  clash  is  detected	on the default list identifier
	      value then the next higher value is tried	(stopping after	10 at-
	      tempts).
	      oflag=wstream: LID is a 2	byte  (16  bit)	 value	whose  default
	      value  is	 0. It is the Stream Identifier	(STR_ID	field) for the
	      WRITE STREAM(16) command.	Valid Stream identifiers  are  0x1  to
	      0xffff (65535) inclusive,	so the default value of	0 is invalid.

       obs=OBS
	      where OBS	is the OFILE block size	in bytes. The default value is
	      BS  or its default (512).	Conflicts the "bs=" operand (e.g. giv-
	      ing both "bs=512 obs=512"	is considered a	syntax error).	If OBS
	      is given then it has the following restriction: the integer  ex-
	      pression	(((IBS	*  BPT)	% OBS) == 0) must be true.  Stated an-
	      other way: the copy buffer size must be an integral multiple  of
	      OBS. If of2=OFILE2 is given then OBS is its block	size as	well.

       of=OFILE
	      write to OFILE. The default value	is /dev/null . If OFILE	is '-'
	      then  writes  to	stdout.	 If  OFILE is /dev/null	then no	actual
	      writes are performed. If	OFILE  is  '.'	(period)  then	it  is
	      treated  the  same way as	/dev/null . If OFILE exists then it is
	      _not_ truncated unless "oflag=trunc" is given. See section on DD
	      DIFFERENCES.
	      odx: if this operand (of=OFILE) is not  given  and  the  rtf=RTF
	      operand  is given	then the RTF file may be thought of as receiv-
	      ing the output in	the form of one	or more	ROD  Tokens.  See  the
	      ODX section.

       of2=OFILE2
	      write output to OFILE2. The default action is not	to do this ad-
	      ditional	write (i.e. when this operand is not given). OFILE2 is
	      assumed to be a regular file or a	 fifo  (i.e.  a	 named	pipe).
	      OFILE2  is  opened  for  writing and is created if necessary. If
	      OFILE2 is	a fifo (named pipe) then some other command should  be
	      consuming	that data (e.g.	'md5sum	OFILE2'), otherwise this util-
	      ity  will	 block.	The write to OFILE2 occurs before the write to
	      OFILE and	prior to sparse	writing	and write  sparing  logic.  So
	      everything read is written to OFILE2.
	      OFILE2 is	not truncated before writing. Assuming that the	OFILE2
	      length  is  shorter than what is written (or it is created) then
	      its contents should be the concatenation of all  segments	 (each
	      of  ibs*bpt  bytes  long,	 with  the last	segment	being possibly
	      shorter).	The gather list	given to  skip=SKIP  effects  what  is
	      read  into each segment so it indirectly effects what is written
	      to OFILE2. However the scatter list given	to  seek=SEEK  has  no
	      effect on	what is	written	to OFILE2.

       oflag=FLAGS
	      where  FLAGS is a	comma separated	list of	one or more flags out-
	      lined in the FLAGS section.  These  flags	 are  associated  with
	      OFILE  and are ignored when OFILE	is /dev/null, '.' (period), or
	      stdout.

       oseek=SEEK
	      start writing SEEK blocks	(each of OBS bytes) from the start  of
	      OFILE.  Default is block 0 (i.e. start of	file). This operand is
	      a	synonym	for seek=SEEK, see its description.

       prio=PRIO
	      xcopy: SCSI EXTENDED COPY	parameter list PRIORITY	field  is  set
	      to PRIO.	The default value is 1 .

       protect=RDP[,WRP]
	      where  RDP  is the RDPROTECT field in SCSI READ commands and WRP
	      is the WRPROTECT field in	SCSI WRITE commands. The default value
	      for both is 0 which implies no additional	protection information
	      will be transferred.  Both RDP and WRP can be from 0  to	7.  If
	      RDP  is greater than 0 then IFILE	must be	a pt device. If	WRP is
	      greater than 0 then OFILE	must be	a pt device.
	      When copying data	plus protection	information from one  disk  to
	      another  then  'protect=3,3' will	give the least number of prob-
	      lems as that combination then of PI checking on  both  the  read
	      and write	side. See the PROTECTIO	INFORMATION section below.

       retries=RETR
	      sometimes	retries	at the host are	useful,	for example when there
	      is  a  transport error. When RETR	is greater than	zero then SCSI
	      READs and	WRITEs are retried on error, RETR times. Default value
	      is zero.	Only applies to	errors on pt devices.

       rtf=RTF
	      odx: where RTF is	a filename. One	or more	ROD tokens are written
	      to RTF during a read to tokens variant or	a full	copy  variant.
	      One or more ROD tokens are read from RTF during a	write from to-
	      ken  variant.  This operand is not required on a full copy vari-
	      ant. ROD Tokens are 512 bytes long and an	extra 8	byte  (big-en-
	      dian)  integer  containing  the 'number of bytes represented' is
	      placed after each	ROD Token if rtf_len is	given.

       rtype=RTYPE
	      odx: where RTYPE is the ROD Type.	The default  value  (0)	 indi-
	      cates  that  the copy manager (in	the source) decides. RTYPE can
	      be a decimal number, a hex number	(prefixed by 0x	or with	a  "h"
	      appended)	  or   one   of	  "pit-def",  "pit-vuln",  "pit-pers",
	      "pit-cow", "pit-any" or "zero".  The final truncated word	can be
	      spelt out	(e.g.  "pit-vulnerable").   The	 "pit-"	 prefix	 is  a
	      shortening  of "point in time" copy. The "zero" causes a special
	      Block device zero	Token to be created.

       seek=SEEK
	      start writing SEEK blocks	(each of OBS bytes) from the start  of
	      OFILE.  Default  is block	0 (i.e.	start of file).	The SEEK value
	      may exceed the number of OBS-sized blocks	in OFILE.
	      SEEK can be a scatter (gather) list:  see	 the   SCATTER	GATHER
	      LISTS section below.

       skip=SKIP
	      start  reading SKIP blocks (each of IBS bytes) from the start of
	      IFILE. Default is	block 0	(i.e. start of file). The  SKIP	 value
	      must be less than	the number of IBS-sized	blocks in IFILE.
	      SKIP  can	 be  a	(scatter)  gather list:	see the	SCATTER	GATHER
	      LISTS section below.

       status=STAT
	      the STAT value of	'noxfer' suppresses the	throughput  speed  and
	      the  copy	time reporting at the end of the copy. A STAT value of
	      'none' additionally suppresses the records in and	out  reporting
	      after  the  copy.	 So 'status=none' makes	ddpt act like a	tradi-
	      tional Unix command in which "no news is good  news".   The  de-
	      fault action of ddpt is to show the throughput (in megabytes per
	      second) and the time taken to do the copy	after the "records in"
	      and  "records out" lines at the end of the copy. A STAT value of
	      'sgl' together with '-vv'	option will print internally generated
	      scatter gather lists before the copy begins. When	the '-vv'  op-
	      tions  is	 given	alone  then internal scatter lists headers are
	      printed, but not individual elements.  In	most cases these scat-
	      ter gather lists will be the same	lists given to	the  seek=SEEK
	      and  skip=SKIP  operands.	  As a convenience the value 'null' is
	      accepted for STAT	and does nothing.
	      A	STAT value of 'progress' prints	a progress report (to  stderr)
	      every  two  minutes.  If 'progress' is used twice, either	by re-
	      peating the  'status=progress'  operand  or  by  entering	 'sta-
	      tus=progress,progress',  then a progress report is printed every
	      minute. If it is used thrice, the	a progress report  is  printed
	      every  30	 seconds.  Note	that care is taken not to flood	the OS
	      with calls to check the time which  would	 slow  down  the  copy
	      process.	The  amount of data output by the progress reports can
	      modified at runtime (e.g.	during a long copy).  If  the  verbose
	      flag  is 0 or 1 (but not higher and not if the --quiet option is
	      given) then sending a SIG_USR1 (or SIGINFO in FreeBSD) signal to
	      the running ddpt process will toggle the verbose flag between  0
	      and  1.  Note  there is now a shorter form, the command line op-
	      tion: --progress or simply '-p'.
	      Note that	GNU's dd supports 'noxfer', 'none' and 'progress' with
	      similar semantics.

       to=TO  odx, xcopy: where	TO is am xcopy originating command timeout  in
	      seconds.	 The  default value is 0 which is converted internally
	      to 600 seconds (10 minutes). Best	to set this timeout value well
	      above the	expected copy time.  In	a odx full copy	 this  timeout
	      is applied to both the POPULATE TOKEN and	WRITE USING TOKEN com-
	      mands.

       verbose=VERB
	      as  VERB increases so does the amount of debug reporting sent to
	      stderr.  Default value is	zero which yields the  minimum	amount
	      of debug reporting.  A value of 1	reports	extra information that
	      is not repetitive. A value 2 reports cdbs	and responses for SCSI
	      commands	that  are  not	repetitive  (i.e.  other that READ and
	      WRITE). Error processing is not considered repetitive. Values of
	      3	and 4 yield reporting for all SCSI commands, plus Unix	read()
	      and write() calls, so there can be a lot of output.
	      If  VERB	is  "-1"  then	reporting that would have been sent to
	      stderr is	redirected to /dev/null	essentially throwing it	 away.
	      It has the same action as	the --quiet option.
	      In some cases the	position of verbose=VERB (or --verbose)	on the
	      command  line  is	significant. For example to debug (or at least
	      list out)	a scatter gather list given to skip=SKIP or  seek=SEEK
	      the  verbose=VERB	 operand  (or  --verbose) should appear	before
	      skip and/or seek.

OPTIONS
       Options are listed in alphabetical order, sorted	by their long name.

       -d, --dry-run
	      does all the operand and option processing, opens	given file and
	      devices but bypasses the copy stage. For	complex	 command  line
	      invocations  or  for  testing invocations	to be placed in	script
	      files, this option may be	useful to check	for syntax and related
	      errors.
	      When used	once the logic bypasses	the copy just before it	 would
	      normally start copying. When used	twice (or more)	it goes	deeper
	      into  the	 copy to the IO	call level before bypassing the	calls.
	      To see (on stderr) information for each IO this option  combina-
	      tion may be useful: '-ddvv'.

       -f, --flexible
	      this option currently only effects the parsing of	sgl_s in files
	      that are in hexadecimal plus they	have a leading line with 'HEX'
	      in  them.	Without	this option any	such line must be invoked with
	      'H@' before the filename;	in other words the 'H' in the  invoca-
	      tion  needs to match the HEX in the file.	With this option a sgl
	      in a file	can be invoked with '@'	and if	a  line	 with  HEX  is
	      parsed  before any LBA,NUM pairs then it switches	to hexadecimal
	      mode; so all the parsed LBA,NUM pairs are	assumed	to be in hexa-
	      decimal.

       -h, --help
	      reports usage message then exits.

       --job=JF
	      where JF is a file name. That file can contain operands and  op-
	      tions  listed  in	 this  and  the	previous sections. See the JOB
	      FILES section below.

       -o, --odx
	      indicates	to this	utility	that one of the	four odx  variants  is
	      requested.  See ODX section.

       -P, --prefetch
	      this  option  is	only  active  when the --verify	option is also
	      given.  It causes	the SCSI PRE-FETCH(OFILE, IMMED) command to be
	      sent at the start	of each	copy segment. See the  VERIFY  section
	      below.

       -p, --progress
	      this  option  has	 the  same  effect  as	status=progress	but is
	      shorter to type and easier to remember. When given once, the de-
	      fault reporting period is	two  minutes,  if  given  twice	 (e.g.
	      '-pp') that period is shortened to one minute.

       -q, --quiet
	      redirects	 the  messages	(sent to stderr) to /dev/null which is
	      essentially throwing them	away. That redirect takes place	 after
	      the  command line	operands and options are parsed	and associated
	      sanity checks performed.

       -v, --verbose
	      equivalent of verbose=1. If --verbose appears twice then that is
	      equivalent to verbose=2. Also -vv	is equivalent to verbose=2.

       -X, --verify
	      rather than copy,	a comparison is	done between IFILE and	OFILE.
	      The  compare  continues  until  an  inequality is	found at which
	      point the	operation stops. This is only available	if OFILE is  a
	      pass-through device that implements VERIFY(10 or 16) with	BYTCHK
	      set to 1.	See the	VERIFY section below.

       -V, --version
	      reports version number information then exits.

       -w, --wscan
	      this  option  is available in Windows only. It lists storage de-
	      vice names and the corresponding	volumes,  if  any.  When  used
	      twice  it	 adds  the "bus	type" of the closest transport (e.g. a
	      SATA disk	in a USB connected enclosure has bus type  USB).  When
	      used  three  times  a SCSI adapter scan is added.	When used four
	      times only a SCSI	adapter	scan is	shown.	See  EXAMPLES  section
	      below and	the README.win32 file.

       -x, --xcopy
	      this  option  will  attempt to call the SCSI EXTENDED COPY(LID1)
	      command. In the absence of another indication the	xcopy  command
	      will be sent to the destination (i.e. OFILE). See	the section on
	      ENVIRONMENT VARIABLES below.

ARGUMENTS
       Arguments do not	start with hyphen nor contain a	"=".

       ddpt   this  string is just a marker. It	must not appear	in the command
	      line and it must appear in the contents of a job file that isn't
	      part of a	comment	(i.e. following	a "#" on a line). A syntax er-
	      ror is generated (and no copy occurs) if these  rules  are  vio-
	      lated.

       JF     a	 command line element that does	not contain a '=' (i.e.	a ddpt
	      operand) and does	not start with	'-',  apart  from  the	string
	      "ddpt"  is  treated  as  a job file (i.e.	JF). See the JOB FILES
	      section below.

CONVERSIONS
       One or more conversions can be given to the  "conv="  option.  If  more
       than  one  is given, they should	be comma separated. ddpt does not per-
       form the	traditional dd conversions (e.g. ASCII	to  EBCDIC).  Recently
       added  conversions  inherited  from  GNU's dd overlap somewhat with the
       some of ddpt flags.

       fdatasync
	      equivalent to "oflag=fdatasync". Flushes	data  associated  with
	      the  OFILE to storage at the end of the copy. This conversion is
	      for compatibility	with GNU's dd.

       fsync  equivalent to "oflag=fsync". Flushes data	and meta-data  associ-
	      ated with	the OFILE to storage at	the end	of the copy. This con-
	      version

       no_del_tkn
	      equivalent to "oflag=no_del_tkn".

       nocreat
	      OFILE  will  not be created if it	doesn't	exist. The default ac-
	      tion if OFILE does not exist is to create	a regular  file	 (then
	      write  into it). The default action can be surprising if writing
	      to a device node in /dev and due to some external	action (e.g. a
	      USB key being removed) that device node name disappears.

       noerror
	      this conversion is very close to "iflag=coe" and is  treated  as
	      such.  See  the "coe" flag. Note that an error on	a block	device
	      or regular file OFILE will stop the copy.

       notrunc
	      this conversion is accepted for compatibility with  dd  and  ig-
	      nored  since  the	default	action of this utility is not to trun-
	      cate OFILE.

       null   has no affect, just a placeholder.

       prefer_rcs
	      equivalent to "oflag=prefer_rcs".

       resume See "resume" in the FLAGS	sections for more information.

       rtf_len
	      equivalent to "oflag=rtf_len".

       sparing
	      See "sparing" in the FLAGS sections for more information.

       sparse FreeBSD's	dd supports "conv=sparse" and now  GNU's  dd  does  as
	      well  so	the  same syntax is supported in ddpt. See "sparse" in
	      the FLAGS	sections for more information.

       sync   is ignored by ddpt. With dd it means supply  zero	 fill  (rather
	      than  skip)  and is typically used like this "conv=noerror,sync"
	      to have the same functionality as	ddpt's "iflag=coe".

       trunc  if OFILE is a regular file then truncate it  prior  to  starting
	      the copy.	See "trunc" in the FLAGS section.

FLAGS
       A list of flags and their meanings follow. The flag name	is followed by
       one  or two indications in square brackets. The first indication	is ei-
       ther "[i]", "[o]" or "[io]" indicating this  flag  is  active  for  the
       IFILE,  OFILE  or  both	the IFILE and the OFILE. The second indication
       contains	some combination of "reg",  "blk"  "pt",  "odx",  or  "xcopy".
       These  indicate whether the flag	applies	to a regular file, a block de-
       vice (accessed via Unix read() and write() commands, a pass-through de-
       vice, an	ODX offloaded copy or a	 XCOPY(LID1)  offloaded	 copy  respec-
       tively.	 Other	special	 file types that are sometimes referred	to are
       "fifo" and "tape".

       00 [i] This flag	may replace IFILE with a source	of zero	 (0x0)	bytes.
	      If IFILE is given	and is shorter than OFILE then it continues to
	      copy  after  IFILE  is  exhausted	supplying zero fill bytes. Can
	      only be used on input. Zeros can	also  be  generated  by	 using
	      "if=/dev/zero" or	an equivalent.
	      If  both '00' and	'ff' flags are given then a marching byte pat-
	      tern is placed in	the segment prior to writing it	out. It	starts
	      at 0x0 and wraps after 0xff (if the segment is large enough,  as
	      it usually is).

       append [o] [reg], [io] [odx]
	      causes  the  O_APPEND flag to be added to	the open of OFILE. For
	      regular files this will lead to data being appended to  the  end
	      of  any  existing	 data. Conflicts the seek=SEEK option. The de-
	      fault action of this utility is to overwrite any	existing  data
	      from  the	 beginning  of OFILE or, if SEEK is given, starting at
	      block SEEK. Note that attempting to 'append' to  a  device  file
	      (e.g.  a	disk) will usually be ignored or may cause an error to
	      be reported.
	      odx: if the rtf=RTF option is given, RTF exists,	is  a  regular
	      file  and	this utility wants to write to RTF then	new ROD	Tokens
	      are appended to RTF. The default action is to truncate  RTF  be-
	      fore new ROD Tokens are written to it.

       atomic [o] [pt]
	      this  flag  changes  the	pass-through SCSI WRITE	command	to the
	      SCSI   WRITE   ATOMIC(16)	  command   on	  OFILE	   (and	   the
	      cdbsz={6|10|12|16|32} option is ignored for OFILE). If this flag
	      is applied to IFILE or to	a non pass-through file	then it	is ig-
	      nored.

       block [io] [pt]
	      pass-through  file opens are non-blocking	by default and may re-
	      port the pt device is busy. Use this flag	to  open  blocking  so
	      utility  may  wait until another process locking (or with	an ex-
	      clusive open) is complete	before continuing.

       bytchk [o] [pt]
	      only active when used  together  with  oflag=wverify.  Sets  the
	      BYTCHK  field  in	 the SCSI WRITE	AND VERIFY command. Since that
	      field is two bits	wide, this  flag  can  be  specified  multiple
	      times  (up  to  three)  to  place	the corresponding value	in the
	      field.

       cat [io]	[xcopy]
	      xcopy:  set  CAT	(residual  data	 handling)  bit	 in   EXTENDED
	      COPY(LID1)  parameter list segment descriptor header. May	appear
	      in either	flag list when xcopy is	being used. Works with the PAD
	      bit for handling residual	data on	the destination	side. See  the
	      XCOPY section below.

       coe [io]	[pt], [i] [reg,blk]
	      continue on error. 'iflag=coe oflag=coe' and 'coe=1' are equiva-
	      lent.   Errors  occurring	 on output regular or block files will
	      stop ddpt.  Error	messages are sent to stderr. This flag is sim-
	      ilar to 'conv=noerror,sync' in the  dd(1)	 utility.  Unrecovered
	      errors are counted and reported in the summary at	the end	of the
	      copy.

	      This paragraph concerns coe on pt	devices. A medium, hardware or
	      blank  check  error  during a read operation will	will cause the
	      following: first re-read blocks prior to the bad block, then try
	      to recover the bad block (supplying zeros	if  that  fails),  and
	      finally  re-read the blocks after	the bad	block. A medium, hard-
	      ware or blank check error	while writing is reported  but	other-
	      wise  ignored. SCSI disks	may automatically try and remap	faulty
	      sectors (see the AWRE and	ARRE in	the read write error  recovery
	      mode  page (the sdparm utility can access	these attributes)). If
	      bad LBAs are reported by the pass-through	then the  LBA  of  the
	      lowest and highest bad block is also reported.

	      This paragraph concerns coe on input regular files and block de-
	      vices.   When  a	EIO or EREMOTEIO error is detected on a	normal
	      segment read then	the segment is re-read	one  block  (i.e.  IBS
	      bytes) at	a time.	Any block that yields a	EIO or EREMOTEIO error
	      is replaced by zeros. Any	other error, a short read or an	end of
	      file  will  terminate  the copy, usually after the data that has
	      been read	is written to the output file.

       dc [io] [blk,pt]
	      xcopy: set DC (destination counter) bit in  EXTENDED  COPY(LID1)
	      parameter	 list  segment descriptor header. May appear in	either
	      flag list	when xcopy is being used.

       direct [io] [reg,blk]
	      causes the O_DIRECT flag to be added to the open of IFILE	and/or
	      OFILE. This flag requires	some memory  alignment	on  IO.	 Hence
	      user  memory  buffers  are aligned to the	page size. May have no
	      effect on	pt devices or cause an	error  (e.g.  Linux  seems  to
	      dis-allow	O_DIRECT on character devices (like sg devices)	yield-
	      ing  EINVAL).  This  flag	will bypass caching/buffering normally
	      done by block layer. Beware of data coherency issues if the same
	      locations	have been recently accessed via	the block layer	in its
	      normal mode (i.e.	non-direct). See open(2) man page.

       dpo [io]	[pt]
	      set the DPO bit (disable page out) in SCSI READ and  WRITE  com-
	      mands.  Not supported for	6 byte cdb variants of READ and	WRITE.
	      Indicates	that data is unlikely to be required to	stay in	device
	      (e.g. disk) cache.  May speed media copy and/or  cause  a	 media
	      copy to have less	impact on other	device users.

       errblk [i] [pt] [experimental]
	      attempts	to  create  or append to a file	called "errblk.txt" in
	      the current directory the	logical	block addresses	of blocks that
	      cannot be	read. The first	(appended) line	 is  "#	 start	<time-
	      stamp>".	That is	followed by the	LBAs in	hex (and prefixed with
	      "0x") of any block that cannot be	read, one LBA per line.	If the
	      sense data does not correctly identify the LBA of	the first  er-
	      ror  in  the  range it was asked to read then a LBA range	is re-
	      ported in	the form of the	lowest and  the	 highest  LBA  in  the
	      range  separated by a "-". At the	end of the copy	a line with "#
	      stop <timestamp>"	is appended to	"errblk.txt".  Typically  used
	      with "coe".

       excl [io] [reg,blk]
	      causes  the  O_EXCL flag to be added to the open of IFILE	and/or
	      OFILE. See open(2) man page.

       fdatasync [o] [reg,blk]
	      Flushes data associated with the OFILE to	storage	at the end  of
	      the copy.

       ff [i] This  flag  may  replace	IFILE  with a source of	0xff bytes. If
	      IFILE is given and is shorter than OFILE then  it	 continues  to
	      copy  after  IFILE  is  exhausted	supplying 0xff fill bytes. Can
	      only be used on input.
	      If both '00' and 'ff' flags are given then a marching byte  pat-
	      tern is placed in	the segment prior to writing it	out. It	starts
	      at  0x0 and wraps	after 0xff (if the segment is large enough, as
	      it usually is).

       flock [io] [reg,blk,pt]
	      after opening the	associated file	(i.e. IFILE and/or  OFILE)  an
	      attempt  is  made	 to  get  an  advisory exclusive lock with the
	      flock()  system  call.  The  flock  arguments  are  "FLOCK_EX  |
	      FLOCK_NB"	 which	will  cause  the lock to be taken if available
	      else a "temporarily unavailable" error  is  generated.  An  exit
	      status of	90 is produced in the latter case and no copy is done.
	      See flock(2) man page.

       force [io] [pt] [xcopy,odx]
	      override	difference between given block size and	the block size
	      found by the SCSI	READ CAPACITY command.	Use  the  given	 block
	      size.  Without this flag the copy	would not be performed.	pt ac-
	      cess to what appears to be a block partition is aborted in  ver-
	      sion 0.92; that can be overridden	by the force flag. For related
	      reasons  the  'norcap' flag requires this	flag when applied to a
	      block device accessed via	pt.
	      xcopy and	odx: various limits imposed by associated VPD pages or
	      the RECEIVE COPY OPERATING PARAMETERS command can	be  overridden
	      (i.e.   exceeded)	if this	flag is	given. Note that the copy man-
	      ager will	probably object.

       fsync [o] [reg,blk]
	      Flushes data and metadata	(describing the	file) associated  with
	      the OFILE	to storage at the end of the copy.

       fua [io]	[pt]
	      causes  the  FUA	(force unit access) bit	to be set in SCSI READ
	      and/or WRITE commands. The 6 byte	variants of the	SCSI READ  and
	      WRITE commands do	not support the	FUA bit.

       fua_nv [io] [pt]
	      causes  the FUA_NV (force	unit access non-volatile cache)	bit to
	      be set in	SCSI READ and/or WRITE commands. This only has an  ef-
	      fect  with pt devices.  The 6 byte variants of the SCSI READ and
	      WRITE commands do	not support the	FUA_NV bit. The	FUA_NV bit was
	      made obsolete in SBC-3 revision 35d.

       ignoreew	[o] [tape]
	      ignore the early warning indication (of end of tape) when	 writ-
	      ing to tape.  See	TAPE section.

       immed [io] [odx]
	      sets the IMMED bit in the	POPULATE TOKEN (when [i]) or WRITE US-
	      ING  TOKEN (when [o]) command. That command should return	status
	      promptly after starting the data transfer. The RECEIVE ROD TOKEN
	      INFORMATION command is then used to poll	for  completion.  SCSI
	      command  timeouts	 should	 not  be exceeded, even	for very large
	      RODs, if this flag is used.

       nocache [io] [reg,blk]
	      use posix_fadvise(POSIX_FADV_DONTNEED) to	 advise	 corresponding
	      file there is no need to fill the	file buffer with recently read
	      or  written  blocks.  If used with "iflag=" it will increase the
	      read ahead on IFILE.

       no_del_tkn [o] [odx]
	      will clear the DEL_TKN bit on the	last WRITE USING TOKEN command
	      of each ROD Token	in a odx full copy. In a large odx  full  copy
	      several  ROD  Tokens  may	be used	(one after the other). The de-
	      fault action is to set the DEL_TKN bit on	the last  WUT  command
	      of  each	ROD. Either way	it should not make much	difference be-
	      cause the	copy manager deletes a ROD Token when  its  inactivity
	      time-out occurs.

       nocreat [o]
	      if  OFILE	 does not exist	then an	error will be generated	rather
	      than creating an empty regular file. This	flag has the same  ac-
	      tion as "conv=nocreat".

       nofm [o]	[tape]
	      no  File	Mark (FM) on close when	writing	to tape. See TAPE sec-
	      tion.

       nopad [o] [tape]
	      when the block to	be written to a	tape drive contains less  than
	      OBS bytes, then this option causes the partial block to be writ-
	      ten  as is. The default action for a tape	in this	case is	to pad
	      the block. See TAPE section.

       norcap [io] [pt]
	      do not perform SCSI READ CAPACITY	command	on  the	 corresponding
	      pt device.  If used on block device accessed via pt then 'force'
	      flag  is also required. This is to warn about using pt access on
	      what may be a block device partition.

       nowrite [o] [reg,blk,pt]
	      bypass writes to OFILE. The "records out"	count  is  not	incre-
	      mented.  OFILE is	still opened but "oflag=trunc" if given	is ig-
	      nored.  Also  the	ftruncate call associated with the sparse flag
	      is ignored (i.e.	bypassed). Commands such as trim and SCSI SYN-
	      CHRONIZE CACHE are still sent.

       null [io]
	      has no affect, just a placeholder.

       odx [io]	[odx]
	      indicates	to this	utility	that one of the	four  variants	of  an
	      odx  copy	 is  requested.	 Using	any  of	 the --odx, rtf=RTF or
	      rtype=RTYPE options also indicates that odx  is  requested.  See
	      the ODX section.

       pad [o] [reg,blk,pt], [io] [xcopy]
	      when the block to	be written (typically the last block) contains
	      less  than  OBS  bytes,  then this option	causes the block to be
	      padded with zeros	(i.e. bytes of binary zero). The  default  ac-
	      tion for a regular file and a fifo is to do a partial write. The
	      default  action of a block and a pt device is to ignore the par-
	      tial write. The default action of	a tape is to pad, so this flag
	      is not needed (see the nopad flag).
	      xcopy: sets the PAD bit in the CSCD descriptor of	the associated
	      IFILE or OFILE. Is associated with residual  data	 handling  and
	      works together with the cat flag.	See the	XCOPY section below.

       prealloc	[o] [reg]
	      use  the	fallocate() call prior to starting a copy to set OFILE
	      to its expected size.

       prefer_rcs [o] [odx]
	      prefer RECEIVE COPY STATUS (RCS) command to the RECEIVE ROD  TO-
	      KEN  INFORMATION	(RRTI) command which is	the default. This only
	      is active	when polling after a WUT command (since	polling	 after
	      a	 PT  command needs to fetch the	ROD Token so it	needs the RRTI
	      command).

       pt [io] [blk,pt]
	      causes a device to be accessed in	"pt" mode. In "pt"  mode  SCSI
	      READ  and	 WRITE	commands are sent to access blocks rather than
	      standard UNIX read() and write() commands. The "pt" mode may  be
	      implicit	if  the	device is only capable of passing through SCSI
	      commands (e.g. the  /dev/sg*  and	 some  /dev/bsg/*  devices  in
	      Linux).  This  flag  is  needed for device nodes that can	be ac-
	      cessed both via standard UNIX read()  and	 write()  commands  as
	      well as SCSI commands. Such devices default standard UNIX	read()
	      and write() commands in the absence of this flag.

       rarc [i]	[pt]
	      bit  set	in  READ(10,  12,  16 and 32) to suppress RAID rebuild
	      functions	when a bad (or recovered after difficulties) block  is
	      detected.

       resume [o] [reg]
	      when  a  copy  is	interrupted (e.g. with Control-C from the key-
	      board) then using	the same invocation again with the addition of
	      "oflag=resume" will attempt to restart the copy from  the	 point
	      of  the interrupt	(or just before	that point). It	is harmless to
	      use "oflag=resume" when OFILE doesn't exist or is	 zero  length.
	      If  the  length  of OFILE	is greater than	or equal to the	length
	      implied by a ddpt	invocation that	includes  "oflag=resume"  then
	      no further data is copied.

       self [io] [pt]
	      used together with trim flag to do a self	trim (trim of segments
	      of  a  pt	device that contain all	zeros).	If OFILE is not	given,
	      then it is set to	the same as IFILE. If SEEK is not given	it set
	      to the same value	as SKIP	(possibly adjusted if IBS and OBS  are
	      different). Implicitly sets "nowrite" flag.

       sparing [o] [reg,blk,pt]
	      during  the  copy	each IBS * BPT byte segment is read from IFILE
	      into a buffer. Then, instead of writing that  buffer  to	OFILE,
	      the  corresponding  segment  is  read  from  OFILE  into another
	      buffer. If the two buffers are different,	the former  buffer  is
	      written  to the OFILE. If	the two	buffers	compare	equal then the
	      write to OFILE is	not performed. Write sparing is	useful when  a
	      write  operation is significantly	slower than a read. Under some
	      conditions flash memory devices have slow	writes plus  an	 upper
	      limit on the number of times the same cell can be	rewritten. The
	      granularity  of  the  comparison can be reduced from the default
	      IBS * BPT	byte segment with the the  OBPC	 value	given  to  the
	      "bpt="  option.  The  finest granularity is when OBPC is 1 which
	      implies OBS bytes.

       sparse [io] [reg,blk,pt]
	      after each IBS * BPT byte	segment	is  read  from	IFILE,	it  is
	      checked  to  see	if it is all zeros. If so, that	segment	is not
	      written to OFILE.	See the	section	on SPARSE WRITES below for the
	      difference between using this flag once or twice.	The  granular-
	      ity of the zero comparison can be	reduced	from the default IBS *
	      BPT byte segment with the	OBPC value given to the	"bpt=" option.
	      The  sparse  flag	may be used on input when a file is only being
	      read (e.g.  when of=OFILE	is not given or	OFILE is /dev/null) to
	      determine	how many blocks	are contained in  sparse  segments  of
	      IFILE.

       ssync [o] [pt]
	      if OFILE is in "pt" mode then the	SCSI SYNCHRONIZE CACHE command
	      is sent to OFILE at the end of the copy.

       strunc [o] [reg]
	      perform a	sparse copy with a ftruncate system call to extend the
	      length of	the OFILE if required. Sets the	sparse flag internally
	      if  this	has  not  been	specified on the command line. See the
	      sparse flag and the section on SPARSE WRITES below.

       sync [io] [reg,blk]
	      causes the O_SYNC	flag to	be added to the	open of	 IFILE	and/or
	      OFILE. See open(2) man page.

       rtf_len [io] [odx]
	      odx:  with the 'read to tokens' variant, after 512 bytes of each
	      ROD Token	are written to RTF an additional 8 byte	 (big  endian)
	      integer is written. That integer is the number of	bytes that the
	      associated  ROD represents. The draft standards say for standard
	      ROD types	the ROD	Token contains this value. However vendor spe-
	      cific ROD	types may be used or vendors may choose	not to comply.
	      Either way the 'write from tokens' variant  needs	 to  know  the
	      data size	associated with	the ROD	it is writing from.

       trim [io] [pt] [experimental]
	      similar  logic  to the "sparse" option. However instead of skip-
	      ping segments that are full of zeros a "trim" command is sent to
	      OFILE. Usually set as an oflag argument but for self trim	can be
	      used as an iflag argument	(e.g. "iflag=self,trim"). Depending on
	      the usage	this may require the device to support	"deterministic
	      read  zero  after	trim". See the TRIM, UNMAP AND WRITE SAME sec-
	      tion below.

       trunc [o] [reg]
	      if OFILE is a regular file then it is truncated prior to	start-
	      ing  the copy. If	SEEK is	not given or 0 then OFILE is truncated
	      to zero length; when SEEK	is larger  than	 zero  the  truncation
	      takes   place   at  file	byte  pointer  SEEK*OBS.   Ignored  if
	      "oflag=append". Conflicts	with "oflag=sparing".

       unmap [io] [pt]
	      same as the trim flag.

       wverify [o] [pt]
	      this causes SCSI WRITE AND VERIFY	commands to be sent  to	 OFILE
	      (instead	of  SCSI  WRITE	(or WRITE ATOMIC) commands). Note that
	      the fua flag is ignored when this	 flag  is  given.  The	BYTCHK
	      field  in	 the SCSI WRITE	AND VERIFY commands is set to zero un-
	      less the bytchk flag is also given.

       wstream [o] [pt]
	      this causes SCSI WRITE STREAM(16)	command	to be  sent  to	 OFILE
	      (instead	of  SCSI WRITE.	The Stream Identify (valid range: 1 to
	      0xffff (65535)) should be	 given	via  the  list_id=LID  operand
	      (note that it defaults to	0 which	is invalid). The stream	can be
	      created  (closed	(for  write)  or  its status checked) with the
	      sg_stream_ctl utility. It	is the user's responsibility to	open a
	      stream before calling "ddpt ... oflag=wstream list_id=<strm_id>"
	      and close	it after, if required.

       xcopy [io] [pt]
	      invoke SCSI XCOPY(LID1) logic and	send the XCOPY command to  the
	      either  IFILE  or	 OFILE depending on which flag this called. If
	      both  are	 given	(i.e.  an  invocation  including  'iflag=xcopy
	      oflag=xcopy') then send the XCOPY(LID1) to OFILE.

COUNT
       When the	count=COUNT option is not given	(or COUNT is '-1') then	an at-
       tempt is	made to	deduce COUNT as	follows.

       When both or either IFILE and OFILE are block devices, then the minimum
       size,  expressed	in units of input blocks, is used. When	both or	either
       IFILE and OFILE are pass-through	devices, then the  minimum  size,  ex-
       pressed in units	of input blocks, is used.

       If a regular file is used as input, its size, expressed in units	of in-
       put  blocks (and	rounded	up if necessary) is used. Note that the	round-
       ing up of the deduced COUNT may result in a partial read	 of  the  last
       input block and a corresponding partial write to	OFILE if it is a regu-
       lar file. After a regular file to regular file copy the length of OFILE
       will  be	 the same as IFILE unless OFILE	existed	and its	length was al-
       ready greater than that of IFILE. To get	a copy like the	standard  Unix
       cp command, use oflag=trunc with	ddpt.

       The  size of pt devices is deduced from the SCSI	READ CAPACITY command.
       Block device sizes (or their partition sizes) are obtained from the op-
       erating system, if available.

       If skip=SKIP or seek=SEEK are given and the COUNT is deduced (i.e.  not
       explicitly  given)  then	that size is scaled back so that the copy will
       not overrun the file or device.

       If COUNT	is not given and IFILE is a fifo (and stdin is	treated	 as  a
       fifo)  then  IFILE  is  read until an EOF is detected.  If COUNT	is not
       given and IFILE is a /dev/zero (or equivalent) then zeros are read  un-
       til an error occurs (e.g. file system full).

       If  COUNT  is  not given	and cannot be deduced then an error message is
       issued and no copy takes	place.

JOB FILES
       Some operands can have long arguments (e.g. skip=SKIP and  iflag=FLAGS)
       so  that	 the  command  line can	become quite long. Also	scatter	gather
       lists can be arbitrarily	long and may be	generated by a	program;  then
       it  would  be  tiresome	and error-prone	to re-type them	on the command
       line. So	the job	file was introduced to hold  this  utility's  operands
       and options.

       A  job  file is invoked by either the --job=JF option or	by placing the
       job filename (JF) unadorned on the command line.	The job	filename  can-
       not  contain  a	"=",  start  with a hyphen nor be called "ddpt". It is
       parsed when it is detected, in a	left to	 right	scan  of  the  command
       line.  The  JF file must	contain	the string "ddpt" and may invoke other
       job files (to a maximum depth of	4). A job file should not  invoke  it-
       self.  Also the first line of the job file should not contain any char-
       acters (bytes) with their top bit set; in other words it	should be  re-
       stricted	 to  7	bit ASCII (otherwise sanity checks might think it is a
       binary file and reject it).

       The operands and	options	within a job file are processed	in  the	 order
       they are	found (i.e. parsing lines left to right, top (of file) to bot-
       tom).   The operands and	options	may contradict (and cause a syntax er-
       ror), override or accumulate with earlier ones, the same	as if they ap-
       peared on the command line. For example '-v' on the command  line  fol-
       lowed  by  a job	file containing	'-vv' will result in a verbosity level
       of '-vvv' during	the copy phase.	Empty  lines,  lines  only  containing
       whitespace(s)  and anything from	and including a	'#' in a job file line
       are ignored.

SCATTER	GATHER LISTS
       Each element of a scatter gather	list (sgl, plural: sgl_s) is  made  up
       of  a  starting logical block address (LBA, plural: LBAs), and a	number
       of blocks (NUM) to be accessed from that	starting LBA.

       The skip=SKIP and seek=SEEK options (and	their aliases) can take	 scat-
       ter  gather  lists.  These  can be explicit on the command line,	fed in
       through stdin or	in a file whose	name is	prefixed by "@"	or "H@"	on the
       command line. For large scatter gather lists, placing them in a file is
       the most	practical as command lines  are	 limited  in  length.  Scatter
       gather  list  (sgl) is a	collective term	for either a scatter list or a
       gather list.  The actual	implementation of each sgl is an  array.  Syn-
       tactically a scatter list and a gather list are the same.

       Conceptually  these  sgl_s refer	to what	happens	at the "far end" (e.g.
       within a	hard disk or SSD), not what happens in the computer's  memory.
       So  a  gather list is associated	with the read part of a	copy (i.e. the
       first half) where a list	of Logical Blocks (LBs,	 identified  by	 their
       addresses,  hence  LBAs)	 and a number of consecutive, following	blocks
       are "gathered" from the medium (e.g. a SSD). They  are  formed  into  a
       linear sequence of bytes	that is	transferred into a segment in the com-
       puter's	RAM.  The  second  half	of the copy, the write part, may use a
       scatter list. A scatter list starts with	a linear  sequence  of	bytes,
       taken  from  the	 segment,  that	 is transferred	to the device and then
       "scattered" on the medium as indicated by the list of LBA,NUM pairs.

       In the simplest case a sgl is given on the command  line	 and  has  the
       form:  LBA1,NUM1[,LBA2,NUM2[,LBA3,NUM3...]]. There must be an even num-
       ber of items (i.e. for every LBAn there should  be  a  following	 NUMn)
       with one	exception: when	LBA1 alone is given, in	which case the value 0
       is  assumed  for	 NUM1. Comma is	the simplest separator for the command
       line, but whitespace may	also be	used (but needs	to be escaped  because
       the  shell  usually interprets whitespace as an option separator). In a
       file (or	read from stdin	or file	redirection) more flexibility is  per-
       mitted  in  the format.	The LBA,NUM pairs could	all appear on one line
       in a file but the line length is	limited	to  1024  characters  (with  a
       maximum of 256 parseable	items on it). So for longer sgl_s one pair per
       line  is	 recommended  in  file format.	Also in	file format everything
       from and	including '#' to the end of that line is ignored as are	 lines
       that are	empty or only contain whitespace(s).

       Each  pair  becomes one element (or more, see below) of the sgl.	By de-
       fault all numbers given for LBA and NUM items are in decimal  with  op-
       tional  suffix  multipliers.  Hex numbers use either a "0x" prefix or a
       'h' suffix (hex notation	and suffix multipliers cannot  be  mixed).  In
       the  case  of  a	 'H@' lead-in to the filename on the command line, all
       numbers are interpreted as hex with no  suffix  multipliers  permitted.
       Further,	 with  the  'H@' lead-in the file may contain the string 'HEX'
       before any numbers are given. The 'HEX' is ignored. The point  of  this
       is  to  catch when a sgl	file with default hexadecimal numbers is given
       without the 'H@'	lead-in; in this case this utility  will  exit	saying
       that  file  is  in the wrong format.  This "wrong format" action	can be
       bypassed	with the --flexible option.

       Allowing	sgl_s brings lots of flexibility (including the	possibility to
       use the SCSI WRITE SCATTERED command) but with that  comes  complexity.
       Every sgl is scanned to determine if it is monotonic and	whether	it has
       overlapping  elements.  The  term monotonic is used to indicate whether
       each LBA	is in ascending	order, with each LBA greater than the previous
       element's LBA.  Overlapping refers to the situation when	any  element's
       LBA range intersects with any other element's range. Elements that have
       zero  number of blocks (described here as "degenerate") are ignored for
       determining monotonic and overlapping (and the lowest LBA). Overlapping
       elements	are not	ideal (but not necessarily fatal). The above mentioned
       WRITE SCATTERED command allows the medium's logic to write elements  in
       any  order  it  prefers.	 That means if elements	overlap, then the user
       doesn't know which one gets written last	(overwriting the  one  written
       to  the	same LBA earlier).  Determining	whether	element	ranges overlap
       is difficult in the general case	(so this utility doesn't  do  it)  but
       easy in the case	of a monotonic sgl (so this utility does do it). Warn-
       ings  are  issued in dangerous situations, with the force flag allowing
       the warning to be overridden.

       A degenerate sgl	element	is one that has	zero in	its NUM	 field.	  Nor-
       mally degenerate	elements are ignored with some exceptions. The defini-
       tion of the SCSI	WRITE SCATTERED	command	clearly	states that degenerate
       elements	are valid, thus	do not cause an	error, but cause no associated
       action.	This  utility  uses  the concept of a 'hard' and 'soft'	sgl: a
       'soft' sgl is one in which the last element's NUM is  zero  (i.e.   its
       last element is degenerate). A sgl with a non-zero NUM in its last ele-
       ment  is	considered 'hard'. In a	'soft' sgl the LBA of the last element
       should be greater than or equal to any  LBA+NUM	of  earlier  elements.
       Because	this  is  hard to check	it is not enforced, so the decision is
       made on whether a sgl is	hard or	soft simply by	checking  the  NUM  of
       that  last  element.  The difference between a hard and soft sgl	is the
       way the sum of NUM of all elements is used  by  this  utility.	For  a
       'hard'  sgl  that  sum is used for COUNT	when the count=COUNT option is
       not given; and if count=COUNT is	given and the counts differ then those
       two values are output and this utility exits with a syntax error. For a
       'soft' sgl the degenerate last element  is  interpreted	as  "from  the
       highest	LBA in the list	to the end of the copy"	where the COUNT	is de-
       termined	some other way.	The "highest LBA" is calculated	from all  ele-
       ments  that  have  a non-zero number of blocks plus the LBA of the last
       element (regardless of whether it is degenerate or not).

       The rules in the	above paragraph	make a one item	skip or	seek  argument
       (e.g.  skip=0x123) in this utility first	become a one element sgl (e.g.
       containing  the	pair [0x123, 0x0]). Since this is the last element, it
       is a soft sgl and the transfer will start  from	the  given  lba	 (i.e.
       0x123)  and  continues for the number of	blocks indicated by some other
       mechanism (e.g.	an option such as count=COUNT or the length of IFILE).
       This mirrors what the classic dd	command	does with its skip= and	 seek=
       options.

       Some  sgl  implementation  details:  LBAs are stored in 64 bit integers
       which is	more than sufficient to	span even the largest disk  array  be-
       hind a logical device, even if the block	size is	one byte, which	is un-
       likely. The NUM field is	a 32 bit integer and this is more problematic.
       The  reason is that SCSI	WRITE commands (and their variants) only allo-
       cate at most a 32 bit integer for this value. Further, modern operating
       systems do not allow any	driver to get large amounts of contiguous sys-
       tem RAM,	even if	the machine has	it available. A	32 bit integer for NUM
       with each block at 512 bytes is around 2	TB  of	storage.  Unix	system
       calls (in Linux)	also limit each	read(2)	and write(2) system call to 32
       bits  of	 single	 bytes	which is 4 GB. The problem for this utility is
       that the	NUM can	easily exceed 32 bits when  a  single  scatter	gather
       list element refers to the whole	device.	The action taken by this util-
       ity  is	to allow larger	than 32	bit NUM	values to be given on the com-
       mand line (or in	a scatter gather list file). However such a large ele-
       ment will be split into multiple	elements internally. This will be vis-
       ible to the user	when the verbose=VERB option (or one of	its  variants)
       is used with an elevated	value.

       There  is a helper utility called ddpt_sgl in this package for generat-
       ing, manipulating and checking scatter gather lists. See	its manpage.

SANITY CHECKS
       With powerful data tools, the ability  to  accidentally	overwrite  and
       hence  lose important data is ever present. So a	significant portion of
       the code	is dedicated to	checking the input arguments for  duplications
       and contradictions. Still nothing is better than	re-reading the command
       line (which can be quite	long) before hitting the enter key.

       Other  useful  possibilities  are to use	job files (see the JF argument
       and the --job=JF	option)	and the	--dry-run option.  The "dry  run"  op-
       tion  is	 becoming popular in modern command line utilities and more or
       less does what the user would expect. Firstly it	parses all the command
       line arguments then opens IFILE,	OFILE and OFILE2 as  directed  by  the
       command	line and does any meta-data operations that it would typically
       do (e.g.	check a	pass-though or block device's logical block  size  and
       object  if  it  differs	from BS, IBS or	OBS (whichever applies)). Then
       just at the point where the code	would commence	the  actual  copy  (or
       read) it	does a premature exit. If the --dry-run	option is given	twice,
       the  code continues into	the copy logic and bypasses the	low level read
       and write calls (and file repositioning). That inner level of "dry run"
       is useful for debugging and can be used with multiple verbose=VERB  op-
       tions.

       The verbose=VERB	option sends diagnostic	messages to stderr. The	higher
       value  of VERB (in verbose=VERB)	or the more times that -v is used, the
       greater the volume of diagnostic	messages. When use three or more times
       then diagnostic messages	are generated for  each	 read  to,  and	 write
       from,  the  working  copy  buffer; so the volume	of messages is propor-
       tional to the number of reads and writes	that are done; this can	easily
       be in the megabyte range. If used less than three times,	the reads  and
       writes  associated  with	 the  copy do not generate diagnostic messages
       (unless abnormal	situations are encountered). These diagnostic messages
       are mainly associated with command line parsing and fetching  meta-data
       about the given files, plus messages from the cleanup at	the end	of the
       copy.

       The following command line arguments are	checked	that they don't	appear
       more  than once:	bpt=BPT[,OBPC],	bs=BS, count=COUNT, ibs=IBS, if=IFILE,
       iseek=SKIP, obs=OBS, of=OFILE, of2=OFILE2,  oseek=SEEK,	seek=SEEK  and
       skip=SKIP.  On the other	hand, some arguments are additive, for example
       iflag=FLAGS, oflag=FLAGS, status=STAT and --verbose and may  appear  as
       many times as required.

XCOPY
       This  section  describes	XCOPY(LID1) support with this utility. For ODX
       support (XCOPY(LID4) subset) see	the ODX	section.

       A device	(logical unit (LU)) that supports XCOPY	operations should  set
       the 3PC field (3PC stands for Third Party Copy) in its standard INQUIRY
       response. That is not checked when this utility does an xcopy operation
       but if it fails,	that is	one thing that the user	may want to check.

       If the xcopy starts and fails while underway, then 'sg_copy_results -s'
       may  be	useful	to  view the copy status. It might also	be used	from a
       different process with the same I_T nexus (i.e. the  same  machine)  to
       check status during an xcopy operation.

       The  pad	 and  cat  flags control the handling of residual data.	As the
       data can	be specified either in terms of	source or  target  block  size
       and  both  might	 have different	block sizes residual data is likely to
       happen in these cases.  If both block sizes are	identical  these  bits
       have no effect as residual data will not	occur.

       If  neither  of	these flags are	set, the EXTENDED COPY command will be
       aborted with additional sense 'UNEXPECTED INEXACT SEGMENT'.

       If only the cat flag is set the residual	data will be retained and made
       available for subsequent	segment	descriptors.  Residual	data  will  be
       discarded for the last segment descriptor.

       If  the	pad  flag  is set for the source descriptor only, any residual
       data for	both source or destination will	be discarded.

       If the pad flag is set for the  target  descriptor  only	 any  residual
       source data will	be handled as if the cat flag is set, but any residual
       destination data	will be	padded to make a whole block transfer.

       If  the	pad flag is set	for both source	and target any residual	source
       data will be discarded, and  any	 residual  destination	data  will  be
       padded.

       There   is   a	web   page   discussing	  ddpt,	  XCOPY	  and  ODX  at
       https://sg.danny.cz/sg/ddpt_xcopy_odx.html

ODX
       This section describes ODX support (an  XCOPY(LID4)  subset)  for  this
       utility.	  ODX  descriptions  use  the following	command	name abbrevia-
       tions: PT for the POPULATE TOKEN	command, RRTI for the READ  ROD	 TOKEN
       INFORMATION command, and	WUT for	the WRITE USING	TOKEN command.

       A  device  (logical unit	(LU)) that supports ODX	operations is required
       to set the 3PC field (3PC stands	for Third Party	Copy) in its  standard
       INQUIRY	response  and  support	the Third Party	Copy VPD page. If this
       utility generates errors	noting the absence of these then the device in
       question	probably does not support ODX.

       There a four variants of	ODX supported by ddpt:
	 full copy : ddpt --odx	if=/dev/sg3 bs=512 of=/dev/sg4
	 zero output blocks : ddpt if=/dev/null	rtype=zero bs=512 of=/dev/sg4
	 read to tokens	: ddpt if=/dev/sg3 bs=512 skip=@gath.lst rtf=a.rt
	 write from tokens : ddpt rtf=a.rt bs=512 of=/dev/sg4 seek=@scat.lst

       The full	copy will call PT and WUT commands repeatedly until  the  copy
       is  complete. More precisely the	full copy will make the	largest	single
       call to PT allowed by the input's Third Party Copy VPD  page  (and,  if
       given,  allowed by the BPT argument in the bpt=BPT[,OBPC] option). Then
       one or more WUT calls are made to write out from	the ROD	created	by the
       PT step.	The largest single WUT call is	constrained  by	 the  output's
       Third  Party Copy VPD page (and,	if given, allowed by the OBPC argument
       in the bpt=BPT[,OBPC] option). This sequence continues  until  the  re-
       quested copy is complete.

       The  zero  output  blocks variant is a special case of the full copy in
       which only WUT calls are	made. ODX defines a special ROD	Token to  zero
       blocks. That special ROD	Token has a fixed pattern (shown in SBC-3) and
       does not	need to	be created by a	PT command like	normal ROD Tokens.

       The  read  to tokens and	the write from tokens variants are designed to
       be the read (input) and write (output) sides respectively of a  network
       copy.   Each can	run on different machines by sending the RTF file from
       the machine doing the read to the machine doing the write. The read  to
       tokens  will make one or	more PT	calls and output the resulting ROD To-
       kens to the RTF file. RTF might be a regular file or a named pipe.

       All four	variants can have the immed flag set. Then the PT  and/or  WUT
       commands	are issued with	the IMMED bit set and the RRTI command is used
       to  poll	for completion.	The delay between the polls is as suggested by
       the RRTI	command	(or if no suggestion is	made, 500  milliseconds).  Ei-
       ther  iflag=immed, oflag=immed or both can be given but are only	effec-
       tive if the corresponding IFILE or OFILE	sends a	PT or WUT command.

       Typically there is no need to give the list_id=LID option. If this  op-
       tion  is	 not  given  then  257	is chosen. If that is busy then	258 is
       tried.  That continues until a usable LID is found or 10	LIDs have been
       tried. In the latter case ddpt exits with status	of  55	(operation  in
       progress).  If  the  user gives list_id=LID option and LID is busy then
       ddpt exits with exit status 55.

       If the block size of the	input and output are different	(i.e.  IBS  is
       not equal to OBS) then one must be a multiple of	the other. So an input
       block size of 512 bytes and an output block size	of 4096	bytes (or vice
       versa) is acceptable.

       The  four  ODX  variants	 are  distinguished  as	follows: if OFILE is a
       pass-through device, if=/dev/null (or equivalent) and  rtype=zero  then
       the zero	output blocks variant is selected. If both IFILE and OFILE are
       pass-through  devices  and  there  is some indication of	an ODX request
       (e.g.  the --odx	option), then the full copy variant is	selected.  The
       read  to	 tokens	and the	write from token variants are indicated	by the
       absence of either a of=OFILE or a if=IFILE option,  respectively,  plus
       the presence of a rtf=RTF option.

       The helper utility ddptctl contains options to issue a single PT, RRTI,
       WUT  or	COPY  OPERATION	 ABORT	command. It can	also issue a series of
       polling RRTI commands. It can decode information	in ROD	Tokens	(which
       is  not	as informative as it should be)	and print the number of	blocks
       and block size of a disk, plus protection information if	available. See
       ddptctl.

       There  is  a   web   page   discussing	ddpt,	XCOPY	and   ODX   at
       https://sg.danny.cz/sg/ddpt_xcopy_odx.html

SPARSE WRITES
       Bypassing  writes of blocks full	of zeros can save a lot	of IO. However
       with regular files, bypassed writes at the end of the copy can lead  to
       an  OFILE  which	 is  shorter  than  it	would have been	without	sparse
       writes. This can	lead to	integrity checking programs  like  md5sum  and
       sha1sum generating different values.

       This utility has	two ways of handling this file length problem: writing
       the  last  block	 (even	if it is full of zeros)	or using the ftruncate
       system call. A third approach is	to ignore the  problem	(i.e.  leaving
       OFILE  shorter).	 The  ftruncate	 approach  is used when	"oflag=strunc"
       while the last block is written when "oflag=sparse". To ignore the file
       length issue use	"oflag=sparse,sparse". Note that if OFILE's length  is
       already correct or longer than required,	no action is taken.

       The  support  for sparse	writing	of regular files may depend on the OS,
       the file	system and the settings	of OFILE. POSIX	makes  few  guarantees
       when  the  ftruncate  system call is used to extend a file's length, as
       may occur when "oflag=strunc". Further,	primitive  file	 systems  like
       VFAT  may  not  accept  sparse writes or	simulate the effect by writing
       blocks of zeros.	The latter approach will  defeat  any  sparse  writing
       performance gain.

TRIM, UNMAP AND	WRITE SAME
       This  is	 a new storage feature often associated	with Solid State Disks
       (SSDs) or disk arrays with "thin	provisioning". In the ATA command  set
       (ACS-2)	the  relevant command is DATA SET MANAGEMENT with the TRIM bit
       set. In the SCSI	command	set (SBC-3) it is either the  UNMAP  or	 WRITE
       SAME  command.  Note  there is no TRIM command however the term is fre-
       quently used in the technical press.

       Trim is a way of	telling	a storage device that  blocks  are  no	longer
       needed.	 Keeping  the  pool of unwritten blocks	large is important for
       the write performance of	SSDs and the thrifty use of  real  storage  in
       thin  provisioned arrays. Currently file	systems	in recent OSes may is-
       sue trims associated with file deletes. The trim	option in ddpt may  be
       useful  when  a	partition or a whole SSD is to be "deleted". Note that
       ddpt is	bypassing  file	 systems  in  that  it	only  offers  trim  on
       pass-through (pt) devices.

       This  utility  issues  SCSI  commands to	pt devices and for "trim" cur-
       rently issues a SCSI WRITE SAME(16) command with	the UNMAP bit set.  If
       the  pt	device	is  a SSD with a ATA interface then recent versions of
       Linux will translate the	SCSI WRITE SAME	to the ATA DATA	SET MANAGEMENT
       command with the	TRIM bit set. The maximum size of each "trim"  command
       sent  is	 the  size of the copy buffer (i.e. IBS	* BPT bytes). And that
       maximum can be reduced with the OBPC argument of	the "bpt=" option.

       The trim	can be used various ways. One way is a	copy  where  the  copy
       buffer  (or  some  part	of  it)	is checked for zeros as	is done	by the
       sparse oflag. When a zero segment is found, a trim "command" is sent to
       the OFILE. For example:

	  ddpt if=dsk.img bs=512 of=/dev/sdc oflag=pt,trim

       The copy	buffer is 64 KiB (since	BPT  and  OBPC	default	 to  128  when
       "bs=512")  and  it  is checked for all zeros. If	it is all zeros	then a
       trim command is sent to the corresponding location of /dev/sdc which is
       accessed	via the	pt interface. If it is not all zeros then a SCSI WRITE
       command is sent.	Another	way is to trim all or part of a	disk. To  trim
       a whole disk (i.e. deleting all its data):

	  ddpt if=/dev/zero bs=512 of=/dev/sdc oflag=pt,trim

       A  third	 way  is to "self-trim"	which is to only trim those parts of a
       disk that contain segments full of zeros:

	  ddpt	  if=/dev/sdc	 skip=0x2300	 bs=512	    iflag=pt,self,trim
       count=0x1234f0

       The  "self"  oflag automatically	sets up	the output side	of the copy to
       send trim commands  (if	required)  back	 the  the  same	 device	 (i.e.
       /dev/sdc).  If this example was self-trimming a partition then the par-
       tition would start at LBA 0x2300	and be 0x1234f0	blocks long.

       Some  random  product  examples:	the Intel X25-M	G2 SSDs	have trim with
       recent firmware and they	do deterministic read  zero  after  trim.  The
       Seagate	Pulsar SSD has an ATA interface	which supports the determinis-
       tic reads of zero after the DATA	SET MANAGEMENT command with  the  TRIM
       option.

NVME SUPPORT
       The  following information is Linux specific at this time. NVMe devices
       in Linux	have names like	/dev/nvme0, /dev/nvme0n1  and  /dev/nvme0n1p3.
       The  first  device name is a character device and some "Admin" commands
       can be sent to it (e.g. Identify) but no	media access  commands	(which
       the  NVMe  specification	calls the "NVM"	Command	set). The number given
       is a controller identifier. Storage in NVMe is  associated  with	 name-
       spaces  which  are  numbered  within  a controller, starting at 1 (e.g.
       /dev/nvme0n1 is controller 0, namespace	1).  These  device  nodes  are
       block devices and can be	given as IFILE and/or OFILE. The third type of
       NVMe device node	selects	a partition (within a namespace, within	a con-
       troller). Partition numbers also	start with 1.

       By  default  ddpt  will treat the second	and third form (of NVMe	device
       nodes) as standard Linux	block devices. So ddpt will act	in the same as
       the dd utility would. In	a similar fashion to accessing SCSI block  de-
       vices  (e.g.  /dev/sdc3)	get access NVMe	block devices the "pt" flag is
       required, either	with iflag=FLAGS and/or	oflag=FLAGS. There is  a  SCSI
       to  NVMe	Translation Layer (SNTL) in the	sg3_utils library which	under-
       pins this utility.

DD DIFFERENCES
       dd defaults "if=" and "of=" to stdin and	stdout respectively. This fol-
       lows Unix filter	conventions. However since dd and ddpt are often  used
       to   read   binary   data   for	 timing	 purposes,  having  to	supply
       "of=/dev/null" can be easily forgotten. Without it  dd  will  typically
       spew  binary data on the	console. So ddpt has changed its defaults: the
       "if=IFILE" is now mandatory for direct copies and to  read  from	 stdin
       "if=-" can be used; "of=OFILE" remains optional but its default changes
       to "/dev/null" (or "NUL"	in Windows). To	send output to stdout ddpt ac-
       cepts "of=-".

       dd  truncates  OFILE unless "conv=notrunc" is given. When dd truncates,
       it truncates to zero length unless SEEK is greater than zero. ddpt does
       not truncate OFILE by default. If OFILE exists it will be  overwritten.
       The  overwrite  starts  at  block zero unless SEEK or "oflag=append" is
       given. If OFILE is a regular file then "oflag=trunc" (or	 "conv=trunc")
       will truncate OFILE prior to the	copy.

       Numeric	arguments  to  ddpt can	be given in hexadecimal, either	with a
       leading "0x" or "0X" or with a  trailing	 "h".  Note  that  dd  accepts
       "0x123"	but interprets it as "0	* 123" (i.e. zero). ddpt will also in-
       terpret "x" as  multiplies  unless  the	left  operand  is  zero	 (e.g.
       "0x123").   So	both  dd  and  ddpt  will  interpret  "skip=2x123"  as
       "skip=246".

       Terabyte	size disks make	it impractical to copy all  the	 data  into  a
       single buffer of	512 bytes length before	writing	it out.	Therefore both
       dd  and	ddpt  read  a  relatively small	amount of data into a copy (or
       transfer) buffer	then write it out to the destination,  repeating  this
       process until the COUNT is exhausted.

       A major difference in ddpt is the addition of BPT (Blocks Per Transfer)
       to control the size of the copy buffer. With dd,	IBS is the size	of the
       copy buffer and the unit	of SKIP	and COUNT. With	ddpt, IBS * BPT	is the
       size of the copy	buffer and IBS is the unit of SKIP and COUNT. This al-
       lows  ddpt to have its IBS set to the logical block size	of IFILE with-
       out unduly restricting the size of the copy  buffer.  And  setting  IBS
       (and OBS	for OFILE) accurately is required when the pass-through	inter-
       face  is	 used  since with the SCSI READ	and WRITE commands the logical
       block size is implicit.

       The way dd handles its copy buffer (outlined in	SUSv4  description  of
       dd)  is	relatively  complex, especially	when IBS and OBS are different
       sizes. The restriction that ddpt	places on IBS and OBS (	i.e. (((IBS  *
       BPT)  %	OBS) ==	0) ) means that	a single copy buffer can be used since
       its size	is a multiple of both IBS and OBS. Being able to precisely de-
       fine the	copy buffer size in ddpt makes sparse writing,	write  sparing
       and trim	operations simpler to define and the user to control.

       ddpt  does  not	support	dd's "cbs=" option (conversion block size). If
       the "cbs=" option is given to ddpt then it is ignored.

       ddpt adds two types of disk  to	disk,  offloaded  copies:  XCOPY(LID1)
       first  introduced  in  SPC-2 (standardized in 2001), and	ODX which is a
       subset of XCOPY(LID4) first introduced in  SPC-4	 draft	(revision  34,
       2012).

PROTECTION INFORMATION
       This  section is	about protection information which is typically	an ex-
       tra 8 bytes associated with each	logical	block. Those 8	byte  are  di-
       vided into 3 fields: logical block guard	(16 bit	(2 byte) CRC), logical
       block  application tag (2 bytes)	and the	logical	block reference	tag (4
       bytes). The acronym DIF is sometimes used for protection	information.

       The feature to read and/or write	protection information	by  using  the
       protect=RDP[,WRP]  option  is currently experimental. It	should be used
       with care and may not "play well" with  some  other  features  such  as
       write  sparing  and sparse writing. It should be	used to	copy user data
       plus the	associated protection information to or	from a	regular	 file.
       It could	also be	used for a device to device copy assuming the "pt" in-
       terface	is  used for both. Also	only modern SCSI disks support protec-
       tion information.

       When RDP	or WRP is greater than 0 then a	copy with  associated  protec-
       tion  information is active. In this state IBS and OBS must be the same
       and equal to the	logical	block size of  the  device(s)  formatted  with
       protection information. If a SCSI disk with 512 byte logical block size
       has  protection information then	the actual number of bytes transferred
       for each	logical	block is typically 520 bytes. For such a  disk	BS=512
       is required even	when additional	protection information is being	trans-
       ferred.

       When  protection	 type  2  is used, the "normal"	READ, WRITE and	VERIFY
       SCSI commands are disallowed. In	this context "normal" means the	6, 10,
       12, and 16 byte variants. Only READ(32) and WRITE(32) can be used.  The
       32  byte	 variants can be selected in this utility by using the operand
       'cdbsz=32'.

MULTIPLIERS
       By default numeric arguments to options are assumed to be decimal.  Al-
       most  all  numeric  arguments to	options	(e.g. COUNT in the count=COUNT
       option) may include one of these	multiplicative suffixes: c C *1;  w  W
       *2;  b  B  *512;	 k  K  KiB  *1,024;  KB	*1,000;	m M MiB	*1,048,576; MB
       *1,000,000 . This pattern continues for "G", "T"	and  "P".  The	latter
       two suffixes can	only be	used for 64 bit	values.	Some numeric arguments
       are limited to 32 bit values (e.g. BSin the bs=BS option).  Also	a suf-
       fix  of	the  form "x<n>" multiplies the	leading	number by <n>; however
       the combinations	"0x" and "0X" are treated differently,	see  the  next
       paragraph.  These  multiplicative suffixes are compatible with GNU's dd
       command (since 2002) which claims compliance with the SI	and  with  IEC
       60027-2 standards.

       Alternatively numerical values can be given in hexadecimal indicated by
       either  a  leading  "0x"	or "0X", or by a trailing "h" or "H". When hex
       numbers are given, suffix multipliers cannot be used.

       If a numeric argument is	required to fit	in 32 bits and	is  too	 large
       then  an	 error is reported. Usually negative numbers are not permitted
       but "count=-1" is a special  case  and  means  "all  available";	 "ver-
       bose=-1"	is another special case.

NOTES
       Copying	data  behind an	Operating System's back	can cause problems. In
       the   case   of	 Linux,	  users	  should   look	   at	 this	 link:
       https://linux-mm.org/Drop_Caches
       This command sequence may be useful:
	 sync; echo 3 >	/proc/sys/vm/drop_caches

       A  partial  write  is a write to	the OFILE of less than OBS bytes. This
       typically occurs	at the end of a	copy. dd can do	partial	 writes.  ddpt
       does partial writes to regular files and	fifos (including stdout). How-
       ever  ddpt  ignores partial writes when OFILE is	a block	device or a pt
       device. When ddpt ignores a partial write, it sends a  warning  to  the
       console (stderr).

       At the end of the copy two lines	are reported to	the console:
	  <in_full>+<in_partial> records in
	  <out_full>+<out_partial> records out

       The  "records  in" line is the number of	full input blocks (each	of IBS
       bytes) that have	been read plus the number of partial blocks (  usually
       less than IBS bytes) that have been read. Following the lead of dd when
       'iflag=coe'  is	active a block that cannot be read (and	has zeros sub-
       stituted	for its	output)	is regarded as a partial  read.	 The  "records
       out"  line is the number	of full	output blocks (each of OBS bytes) that
       have been written plus the number of partial blocks (usually less  than
       OBS bytes) that have been written.

       Block  devices (e.g. /dev/sda and /dev/hda) can be given	for IFILE.  If
       neither 'iflag=direct' nor 'iflag=pt' is	given then normal block	IO in-
       volving buffering and caching is	performed. If 'iflag=direct' is	 given
       then  the buffering and caching is bypassed (this is applicable to both
       SCSI devices and	ATA disks). When 'iflag=pt' is given SCSI commands are
       sent to the device which	bypasses most of the actions performed by  the
       block layer.  The same applies for block	devices	given for OFILE.

       All  informative,  warning and error reports are	sent to	stderr so that
       dd's output file	can be stdout and remain unpolluted. If	no options are
       given, then no copying (nor reading) takes place	and a brief message is
       sent to stderr inviting the user	to invoke ddpt again but with '--help'
       option to get the usage message.

       Disk partition information can often be found with fdisk(8) [the	 "-ul"
       argument	 is  useful  in	this respect]. Also parted(8) can be used like
       this: 'parted /dev/sda unit s print' .

       For pt devices this utility issues SCSI READ and	WRITE  (SBC)  commands
       which  are  appropriate	for  disks  and	reading	from CD/DVD/BD drives.
       Those commands are not formatted	correctly for tape drives so ddpt can-
       not be used on tape drives via a	pt device. If the  largest  block  ad-
       dress  of  the  requested  transfer  exceeds a 32 bit block number (i.e
       0xffffffff) then	a warning is issued and	the pt device is accessed  via
       SCSI READ(16) and WRITE(16) commands.

       The attributes of a block device	(e.g. partitions) are ignored when the
       pt  flag	is used.  Hence	the whole device is read (rather than just the
       second partition) by this invocation:

	  ddpt if=/dev/sdb2 iflag=pt of=t bs=512

       Assuming	/dev/sdb and /dev/sg2 refer to the same	device,	then after the
       following two invocations, the contents of  the	files  "t",  "tt"  and
       "ttt" should be same:

	  ddpt if=/dev/sdb of=tt bs=512

	  ddpt if=/dev/sg2 of=ttt bs=512

       The  SCSI  READ(32) and WRITE(32) commands are restricted to media that
       is formatted with protection type 2. This is a T10 restriction.

SIGNALS
       The signal handling has been borrowed from GNU's	 dd:  SIGINT,  SIGQUIT
       and SIGPIPE report the number of	remaining blocks to be transferred and
       the  records  in	+ out counts; then they	have their default action. SI-
       GUSR1 (or SIGINFO) causes the same information to  be  output  and  the
       copy continues.	All output caused by signals is	sent to	stderr.

       Like  GNU's  dd,	 ddpt  respects	 the  signal  disposition of "ignored"
       (SIG_IGN) set by	the shell, script or other program that	invokes	 ddpt.
       So in that case it will ignore such signals. Further dd ignores SIGUSR1
       if  the	environment  variable POSIXLY_CORRECT is set because POSIX de-
       fines dd	will only act on SIGINFO (and Linux has	no such	signal);  ddpt
       ignores	the  POSIXLY_CORRECT  environment  variable. As	recommended by
       Susv3, ddpt does	not expect the signal (blocking) mask to  be  blocking
       SIGUSR1 (SIGINFO), SIGINT or SIGPIPE on entry.

       Unix  system  calls that	do IO can be interrupted by signal processing,
       typically returning an EINTR error number. The  dd  utility  (and  many
       other  Unix  utilities)	restart	the IO operation that was interrupted.
       While this will work most of the	time for disk IO it is problematic for
       tape drives because the implicit	position pointer on the	tape may  have
       moved.	So  the	 default  (i.e.	 "intio=0") in this utility is to mask
       those signals during IO operations and only check them prior to	start-
       ing  an	IO  operation.	 Most low level	IO (e.g. using SCSI command to
       write to	a disk)	will timeout if	there is a low	level  error.  However
       NFS  (the  Network  File	 System) will potentially wait for a long time
       (e.g. expecting a network problem will soon be fixed) and in this  case
       using "intio=1" may be best.

VERIFY
       The  usual  way	to  check the two disks	(or part of the	disks) are the
       same is to move through the segments to be compared, reading from  both
       and  comparing  the returned buffers, stopping if there is an in	equal-
       ity.

       This utility takes a different approach that relies on the OFILE	 being
       a  pass	through	 device. That pass-through device needs	to support the
       SCSI VERIFY command with	the BYTCHK field set to	1. Optionally, for the
       --prefetch option to improve performance	that pass-through device needs
       to support the SCSI PRE-FETCH command with its IMMED bit	set.

       When the	--verify option	is given, instead of reading  both  IFILE  and
       OFILE,  only the	IFILE is read. Then the	result of that read is sent to
       the OFILE device	as the data-out	buffer of a VERIFY(BYTCHK=1)  command.
       So  the comparison is actually done on the OFILE	device rather than the
       host computer's main memory.

       If the --prefetch option	is also	given, then before the IFILE  read,  a
       PRE-FETCH(OFILE,	IMMED) is sent.	The IMMED bit will make	it return more
       or less immediately. The	effect of the PRE-FETCH	should be to bring the
       contents	 of  the data to be used for the OFILE side of the comparison,
       into the	OFILE device's cache. And that	should	make  the  later  VER-
       IFY(BYTCHK=1) command faster.

TAPE
       There  is support for copies to and from	tape drives in Linux. Only the
       st driver device	names can be used (e.g.	/dev/st0 and /dev/nst2). Hence
       use of Linux pass-through device	names (e.g. /dev/sg2) for tape	drives
       is  not	supported. On Debian-based distributions, it is	suggested that
       the mt-st package is installed as it  provides  a  more	fully-featured
       version of the "mt" tape	control	program.

       Tape  drives  can  operate in fixed- or variable-length block modes. In
       variable-block mode, each write to the tape writes a  single  block  of
       that size. In fixed-block mode, each write to the tape must be a	multi-
       ple of the previously-selected block size.

       The  block  size/mode  can be set with the mt command prior to invoking
       ddpt.  For example:
	 # mt -f /dev/nst0 setblk 0
       sets variable-block mode, and
	 # mt -f /dev/nst0 setblk 32768
       sets fixed-block	mode with block	size 32768 bytes.

       Note that some tape drives support only fixed-block mode, and  possibly
       even only one block size. (For example, QIC-150 tapes use a fixed block
       size  of	 512 bytes.) There may also be restrictions on the block size,
       e.g.  it	may have to be even.

       When using ddpt to write	to tape, if the	final read from	the  input  is
       less  than OBS, it is padded to OBS bytes before	writing	to tape	to en-
       sure that all blocks of the tape	file are the  same  length.  Having  a
       shorter final block would fail if the drive is in fixed-block mode, and
       could create interchange	problems. It is	common to expect all blocks in
       a  file on tape to be the same length. However, to tell ddpt to not pad
       the final block,	use 'oflag=nopad'.

       The st tape driver normally writes  a  filemark	when  the  file	 (e.g.
       /dev/nst0)   is	 closed.   To  not  have  the  filemark	 written,  use
       'oflag=nofm'. One use case for that might  be  if  using	 ddpt  several
       times  in  succession  to append	more data to the same file on tape. In
       that case it is probably	desirable to write the filemark	at the end  of
       the  sequence. So either	omit 'oflag=nofm' on the last ddpt invocation,
       or manually write a filemark using mt after ddpt	exits:
	 # mt -f /dev/nst0 weof	1

       For reading from	an unknown tape	where the block	size(s)	is not	known,
       read  in	 variable-block	mode specifying	a large	IBS. The st driver re-
       turns a smaller amount of data  if  the	size  of  the  block  read  is
       smaller.	Thus a command like:
	 # ddpt	if=/dev/nst0 of=output.bin bs=262144
       should  read  the file from tape	regardless of the block	size used (as-
       suming no blocks	are larger than	256KB).	 ddpt's	 verbose  option  will
       display what the	actual block size(s) is.

ENVIRONMENT VARIABLES
       If the command line invocation of an xcopy does not explicitly (and un-
       ambiguously)  indicate whether the XCOPY	SCSI command should be sent to
       IFILE (i.e.  the	source)	or OFILE (i.e. the destination)	then  a	 check
       is  made	for the	presence of the	XCOPY_TO_SRC and XCOPY_TO_DST environ-
       ment variables. If either one exists (but not both) then	 it  indicates
       where the SCSI XCOPY command will be sent. By default the XCOPY command
       is sent to OFILE.

       The  ODX	 write from tokens variant is very complex to implement	if the
       amount of data held in each ROD is not known. The value should be found
       in the "number of bytes represented" field in the ROD Token but that is
       not well	supported yet by vendors. So for such cases, that  number  can
       be  appended as a big endian 8 byte integer following each ROD Token in
       the RTF file. The conv=rtf_len will cause that length to	 be  appended.
       Specifying that option on each read to tokens and write from tokens in-
       vocation	  can	be   a	nuisance.  Setting  the	 environment  variable
       ODX_RTF_LEN will	cause this utility to act as if	the  conv=rtf_len  op-
       tion has	been given.

       Sometimes  the default block size of 512	can be a nuisance. This	can be
       overridden by the value associated  with	 the  DDPT_DEF_BS  environment
       variable. If the	environment variable is	not found, the value cannot be
       decoded	or is zero or less, then the default block size	remains	at 512
       bytes.

EXIT STATUS
       To aid scripts that call	ddpt, the exit status is set to	indicate  suc-
       cess  (0)  or  failure  (1 or more). Note that some of the lower	values
       correspond to the SCSI sense key	values.	The exit status	values are:

       0      success. Also conveys boolean true for actions  that  result  in
	      true or false (e.g. sgl equality tests)

       1      syntax  error. Either illegal command line options, options with
	      bad arguments or a combination of	options	that is	not permitted.

       2      the device reports that it is not	ready for  the	operation  re-
	      quested.	 The  device  may  be in the process of	becoming ready
	      (e.g.  spinning up but not at speed) so the utility may work af-
	      ter a wait.

       3      the device reports a  medium  or	hardware  error	 (or  a	 blank
	      check).  For  example  an	attempt	to read	a corrupted block on a
	      disk will	yield this value.

       5      the device reports an "illegal request" with an additional sense
	      code other than "invalid operation code".	This is	often  a  sup-
	      ported  command with a field set requesting an unsupported capa-
	      bility.

       6      the device reports a "unit attention"  condition.	 This  usually
	      indicates	 that something	unrelated to the requested command has
	      occurred (e.g. a device reset) potentially  before  the  current
	      SCSI  command  was sent. The requested command has not been exe-
	      cuted by the device. Note	that  unit  attention  conditions  are
	      usually only reported once by a device.

       7      the device reports a "data protect" sense	key. This implies some
	      mechanism	 has blocked writes (or	possibly all access to the me-
	      dia).

       9      the device reports an illegal request with an  additional	 sense
	      code  of	"invalid  operation  code" which means that it doesn't
	      support the requested command.

       10     the device reports a "copy aborted". This	implies	 another  com-
	      mand  or	device problem has stopped and copy operation. The EX-
	      TENDED COPY family of commands (including	WRITE USING TOKEN) may
	      return this sense	key.

       11     the device reports an aborted command.  In  some	cases  aborted
	      commands	can  be	 retried  immediately  (e.g.  if the transport
	      aborted the command due to congestion).

       14     the DEVICE reports a miscompare sense key.  VERIFY  and  COMPARE
	      AND WRITE	commands may report this.

       15     the  utility  is	unable	to open, close or use the given	IFILE,
	      OFILE or other file. The given file name could be	 incorrect  or
	      there  may be permission problems. Adding	the -v option may give
	      more information.

       20     the device reports it has	a check	condition but "no sense".   It
	      is unlikely that this value will occur as	an exit	status.

       21     the  device  reports  a "recovered error". The requested command
	      was successful.  Most likely a utility will report  a  recovered
	      error  to	stderr and continue, probably leaving the utility with
	      an exit status of	0 .

       24     the device reports a SCSI	status of "reservation conflict". This
	      means access to the device with the  current  command  has  been
	      blocked  because another machine (HBA or SCSI "initiator") holds
	      a	reservation on this device. On modern SCSI systems this	is re-
	      lated to the use of the PERSISTENT RESERVATION  family  of  com-
	      mands.

       25     the  DEVICE  reports a SCSI status of "condition met". Currently
	      only the PRE-FETCH command (see SBC-4) yields this status.

       26     the DEVICE reports a SCSI	status of "busy". SAM-5	 defines  this
	      status  as  the  logical unit is temporarily unable to process a
	      command.	It is recommended to re-issue the command.

       27     the DEVICE reports a SCSI	status of "task	set full".

       28     the DEVICE reports a SCSI	status of "ACA active".	ACA  is	 "auto
	      contingent allegiance" and is seldom used.

       29     the  DEVICE reports a SCSI status	of "task aborted". SAM-5 says:
	      "This status shall be returned if	a command is aborted by	a com-
	      mand or task management function on another I_T  nexus  and  the
	      Control mode page	TAS bit	is set to one".

       31     error  involving	two  or	more command line options. Either they
	      contradict or select an unsupported mode.

       32     the is a logic error in the utility. It corresponds to code com-
	      ments like "shouldn't/can't get here". Perhaps the author	should
	      be contacted.

       33     the command sent to device has timed out.	This occurs  in	 Linux
	      only;  in	 other ports a command timeout will appear as a	trans-
	      port (or OS) error.

       36     no error has occurred. For actions that  result  in  a  boolean,
	      this exit	status indicates false.

       40     the  command  sent to a device has received an "aborted command"
	      sense key	with an	additional sense code of 0x10. This  value  is
	      related to problems with protection information (PI or DIF). For
	      example  this  error  may	 occur when reading a block on a drive
	      that has never been written (or is unmapped) if that  drive  was
	      formatted	with type 1, 2 or 3 protection.

       48     this  is an internal message indicating a	NVMe status field (SF)
	      is other than zero after a command has been executed (i.e. some-
	      thing went wrong).  Work in this area is currently experimental.

       49     low level	driver reports a response's residual count (i.e.  num-
	      ber  of  bytes  actually	received  by HBA is 'requested_bytes -
	      residual_count') that is too high. So no useful  processing  can
	      be done with that	response.

       50 + <os_error_number>
	      OS system	calls that fail	often return a small integer number to
	      help indicate what the error is. For example in Unix the inabil-
	      ity  of  a  system  call to allocate memory returns (in 'errno')
	      ENOMEM which often is associated with  the  integer  12.	So  62
	      (i.e. '50	+ 12') may be returned by a utility in this case.

       90     the flock	flag has been given on a device	and some other process
	      holds the	advisory exclusive lock.

       97     the response to a	SCSI command failed sanity checks.

       98     the  device  reports  it	has  a	check  condition but the error
	      doesn't fit into any of the above	categories.

       99     any errors that can't be categorized into	values	1  to  98  may
	      yield  this  value. This includes	transport and operating	system
	      errors after the command has been	sent to	the device.

       100    a	command	received a 'parameter list length error'.

       101    a	command	received 'illegal field	in parameter list'.  This  may
	      occur  with an odx copy if some combination of parameters	is il-
	      legal or not supported (e.g.  iflag=immed).

       105    a	command	received 'operation in progress'. This may occur  with
	      an  odx copy when	the given LID is already being used by another
	      process (e.g. also using odx) on the same	 machine.  Choose  an-
	      other LID.

       110    a	 command  received  'invalid  token  operation,	 cause not re-
	      portable'. This may occur	with an	odx operation when  the	 given
	      ROD  Token is invalid. One reason	for that may be	the inactivity
	      timeout has been reached and the copy manager has	cancelled  the
	      ROD Token.

       110 + <asc_23h_ascq_code>
	      these  status  values  provide more information than exit	status
	      110. See SPC-5 ASC and  ASCQ  assignments	 (currently  in	 Annex
	      F.2),  specifically  the	entries	for asc=23h . For example exit
	      status 112 corresponds to	asc=23h, ascq=2h which implies the odx
	      copy manager does	not support copies between  LUs	 in  different
	      targets.	That  is  optional; an odx copy	manager	is required to
	      support copies between LUs (that are block devices) in the  same
	      target.

       126    the  utility was found but could not be executed.	That might oc-
	      cur if the executable does not have execute permissions.

       127    This is the exit status for utility not found. That might	 occur
	      when a script calls a utility in this package but	the PATH envi-
	      ronment  variable	 has  not  been	properly set up, so the	script
	      cannot find the executable.

       128 + <signum>
	      If a signal kills	a utility then the exit	status is 128 plus the
	      signal number. For example if a segmentation fault occurs	then a
	      utility is typically killed by SIGSEGV which according to	'man 7
	      signal' has an associated	signal number of 11; so	the exit  sta-
	      tus will be 139 .

       255    the utility tried	to yield an exit status	of 255 or larger. That
	      should not happen; given here for	completeness.

EXAMPLES
       The  examples  in this page use Linux device names. For suitable	device
       names  in  other	 supported  Operating  Systems	see  this  web	 page:
       https://sg.danny.cz/sg/device_name.html	. The sg3_utils(8) man page in
       the sg3_utils package also covers device	naming.

       ddpt usage looks	quite similar to dd:

	  ddpt if=/dev/sg0 of=t	bs=512 count=1MB

       This will copy 1	million	512 byte blocks	 from  the  device  associated
       with  /dev/sg0  (which should have 512 byte blocks) to a	file called t.
       Assuming	/dev/sda and /dev/sg0 are the same device then	the  above  is
       equivalent to:

	  dd if=/dev/sda iflag=direct of=t bs=512 count=1000000

       although	dd's speed may improve if bs was larger	and count was suitably
       reduced.	 The  use  of the 'iflag=direct' option	bypasses the buffering
       and caching that	is usually done	on a block device.

       The dd command's	bs argument can	be thought of as roughly equivalent to
       ddpt's bs*bpt . dd almost assumes buffering on a	block device and  will
       work  as	 long  as  bs  is a multiple of	the actual logical block size.
       Since ddpt can work at a	lower level in some cases the bs argument must
       be a disk's actual logical block	size. Thus the bpt argument was	intro-
       duced to	make the copy more efficient. So  these	 two  invocations  are
       roughly equivalent:

	  dd if=/dev/sda of=t bs=8k count=64
	  ddpt if=/dev/sda of=t	bs=512 bpt=16 count=1k

       In  both	 cases	the total number of bytes moved	is bs*count . And that
       will be done by reading 8k (8192	bytes) into a buffer then writing  out
       that  buffer to the file	t. The read write sequence continues until the
       count is	complete or an error occurs.

       The 'of2=' option can save time when the	input would otherwise need  to
       be  read	twice. For example, to copy data and take a md5sum of it with-
       out needing to re-read the data:

	 mkfifo	fif
	 md5sum	fif &
	 ddpt if=/dev/sg3 iflag=coe of=sg3.img oflag=sparse of2=fif bs=512

       This will image /dev/sg3	(e.g. an unmounted disk) and  place  the  con-
       tents  in  the  (sparse)	 file sg3.img .	Without	re-reading the data it
       will also perform a md5sum calculation on the image.

       Now we use sparse writing logic to get some idea	of how many blocks  on
       a  disk	are  full of zeros. After a SCSI FORMAT	UNIT command or	an ATA
       SECURITY	ERASE command a	disk may be all	zeros.

	  ddpt if=/dev/sdc bs=512 oflag=sparse

       Since no	"of=" option is	given, output goes to /dev/null	so nothing  is
       actually	 written so the	"records out" will be zero. However there will
       be a count of "records in" and "bypassed	records	out". If  /dev/sdc  is
       full  of	zeros then "records in"	and "bypassed records out" will	be the
       same. Since the "bpt=" option is	not given it defaults to "bpt=128,128"
       so the copy buffer will be 64 KiB and the sparse	check for  zeros  will
       be done with 64 KiB (128	block) granularity.

       For examples of the trim	and self,trim options see the section above on
       TRIM, UNMAP AND WRITE SAME.

       Following  is an	example	run on a Windows OS using the '--wscan'	option
       which shows the available device	names (e.g. PD1)  and  the  associated
       volume name(s):

	  ddpt -w
       PD0     [C]     FUJITSU	 MHY2160BH	   0000
       PD1     [DF]    WD	 2500BEV External  1.05	 WD-WXE90
       CDROM0  [E]     MATSHITA	DVD/CDRW UJDA775  CB03

       So, for example,	volumes	D: and F: reside on PhysicalDisk1 (abbreviated
       to "PD1") which is manufactured by WD (Western Digital).

       Further	  examples    can    be	   found    on	  this	  web	 page:
       https://sg.danny.cz/sg/ddpt.html	. There	is a text file containing  ex-
       amples  called  ddpt_examples.txt  in the "doc" directory of this pack-
       age's distribution tarball. The ddpt_examples.txt  file	contains  some
       examples	of using job files.

AUTHORS
       Written by Doug Gilbert

REPORTING BUGS
       Report bugs to <dgilbert	at interlog dot	com>.

COPYRIGHT
       Copyright (C) 2008-2021 Douglas Gilbert
       This  software is distributed under the GPL version 2. There is NO war-
       ranty; not even for MERCHANTABILITY or FITNESS FOR  A  PARTICULAR  PUR-
       POSE.

SEE ALSO
       This utility has	companion/helper utilities ddptctl(8), ddpt_sgl(8)
       There is	a web page discussing ddpt at https://sg.danny.cz/sg/ddpt.html

       The lmbench package contains lmdd which is also interesting. For	moving
       data  to	 and  from  tapes  see	dt  which is found at http://www.scsi-
       faq.org/RMiller_Tools/index.html

       To change mode parameters that effect a SCSI device's caching and error
       recovery	see sdparm(sdparm)

       To verify the data on the media is readable see:	sg_verify(sg3_utils)

       To scan and repair disk partitions see TestDisk (testdisk).

       Additional references: dd(1), open(2),  flock(2),  sg_xcopy,sg_copy_re-
       sults, sg_dd(sg3_utils)

ddpt-0.97			  April	2021			       DDPT(8)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=ddpt&sektion=8&manpath=FreeBSD+Ports+15.0>

home | help