DDPT_SGL(8)
β¨ NAME β¨
welcome to the DDPT_SGL(8) page, bestie π ddpt_sgl is the helper for the ddpt utility's scatter gather lists. periodt. slay.
π¦ SYNOPSIS π¦
no cap, the command line is giving:
ddpt_sgl [--action=ACT] [--a-sgl=SGL] [--b-sgl=SGL] [--chs=CHS]
[--degen=DV] [--document] [--elem=SE[,LE]] [--extension=FNE]
[--flexible] [--help] [--hex] [--iaf=IAF] [--index=IA] [--interleave=IL]
[--non-overlap] [--out=O_SGL] [--quiet] [--round=RB] [--sort-cmp=SC]
[--stats] [--verbose] [--version]
π DESCRIPTION π
okay so bestie, this utility is a scatter gather list helper for the ddpt utility, which copies data between or within SCSI devices (logical units). ddpt's command line syntax is modelled on that of the POSIX dd command, but this utility? she has a more standard Unix command line syntax, with both short and long variants of each option. iconic. fr fr.
Scatter gather lists (sgl_s) are made up of scatter gather elements. no cap, each element is literally a starting logical block address (LBA) and a number of blocks (NUM) from and including that LBA. that's the whole vibe.
ngl, the scatter gather lists can also be viewed as arrays where elements can be accessed by an index. Multiple sgl elements can be accessed with an array of indexes, hence index arrays. Indexes in this utility start at 0 and run to (n - 1), where n is the number of elements in the sgl. Negative indexes are permitted too: -1 is the index of the last sgl element, -2 is the index of the second last sgl element, etc. not me using negative indexes like a main character π
For "twin" actions, twin actions have main character energy: there is an assumed relationship between a-sgl and b-sgl, just like there is between two sgl_s used as the gather list (e.g. skip=) and the scatter list (e.g. seek=) in the ddpt utility. Breaking it down to individual logical blocks: LBAr0 is read and its data is written to LBAw0, LBAr1-->LBAw1, LBAr2-->LBAw2, etc; or more generally LBAr_n-->LNAw_n. Many actions will change the order in which those "read-write" items are performed, and the twin portion of the action attempts to maintain the LBAr_n-->LNAw_n mapping. Generally speaking, copies are the same no matter what order the LBAs are read and written.
One exception is an overlapping scatter list (i.e. on the write side), in which case the order of writes onto the same LBA does matter, hence there is an option to check sgl_s are well-formed in that respect: --non-overlap. important!!
For background on scatter gather lists, see the section of that name in the ddpt(8) manpage found in this package. if you want the lore π«Ά There is a web page at https://sg.danny.cz/sg/ddpt.html .
β¨ OPTIONS β¨
okay bestie, this is the part where we get into the flags. π Arguments to long options are mandatory for short options as well. So like, don't think you can just leave the value off and vibe, okay? π
-a,--action=ACTβACTis some action to perform on the given scatter gather list(s). To list the available actions setACTto'xxx'(or'enum'). The available actions are listed in the ACTIONS section below.-A,--a-sgl=SGLβSGLis a scatter gather list, a sequence of comma separated unsigned integers (up to 64 bits each).SGLhas several forms, the simplest is:LBA0,NUM0,LBA1,NUM1,LBA2,NUM2...and there should be an even number of values with the exception ofLBA0appearing by itself. In this caseNUM0is assumed to be0. OtherSGLforms are'@<filename>'and'H@<filename>'where the contents of the<filename>is parsed as a scatter gather list. Since there are two options for inputting SGLs, this one is termed as the'a-sgl'. See the section on FILE FORMATS below and the section on SCATTER GATHER LISTS in theddpt(8)manpage for more information onsgl_sand their associated terminology.-B,--b-sgl=SGLβSGLis a scatter gather list, a second list termed as the'b-sgl'to differentiate it from the other sgl (a-sgl).-C,--chs=CHSβCHSis a 3 element tuple, separated by commas. Currently 16 bit values from1to0xffffare accepted (the cylinder can be one more:0x10000(or65536)). The first value is the number of cylinders, the second value is the number of heads (limited to16), and the final value is the number of sectors per track (limited to255). Sectors are counted origin1according to CHS conventions (cf. normal LBAs which nearly always count from0). π-D,--degen=DVβDVof0(the default) means that all degenerate elements (apart from the last) are ignored (and dropped from the internal representation which may later be written to an output file). IfDVis odd then a degenerate element's LBA is taken into account when calculating the highest and lowest LBA in a sgl (and may be included in an output file). IfDVis even (apart from aDVof0) then a degenerate element's LBA is taken into account when determining if a sgl is monotonic increasing, decreasing or neither (and may be included in an output file).-d,--documentβ this option causes information about the a sgl or index array to be written as comments (i.e. lines starting with'#') to the beginning of output file(s) created by this utility. If this option is given twice then the command line that caused the output is added to the file as a comment (before any numbers are output). π-E,--elem=SE[,LE]β this option allows a single sgl element (at positionSE(starting element index)) to be output toO_SGLorO_SGL.FNE(orIAF).SEis origin0. IfLE(last element index) is given then a range of sgl elements are output starting at indexSEto indexLEinclusive. If a "twin" operation is being performed then this option only applies to the "a" side output, not the "twin" side. This option is ignored by the output of thesplit_nandtsplit_nactions.
Negative values for either SE or LE count from the end of sgl. For example --elem=0,-1 refers to the whole of the list. If LE is less than SE (after any negative indexes are converted to their equivalent positive index) then that range is output in reverse.
-e,--extension=FNEβFNEis the filename extension used when output filenames are generated. For non-split actions the generated filenames are of the form:O_SGL.FNE. For thesplit_naction the generated filenames are of the form:O_SGL[1..n].FNE. For thetsplit_naction the a-sg is named as per the previous sentence, while for the b-sgl the generated filenames are of the form:O_SGL[1..n]_t.FNE. IfO_SGLis'-'(by itself) then all output is sent tostdoutand this option is ignored. π-f,--flexibleβ this option effects the parsing (reading) ofsgl_sand index arrays that are in files which are in hexadecimal. Such files should have a leading line (i.e. before any numbers) with'HEX'on it. Without this option any such file 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 file can be invoked with'@'and if a line with'HEX'is parsed before any numbers then it switches to hexadecimal mode; so that all the parsed numbers are assumed to be in hexadecimal. π₯-h,--helpβ outputs the usage message summarizing command line options then exits. (Your fave. No notes. π )-H,--hexβ used to define the numeric format of sgl and index array elements written to output (often a file namedO_SGLorstdout). If not given then only decimal values are written to output. If this option is given once then hexadecimal values, prefixed with'0x', are written. If this option is given twice then a line with the string'HEX'is written to output, before any values, and those values are implicitly hexadecimal (i.e. no leading'0x'nor'h'suffix). π-I,--iaf=IAFβ whereIAFis a filename (or'-'forstdout) to write an index array to. The only action that generates an index array currently is--action=sort(andtsort). This option can be together used with, or in place of, the--out=O_SGLoption. The--document,--elem=SE[,LE]and--hexoptions effect what is written. See the section on FILE FORMATS below. π¦-x,--index=IAβ whereIAis one or more indexes, comma separated or, if prefixed by"@"or"H@", a filename containing a list of indexes. These indexes are used by the--action=selectand--action=tselectto select elements from the'a-sgl'. Positive and negative indexes that are too large (in absolute terms) are ignored and create noise if the--verboseoption is given. See the section on FILE FORMATS below. π-i,--interleave=ILβILis an integer, starting from0. WhenILis0(the default) there is no interleave. The interleave only effects thesplit_nandtsplit_nactions and when greater than zero is the maximum number of logical blocks written in each segment in the output file, prior to moving to the next output file. For the case whereILis1and--action=split_1is given then the output file will have every LBA (given by the a-sgl) as a separate sgl element (and thus each will have aNUMof1). For thetsplit_naction the interleave is only applied to the a-sgl but it does effect the twin sgl files. π§-N,--non-overlapβ Checks any given sgl and any resulting sgl (from an action) to see if any portion of the sgl overlaps. This is done by first sorting each sgl by the LBA field, then checking every element against the previous one to determine if there is overlap. SCSI commands that acceptsgl_sprocess degenerate elements without error but if two elements in a WRITE command overlap then it is the storage device's choice which one to WRITE first. The last one to be written will be the one read in subsequent read operations. If no errors are detected then if (all) are non-overlapping then0is returned. If no errors are detected then if (any) are overlapping then36is returned. π-o,--out=O_SGLβO_SGLis the name of a file to write a resultant scatter gather list to. IfO_SGLis'-'then the output is directed tostdout. IfO_SGLstarts with'+'then the output is appended to the file whose name follows the'+'. For the split and tsplit actions, the leading'+'is interpreted as appended to all files that meet the template and exist, otherwise the file is created. If'-'is given then all output is directed tostdout(and the--extension=FNEoption, if given, is ignored). β¨-q,--quietβ suppresses warning and messages announcing an action has succeeded. When this option is given, actions that have a logical (boolean) result don't output messages but still yield an indicative exit status. The exit status will typically be either0for true or36for false. Those warnings/messages are typically sent tostderr. π€«-r,--round=RBβRBis the number of round blocks. Without the option thesplit_naction will divide the number of blocks to be split by'<n>'(or useIL) to get a nominal value. This value is the number of blocks taken from the a-sgl before moving to the next output file. TheRBvalue (default0) is the maximum number of blocks the nominal value may be changed by to align with an existing element boundary in the a-sgl. If the number of blocks in'a-sglis less than10orRBis greater than one third of the nominal value, thenRBis ignored (with a notification written tostderr). For thetsplit_naction this option only applies to the a-sgl. π―-S,--sort-cmp=SCβ whereSCis a value indicating what the sort action's comparison will be. WhenSCis0(the default) the sort is ascending based on the LBA; when it is1the sort is descending based on LBA. WhenSCis2the sort is ascending based onNUM; when it is3the sort is descending based onNUM. Any other value is mapped to0. All sorts are stable which means that sgl elements with the same LBA (in the case ofSCbeing0or1) keep their same relative position. A side effect of this is that the ascending and descending sorts are not always reversals of one another. π-s,--statsβ print out sgl statistics on any given sgl and any resultant sgl. π-v,--verboseβ increase the level of verbosity, (i.e. debug output). π-V,--versionβ print the version string and then exit. π¬
β¨ ACTIONS β¨
Okay bestie, so actions are the whole point of this tool and they get passed on the command line as part of the --action=ACT option. Right now, only one action per invocation is allowed β one and done, no multitasking. But if more get allowed in the future, they'll be comma separated and performed in the order they appear (so, like, left to right, obvi).
If no action is given and the --a-sgl=SGL and --out=O_SGL options are given (with no --b-sgl=SGL option), then the a-sgl is copied to O_SGL (or O_SGL.FNE if the --extension=FNE option is given). It's giving "default behavior, but make it copy."
The actions are listed below in alphabetical order, because we're organized like that. π
append-b2aβ appends the b-sgl to the end of the a-sgl and outputs the result toO_SGL(orO_SGL.FNEif the--extension=FNEoption is given). Requires the--a-sgl=SGL,--b-sgl=SGLand--out=O_SGLoptions. Like literally just gluing them together. π«Άdivisible<n>[,L|N]ordivisible_<n>[,L|N]β where<n>is an integer, 1 or higher. This action checks if each LBA and NUM in a-sgl is divisible by<n>(where 'is divisible' is equivalent to having a remainder of zero). If all are divisible then true is returned (i.e. the exit status0); otherwise false is returned (i.e. exit status36). If the optional,Lsuffix (or,LBA) is given then only each LBA element in a-sgl is checked for divisibility. If the optional,Nsuffix (or,NUM) then only each NUM element in a-sgl is checked for divisibility. The output of the string to stderr announcing divisibility, or lack of it, can be suppressed by the--quietoption. Math girlies rise up. π§enumβ prints out the list of supported actions then exits. Giving the actionxxxhas the same effect. It's the "show me what you got" button. πequalβ this action compares the sgl_s given to--a-sgl=SGLand--b-sgl=SGL. If the same LBAs are in the same order with the same overall number of blocks (but not necessarily the same number of elements) then true is returned (i.e. the exit status0); otherwise false is returned (i.e. exit status36). For example the two element sgl"0x10,0x5, 0x15,0x2"is 'equal' to the one element sgl"0x10, 0x7". The output of the string to stderr announcing equality, or lack of it, can be suppressed by the--quietoption. Same energy, same order. β¨noneβ this action does nothing. This is the default action. If--a-sgl=SGLand--out=O_SGLoptions are given and no other action, then a-sgl is copied toO_SGL. It is a placeholder. Just vibing. πpart-equalβ this action is similar to theequalaction but relaxes the condition that both lists must have the same overall number of blocks. For example the two element sgl"0x10,0x5, 0x15,0x2"is 'part-equal' to the one element sgl"0x10, 0x12". It's equal-ish, but make it flexible. π¦part-sameβ this action is similar to thesameaction but relaxes the condition that both lists must have the same overall number of blocks. For example the two element sgl"0x15,0x2,0x10,0x5"is 'part-same' as the one element sgl"0x10, 0x12". Same but not same same, y'know? πΈsameβ this action is similar to theequalaction but relaxes the condition that both lists must be in the same order. The implementation sorts both given lists before comparing them. For example the two element sgl"0x15,0x2, 0x10,0x5"is the 'same' as the one element sgl"0x10, 0x7". Order doesn't matter, it's the content that counts. πscale<n>orscale_<n>β where<n>is an integer, positive or negative but not zero. When<n>is positive then the starting LBA and the NUM in each a-sgl element is multiplied by<n>. The new (scaled) sgl is written toO_SGL(orO_SGL.FNEif the--extension=FNEoption is given). When<n>is negative then the absolute value of<n>is used as a divisor for each starting LBA and NUM in each a-sgl element. As an example: converting a 512 byte logical block (LB) size sgl to a 4096 byte LB size and vice versa is relatively common. To convert from 4096 --> 512 byte LB size then--action=scale_8is appropriate. To convert from 512 --> 4096 byte LB size then--action=scale_-8is appropriate.
Note: because an integer division is used (that rounds 'towards zero') when<n>is negative then LBs or NUMs may be "lost" in this conversion. This can be checked beforehand with the--action=divisible<n>[,L|N]option. For example: for 512 --> 4096 conversions:--action=divisible_8will report if any starting LBAs or NUMs are not divisible be 8 and hence are not able to be precisely represented as 4096 byte LB addresses or number of 4096 byte blocks. β οΈ
selectβ this action can be used to select a subset (or superset) of the a-sgl in the specified order. Alternatively it can be seen as re-ordering the elements in a-sgl such as is done toward the end of a sort operation. Assuming all the indexes in IA are valid, then theO_SGLfile will have the same number of elements as there are indexes in IA. This option requires non-empty--a-sgl=SGLand--index=IAoptions, plus the--out=O_SGLoption. Pick and choose, main character energy. πsortβ this action will sort the sgl given by--a-sgl=SGLin ascending order by LBA. The resulting sgl is output toO_SGL(orO_SGL.FNEif the--extension=FNEoption is given). The sort is "stable", so if two elements have the same starting LBA then they will appear in the same relative order in the output. Stable queen behavior. πsplit<n>orsplit_<n>β where<n>is an integer, 1 or higher. This action divides--a-sgl=SGLinto<n>roughly equal length (i.e. number of blocks) output sgl_s. The output files are named"O_SGL<1..n>"or"O_SGL<1..n>.FNE". Both the--interleave=ILand--round=RBoptions are taken into account during the split process. Divide and conquer, bestie. πto-chsβ this action takes the 'flat' LBA SGL given to--a-sgl=SGLand converts it into CHS (cylinder/head/sector) based SGL which is written out as directed to--out=O_SGL. This action requires the--chs=CHSoption as well as the--a-sgl=SGLand--out=O_SGLoptions. Old school geometry, but make it cute. πtselectβ this is a "twin select" action that selects from--a-sgl=SGL(a-sgl) then re-orders--b-sgl=SGL(b-sgl) in unison. The select from a-sgl is the same as described under theselectaction above. Additionally b-sgl is is broken up so it has "breaks" at the same positions (i.e. number of blocks from the start of the sgl) as a-sgl does; plus the "breaks" b-sgl has already got. So the "broken up" b-sgl will have at least as many elements as a-sgl. The output of the re-ordered b-sgl is then written toO_SGL_torO_SGL_t.FNEif the--extension=FNEoption is given. Twin telepathy but for storage lists. π§tsortβ this is a "twin sort" action that sorts--a-sgl=SGL(a-sgl) and re-orders--b-sgl=SGL(b-sgl) in unison. The sort of a-sgl is the same as described under thesortaction above. Additionally b-sgl is is broken up so it has "breaks" at the same positions (i.e. number of blocks from the start of the sgl) as a-sgl does; plus the "breaks" b-sgl has already got. So the "broken up" b-sgl will have at least as many elements as a-sgl. The re-ordering vector generated by the stable sort of a-sgl is then applied to the broken up b-sgl. The output of the re-ordered b-sgl is then written toO_SGL_torO_SGL_t.FNEif the--extension=FNEoption is given. Sorting together, slaying together. β¨tsplit<n>ortsplit_<n>β this is a "twin split" action that splits the--a-sgl=SGLand--b-sgl=SGLinto separate series of output files. These separate series maintain the LBA to LBA correspondence of the original a_sgl and b_sgl lists.<n>is an integer, 1 or higher. This action divides--a-sgl=SGLinto<n>roughly equal length (i.e. number of blocks) output sgl_s. The "roughly equal length" is influenced by the--interleave=ILand--round=RBoptions. The output filenames are generated the same way as described for thesplitaction. The sgl from--a-sgl=SGLis expected to be a "hard" sgl which means its last element should not be degenerate (i.e. have a NUM of0). The second half of the "twin split" is to split the--b-sgl=SGLsgl. The same number of output files are used as for the 'A' side but the filenames have a slightly different form:"O_SGL<1..n>_t"or"O_SGL<1..n>_t.FNE"(if the--extension=FNEoption is given). The critical point of this split is that it moves in lockstep with the 'A' side split in the sense that whatever block count an 'A' side segment uses, the following 'B' side segment split uses the same block count. The sgl from--b-sgl=SGLmay be a "hard" or "soft" sgl. In the simplest case the 'B' side sgl can be just'0'which gets expanded to'0,0'(i.e. degenerate list starting at LBA 0); this will use the overall block count from the 'A' side. Lockstep twins, no cap. π«Ά
π FILE FORMATS π
okay so bestie, plot twist: both the sgl_s and the index arrays can be read from files or written to files. It's giving β¨bidirectionalβ¨.
The options that hand a sgl_s or an index array over to be read (like --a-sgl=SGL, --b-sgl=SGL and --index=IA) will, by default, just let you put that stuff directly on the command line. And normally those are comma separated lists β though technically space and tab could be your separators too, if they were appropriately escaped π. So with these options, when you're reading sgl_s and index arrays, you need a leading @ or H@ to signal that a file name follows. No @? It's a list, not a file. Periodt.
π numbers, hex, and the whole vibe π
By default, every number you give in this utility β and in the other utilities in this package too β is assumed to be in decimal. Wanna go hex? Hex numbers can be written with either a leading 0x or a trailing h, your choice, we don't gatekeep.
But here's the slay part: you can flag an entire file as containing hex numbers (so none of the numbers need a leading 0x or trailing h themselves) by using H@ on the command line right before the filename. π
The file itself may also contain a line with 'HEX' in it, sitting prior to any numbers that are to be parsed. And if the --flexible option is given, then @ can be used before the filename, and when 'HEX' is detected in the file (before any numbers) the code switches to hex mode. Without --flexible? Then H@ must be used before the filename. No cap.
As a convenience, the 'HEX' string may appear after hex numbers have been decoded and it will just be ignored π. Why? So that hex sgl_s files can be concatenated together and still be parsed without error. Iconic behaviour tbh.
π¬ comments, blanks, and whitespace π¬
A file being parsed may contain comments following a # symbol. Everything from and including the hash mark to the end of the line is ignored π
.
Blank lines and "whitespace" (spaces, tabs, CRs and LFs) are also ignored. Basically if it's not a number, it's not the moment.
π big arrays, one element per line π
If large sgl_s or index arrays are being used, it is better to have one element per line in the file to be read. Why? Because a line is not expected to be over 1024 bytes long, with more than 254 parsable items on it. That's the limit, bestie.
Good news though: this utility imposes no limit on the number of lines a file to be parsed may have. Infinite lines, zero drama. π¦
π writing files out π
Files to be written out by this utility have their names specified by the --out=O_SGL (optionally together with --extension=FNE) and the --iaf=IAF options.
β οΈ Unlike the file reading options, no @ character should be placed in front of the filename on the command line. Don't do it. I'm serious.
Here's the whole deal with output filenames:
- If a filename of
-is given then output is written to stdout instead of a file. And stdout is normally the console. π₯οΈ - If the filename starts with
+then that character is skipped and the output will be appended to that file, if it exists. If the filename starts with+and the file does not exist, then it is created. β¨ - If
+is not given and the file already exists, then it is truncated (to 0) and then overwritten. π bye bye old contents.
Some output file names have numbers (e.g. as a result of the --action=spilt_<n> option) or _t (e.g. as a result of "twin" actions) appended to them (before the extension, if any).
Sgl elements are output one per line, with a comma separating the LBA and the NUM. Index arrays are output one element (an index) per line.
The --hex option controls the form of those numbers output:
- If
--hexis not given, the numbers are output in decimal. - If the
--hexoption is given once, the numbers are output in hex with a0xprefix. - If the
--hexoption is given twice, then the line'HEX'is written to the file before any numbers, and those numbers are in hex without any adornment (i.e. with no leading0x). πΈ
π --document, the receipt option π
If the --document option is given, then some information β including a date timestamp of generation β is placed as comments at the beginning of files that are written out by this utility. It's like a little birth certificate for your file πΌ.
If the --document option is given twice, then the invocation line of this utility that caused the output is placed in the written file as an additional comment. Receipts on receipts. π§Ύ
π round trip, we love to see it π
The written file format is compatible with the read file format. So, for example, a sgl generated by an invocation of this utility can later be used as a file to be read by another invocation of this utility. It's giving full circle. β»οΈ
πͺ EXIT STATUS πͺ
The exit status of ddpt_sgl is 0 when it is successful. π
β οΈ Note that some options and actions that return a boolean value return0for true and36for false. Yes,36. That's not a typo, that's just the lore. π
Otherwise, the exit status for this utility is the same as that for ddpt. See the EXIT STATUS section in the ddpt man page for the full tea.
π§ͺ EXAMPLES π§ͺ
Okay so, examples are needed. π
See the testing/test_sgl.sh script in this package. That script can be run without root permissions β yes bestie, no sudo required π β and it places its work file (sgl_s) in the /tmp directory.
π AUTHORS π
Written by Douglas Gilbert.
π REPORTING BUGS π
Report bugs to <dgilbert at interlog dot com>.
Β©οΈ COPYRIGHT Β©οΈ
Copyright Β© 2020-2021 Douglas Gilbert
This software is distributed under a FreeBSD license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
π«Ά fr fr, no warranty. Use it, love it, but don't come for anybody if it goes sideways.
π SEE ALSO π
and that's the whole page, bestie π that was ddpt-0.97, dated April 2021, and this was DDPT_SGL(8) β go forth and slay your scatter-gather lists β¨ππ¦
π¦ where this page comes from
- debian bookworm: ddpt 0.97-1 Β· BSD-3-Clause
- debian trixie: ddpt 0.97-2 Β· BSD-3-Clause
- fedora 43: ddpt 0.97-13.fc43 Β· LicenseRef-Callaway-BSD
- fedora 44: ddpt 0.97-15.fc44 Β· LicenseRef-Callaway-BSD
- ubuntu noble: ddpt 0.97-1 Β· BSD-3-Clause
- ubuntu questing: ddpt 0.97-2
- ubuntu resolute: ddpt 0.97-3 Β· BSD-3-Clause
- ubuntu stonking: ddpt 0.97-3 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms