Provided by: ddpt_0.97-1_amd64 bug

NAME

       ddpt  - copies data between files and storage devices. Support for devices 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]] [retries=RETR]
       [rtf=RTF]  [rtype=RTYPE]  [seek=SEEK]  [skip=SKIP]  [status=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. Alternatively if the  --verify
       option  is  given, the IFILE and OFILE contents are compared, stopping if an inequality is
       found. This utility is specialized 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  bypass  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 occurs. 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  either  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 differentiate, 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  follows  in  a  similar
       fashion. Operands (i.e. those with the <name>=<something> 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 section.

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" error 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 DIFFERENCES section below. The default is 512 bytes unless overridden by the
              DDPT_DEF_BS environment variable. Note that newer disks use 4096 byte  blocks  with
              perhaps  larger  block  sizes  coming  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 unless 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 command) 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 single 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
              applies 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 supported 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 Command duration limit A
              and B mode pages, plus the Command duration 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 default 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' scatter 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 discussion of  'hard'  and  'soft'
              scatter gather lists.

       ddpt=VERS
              causes  a syntax error while parsing the command line if the current 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 versions 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  operation  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
              before 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. giving 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 either: '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  input.  See  the  ODX
              section.

       iflag=FLAGS
              where  FLAGS  is  a comma separated list of one or more flags outlined 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 SIGINFO)) 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  after  SKIP  blocks
              (each  of  IBS  bytes)  from the start of IFILE.  Default is block 0 (i.e. start of
              file). This operand is a synonym 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  ignored  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 RECEIVE 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 attempts).
              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. giving both "bs=512 obs=512" is considered
              a syntax error).  If OBS is given  then  it  has  the  following  restriction:  the
              integer  expression  (((IBS  * BPT) % OBS) == 0) must be true.  Stated another 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 receiving 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 additional 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 utility 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 outlined 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 problems 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 token variant.  This operand is not required on a full copy
              variant. ROD Tokens are 512 bytes long and an extra  8  byte  (big-endian)  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)  indicates  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 traditional Unix command in which "no  news  is  good  news".   The  default
              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'  options  is
              given  alone  then  internal  scatter lists headers are printed, but not individual
              elements.  In most cases these scatter 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 repeating the 'status=progress' operand or
              by entering 'status=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 option:
              --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 commands.

       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 combination 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  invocation 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 hexadecimal.

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

       --job=JF
              where JF is a file name. That file can contain operands and options 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 default 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  device  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 error is generated (and no copy occurs) if these rules are
              violated.

       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 perform 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 associated with the OFILE
              to storage at the end of the copy. This conversion

       no_del_tkn
              equivalent to "oflag=no_del_tkn".

       nocreat
              OFILE will not be created if it doesn't exist. The default action 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 ignored since the default
              action of this utility is not to truncate 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  either  "[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 device (accessed via Unix
       read() and write() commands, a pass-through device, an ODX offloaded copy or a XCOPY(LID1)
       offloaded  copy respectively.  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 pattern 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 default 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 before 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 ignored.

       block [io] [pt]
              pass-through file opens are non-blocking by default and may report the pt device is
              busy.  Use  this  flag  to  open blocking so utility may wait until another process
              locking (or with an exclusive 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  equivalent.   Errors
              occurring on output regular or block files will stop ddpt.  Error messages are sent
              to stderr. This flag is  similar  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,  hardware  or
              blank  check  error while writing is reported but otherwise 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 devices.  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)  yielding  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 commands. 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 <timestamp>". 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 error in the range it was asked to
              read  then a LBA range is reported 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 pattern 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 access to what appears to be a block partition is  aborted  in
              version  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 manager 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  effect  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  writing  to  tape.   See
              TAPE section.

       immed [io] [odx]
              sets the IMMED bit in the POPULATE TOKEN (when [i]) or WRITE USING 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  default  action is to set the DEL_TKN bit on the last WUT
              command of each ROD. Either way it should not make much difference because 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 action as "conv=nocreat".

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

       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 written 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 incremented.  OFILE is still
              opened  but  "oflag=trunc"  if given is ignored. Also the ftruncate call associated
              with the sparse flag is ignored (i.e.  bypassed). Commands such as  trim  and  SCSI
              SYNCHRONIZE 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 action 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  partial
              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 TOKEN 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 accessed 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 keyboard) 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
              granularity  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 specific
              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 skipping 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 section below.

       trunc [o] [reg]
              if OFILE is a regular file then it is truncated prior to starting 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
              unless 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 attempt 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, expressed in units of input blocks, is used.

       If a regular file is used as input, its size, expressed in  units  of  input  blocks  (and
       rounded  up  if  necessary)  is  used.  Note that the rounding 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 regular 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  already  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 operating 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 until 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 cannot 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 itself. Also the first line of the
       job  file should not contain any characters (bytes) with their top bit set; in other words
       it should be restricted 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  bottom).   The  operands  and  options  may
       contradict  (and cause a syntax error), override or accumulate with earlier ones, the same
       as if they appeared on the command line. For example '-v' on the command line followed  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 scatter 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. Syntactically 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 computer'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  number  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 permitted 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 default all numbers
       given for LBA and NUM items are in decimal with optional 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). Warnings 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.   Normally  degenerate
       elements  are  ignored  with  some  exceptions. The definition 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 element 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 determined some other way. The "highest LBA" is calculated from all  elements
       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 behind a logical device, even if the  block
       size  is  one  byte, which is unlikely. The NUM field is a 32 bit integer and this is more
       problematic. The reason is that SCSI WRITE commands (and their variants) only allocate  at
       most  a  32 bit integer for this value. Further, modern operating systems do not allow any
       driver to get large amounts  of  contiguous  system  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 utility is to allow larger than 32 bit NUM values to be
       given on the command line (or in a scatter gather list file). However such a large element
       will be split into multiple elements internally. This will be visible 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 generating, 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" option 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 options.

       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
       proportional 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  abbreviations:  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 requested 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
       Tokens 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). Either iflag=immed, oflag=immed or both can be given but are only effective
       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  option  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
       frequently 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  issue 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" currently 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 partition 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 deterministic 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 namespaces  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 controller). 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 devices (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 underpins this utility.

DD DIFFERENCES

       dd defaults "if=" and "of=" to stdin and stdout respectively.  This  follows  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 accepts "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 interpret "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 allows ddpt to have its IBS set to the logical block size of IFILE without
       unduly restricting the size of the copy buffer.  And  setting  IBS  (and  OBS  for  OFILE)
       accurately  is  required  when the pass-through interface 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 define 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  extra  8  bytes
       associated  with each logical block. Those 8 byte are divided 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" interface is used for both.
       Also only modern SCSI disks support protection information.

       When RDP or WRP is greater than 0 then a copy with associated  protection  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 transferred.

       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.  Almost  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 suffix 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"; "verbose=-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). However 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 substituted 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 involving 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 cannot be used on tape drives via a pt device. If the
       largest block address 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. SIGUSR1 (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  defines  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 starting 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 equality.

       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
       VERIFY(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 multiple 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 ensure 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 returns 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 (assuming 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 unambiguously)
       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 environment 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 invocation can be  a  nuisance.  Setting  the
       environment  variable  ODX_RTF_LEN  will  cause this utility to act as if the conv=rtf_len
       option 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 success (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 requested.  The device
              may be in the process of becoming ready (e.g.  spinning up but not at speed) so the
              utility may work after 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  supported command with a field set
              requesting an unsupported capability.

       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  executed  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 media).

       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 command or device problem
              has  stopped  and  copy  operation. The EXTENDED 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 related to the use of the PERSISTENT RESERVATION family of commands.

       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 command 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 comments 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 transport (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. something went wrong).  Work in this area
              is currently experimental.

       49     low level driver reports a response's residual count (i.e. number 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 inability 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  illegal  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 another LID.

       110    a  command received 'invalid token operation, cause not reportable'. 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 occur 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 environment 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 status 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 introduced
       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 without 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 contents 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 examples called ddpt_examples.txt in the "doc" directory of this
       package'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 © 2008-2021 Douglas Gilbert
       This software is distributed under the GPL version 2. There is NO warranty; not  even  for
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

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.scsifaq.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_results,
       sg_dd(sg3_utils)