.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Podwrapper::Man 1.48.0 (Pod::Simple 3.47)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds C`
.    ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
.    if \nF \{\
.        de IX
.        tm Index:\\$1\t\\n%\t"\\$2"
..
.        if !\nF==2 \{\
.            nr % 0
.            nr F 2
.        \}
.    \}
.\}
.rr rF
.\"
.\" Required to disable full justification in groff 1.23.0.
.if n .ds AD l
.\" ========================================================================
.\"
.IX Title "nbdkit-data-plugin 1"
.TH nbdkit-data-plugin 1 2026-07-14 nbdkit-1.48.0 NBDKIT
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
nbdkit\-data\-plugin \- nbdkit plugin for serving data from the command line
.SH SYNOPSIS
.IX Header "SYNOPSIS"
.Vb 2
\& nbdkit data [data=]\*(Aq0 1 2 3 @0x1fe 0x55 0xaa\*(Aq
\&             [size=SIZE] [allocator=sparse|malloc|zstd]
.Ve
.PP
.Vb 2
\& nbdkit data base64=\*(AqaGVsbG8gbmJka2l0IHVzZXI=\*(Aq
\&             [size=SIZE] [allocator=sparse|malloc|zstd]
.Ve
.PP
.Vb 2
\& nbdkit data raw=\*(Aqbinary_data\*(Aq
\&             [size=SIZE] [allocator=sparse|malloc|zstd]
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
\&\f(CW\*(C`nbdkit\-data\-plugin\*(C'\fR is a plugin for \fBnbdkit\fR\|(1) which serves a
small amount of data specified directly on the command line.  The
plugin gets its name from the \f(CW\*(C`data:\*(C'\fR URI scheme used by web
browsers.  This is mainly useful for testing NBD clients.
.PP
You can serve data read\-only using the \fI\-r\fR flag, or read\-write.  Any
writes are thrown away when nbdkit exits.
.PP
Most operating systems have command line size limits which are quite a
lot smaller than any desirable disk image, so specifying a large,
fully populated disk image on the command line would not be possible.
However you can specify a small amount of data at the beginning of the
image, possibly followed by zeroes (using the \f(CW\*(C`size\*(C'\fR parameter to pad
the image to the full size), or use the \f(CW\*(C`data\*(C'\fR parameter creatively
to make mostly sparse disk images.
.PP
The \f(CW\*(C`size\*(C'\fR parameter can specify any virtual size up to the maximum
supported by nbdkit (2⁶³\-1\ bytes).
.SH EXAMPLES
.IX Header "EXAMPLES"
.SS "Create small disks filled with test patterns"
.IX Subsection "Create small disks filled with test patterns"
.Vb 2
\& nbdkit data \*(Aq ( 0x55 0xAA )*2048 \*(Aq
\& nbdkit data \*(Aq ( "Hello" )*2000 \*(Aq size=8192
.Ve
.PP
The first command creates a disk containing 4096 bytes filled with the
repeating bytes 0x55 0xAA.  The second command repeats
\&\f(CW\*(C`HelloHelloHello...\*(C'\fR, truncating the disk to exactly 8192 bytes.
.PP
See also \fBnbdkit\-pattern\-plugin\fR\|(3).
.SS "Create a 1 MB disk with MBR\-format partition table"
.IX Subsection "Create a 1 MB disk with MBR-format partition table"
.Vb 11
\& nbdkit data \*(Aq
\&   @0x1be    # MBR first partition entry
\&     0           # Partition status
\&     0 2 0       # CHS start
\&     0x83        # Partition type (Linux)
\&     0x20 0x20 0 # CHS last sector
\&     le32:1      # LBA first sector
\&     le32:0x7ff  # LBA number of sectors
\&   @0x1fe    # Boot signature
\&     0x55 0xaa
\&   \*(Aq size=1M
.Ve
.PP
A more flexible way to create partitions is to use
\&\fBnbdkit\-partitioning\-plugin\fR\|(1).  To create a data string from an
existing disk use the \f(CW\*(C`disk2data.pl\*(C'\fR script provided in the nbdkit
sources
(https://gitlab.com/nbdkit/nbdkit/blob/master/plugins/data/disk2data.pl).
.SS "Create a disk image with sector\-aligned data"
.IX Subsection "Create a disk image with sector-aligned data"
.Vb 1
\& nbdkit data \*(Aq <file1 @^512 <file2 @^512 <file3 @^512 \*(Aq
.Ve
.PP
Local binary files \fIfile1\fR, \fIfile2\fR and \fIfile3\fR are copied into the
disk image.  Regardless of the size of these files, they will all be
aligned to 512\-byte sector boundaries.  Furthermore because of the
final alignment operation (\f(CW\*(C`@^512\*(C'\fR) the total size of the disk will
also be rounded to a whole number of sectors.
.SS "Create a disk with the same random data in each sector"
.IX Subsection "Create a disk with the same random data in each sector"
.Vb 1
\& nbdkit data \*(Aq </dev/urandom[:512]*16 \*(Aq
.Ve
.PP
The expression \f(CW\*(C`</dev/urandom[:512]\*(C'\fR reads 512 bytes (one sector)
of randomness from the system.  The same random data is repeated over
16 sectors.
.SS "Create a 1 MB disk with some nonsense data at the beginning"
.IX Subsection "Create a 1 MB disk with some nonsense data at the beginning"
.Vb 1
\& nbdkit data base64=MTIz size=1M
.Ve
.PP
The above command serves the bytes \f(CW\*(C`0x31 0x32 0x33\*(C'\fR (which is the
base64 decoding of \f(CW\*(C`MTIz\*(C'\fR), followed by 1M\ \-\ 3\ bytes of zeroes.
.SS """Hello, world"" using this plugin"
.IX Subsection """Hello, world"" using this plugin"
.Vb 2
\& $ nbdkit data raw=\*(AqHello, world!\*(Aq \-\-run \*(Aqnbdcopy "$uri" \- | cat\*(Aq
\& Hello, world!
.Ve
.PP
This works by creating a disk containing the string
\&\f(CW"Hello, world!"\fR.  \fBnbdcopy\fR\|(1) connects to the server using an NBD
URI (\f(CW"$uri"\fR) and copies the disk to stdout (\f(CW\*(C`\-\*(C'\fR).  The extra
\&\fBcat\fR\|(1) is needed because nbdcopy refuses to write raw disk data to
a terminal.
.SH PARAMETERS
.IX Header "PARAMETERS"
Exactly one of the \f(CW\*(C`data\*(C'\fR, \f(CW\*(C`base64\*(C'\fR or \f(CW\*(C`raw\*(C'\fR parameters must be
supplied.
.IP [\fBdata=\fR]DATA 4
.IX Item "[data=]DATA"
Specify the disk data using a simple compact format.  See
"DATA FORMAT" below.
.Sp
\&\f(CW\*(C`data=\*(C'\fR prefix may be omitted in most cases.
See "Magic parameters" in \fBnbdkit\fR\|(1).
.IP \fBbase64=\fRBASE64 4
.IX Item "base64=BASE64"
The \f(CW\*(C`base64\*(C'\fR parameter can be used to supply binary data encoded in
base64 on the command line.
.Sp
This is only supported if nbdkit was compiled with GnuTLS ≥ 3.6.0.
You can find out by checking if:
.Sp
.Vb 1
\& $ nbdkit data \-\-dump\-plugin
.Ve
.Sp
contains:
.Sp
.Vb 1
\& data_base64=yes
.Ve
.IP \fBraw=\fRBINARY 4
.IX Item "raw=BINARY"
The \f(CW\*(C`raw\*(C'\fR parameter can be used to supply raw binary data directly on
the command line.
.Sp
It is usually quite difficult to do this unless you are running nbdkit
from another program (see \fBnbdkit\-captive\fR\|(1)).  One particular
problem is that the data must not contain zero bytes (ie. \f(CW\*(C`\e0\*(C'\fR) since
those will be processed in C to mean the end of the string.  In almost
all cases it is better to use base64 encoding or the custom \f(CW\*(C`data\*(C'\fR
format.
.IP \fBsize=\fRSIZE 4
.IX Item "size=SIZE"
The data is truncated or extended to the size specified.
.Sp
This parameter is optional: If omitted the size is defined by the size
of the \f(CW\*(C`data\*(C'\fR, \f(CW\*(C`raw\*(C'\fR or \f(CW\*(C`base64\*(C'\fR parameter.
.IP \fBallocator=sparse\fR 4
.IX Item "allocator=sparse"
.PD 0
.IP \fBallocator=malloc\fR[,\fBmlock=true\fR] 4
.IX Item "allocator=malloc[,mlock=true]"
.IP \fBallocator=zstd\fR 4
.IX Item "allocator=zstd"
.PD
(nbdkit ≥ 1.22)
.Sp
Select the backend allocation strategy.  See
"ALLOCATORS" in \fBnbdkit\-memory\-plugin\fR\|(1).  The default is sparse.
.SH "DATA FORMAT"
.IX Header "DATA FORMAT"
The \f(CW\*(C`data\*(C'\fR parameter lets you specify small disk images in a simple,
compact format.  It is a string containing a list of bytes which are
written into the disk image sequentially.  You can move the virtual
offset where bytes are written using \f(CW@offset\fR.
.PP
.Vb 1
\& nbdkit data \*(Aq0 1 2 3 @0x1fe 0x55 0xaa\*(Aq
.Ve
.PP
creates:
.PP
.Vb 6
\&             total size 0x200 = 512 bytes (1 sector)
\&┌──────┬──────┬──────┬──────┬───────── ── ── ───┬──────┬──────┐
\&│   0  │   1  │   2  │   3  │  0     0  ...  0  │ 0x55 │ 0xaa │
\&└──────┴──────┴──────┴──────┴───────── ── ── ───┴──────┴──────┘
\&                                                  ↑
\&                                            offset 0x1fe
.Ve
.PP
In this example the size is implied by the data.  But you could also
use the \f(CW\*(C`size\*(C'\fR parameter to either truncate or extend (with zeroes)
the disk image.  Another way to write the same disk would be this,
where we align the offset to the end of the sector and move back 2
bytes to write the signature:
.PP
.Vb 1
\& nbdkit data \*(Aq0 1 2 3 @^0x200 @\-2 le16:0xaa55\*(Aq
.Ve
.PP
Fields in the string can be:
.IP BYTE 4
.IX Item "BYTE"
Write a byte at the current offset and advance the offset by 1.  The
byte may be specified as either decimal, octal (prefixed by \f(CW0\fR) or
hexadecimal (prefixed by \f(CW\*(C`0x\*(C'\fR).  To add repeated bytes use the \f(CW\*(C`*\*(C'\fR
operator (eg. \f(CW\*(C`0xFF*16\*(C'\fR).
.IP \fBle16:\fRWORD 4
.IX Item "le16:WORD"
.PD 0
.IP \fBbe16:\fRWORD 4
.IX Item "be16:WORD"
.IP \fBle32:\fRWORD 4
.IX Item "le32:WORD"
.IP \fBbe32:\fRWORD 4
.IX Item "be32:WORD"
.IP \fBle64:\fRWORD 4
.IX Item "le64:WORD"
.IP \fBbe64:\fRWORD 4
.IX Item "be64:WORD"
.PD
(nbdkit ≥ 1.28)
.Sp
Write a word expressed in little endian (le) or big endian (be) of
length 16/32/64 bits and advance the offset by 2/4/8.  The word may be
specified in decimal, octal or hexadecimal.  For example:
.Sp
.Vb 1
\& nbdkit data \*(Aq be32:0x1 \*(Aq
.Ve
.Sp
generates the 4 byte sequence \f(CW\*(C`0 0 0 1\*(C'\fR.
.IP \fBbase64:\fRBASE64 4
.IX Item "base64:BASE64"
(nbdkit ≥ 1.46)
.Sp
Decode the BASE64 string into bytes and write these into the image.
The offset is advanced by the number of decoded bytes.  The BASE64
string cannot contain any whitespace.
.Sp
This is only supported if nbdkit was compiled with GnuTLS\ ≥\ 3.6.0.
The output of \f(CW\*(C`nbdkit data \-\-dump\-plugin\*(C'\fR will contain
\&\f(CW\*(C`data_base64=yes\*(C'\fR.
.IP \fB@\fROFFSET 4
.IX Item "@OFFSET"
Moves the current offset to \f(CW\*(C`OFFSET\*(C'\fR.  The offset may be specified as
either decimal, octal (prefixed by \f(CW0\fR) or hexadecimal (prefixed by
\&\f(CW\*(C`0x\*(C'\fR); when using decimal, it is also possible to supply a scaling
suffix such as \f(CW\*(C`k\*(C'\fR or \f(CW\*(C`M\*(C'\fR.  Offset \f(CW@0\fR is the first byte of the disk.
.IP \fB@+\fRN 4
.IX Item "@+N"
.PD 0
.IP \fB@\-\fRN 4
.IX Item "@-N"
.PD
(nbdkit ≥ 1.22)
.Sp
Add or subtract \f(CW\*(C`N\*(C'\fR from the current offset.
.IP \fB@^\fRALIGNMENT 4
.IX Item "@^ALIGNMENT"
(nbdkit ≥ 1.22)
.Sp
If the current offset is not a multiple of \f(CW\*(C`ALIGNMENT\*(C'\fR then the
offset is moved forward to the next multiple.  The next byte written
will be aligned to \f(CW\*(C`ALIGNMENT\*(C'\fR.
.IP \fB<\fRFILE 4
.IX Item "<FILE"
(nbdkit ≥ 1.8)
.Sp
Read the contents of binary \fIFILE\fR into the disk image at the current
offset.  The offset is incremented by the size of the file.  The
filename can be a relative or absolute path, but cannot contain
whitespace in the name.
.IP \fB<(\fRSCRIPT\fB)\fR 4
.IX Item "<(SCRIPT)"
(nbdkit ≥ 1.24, not Windows)
.Sp
Substitute the output of the shell script or external program as a
binary blob and advance the offset by the length in bytes of the
output.  You can use this to create more complex test patterns.  For
example this produces a 32K disk image with an incrementing test
pattern in groups of 4 bytes:
.Sp
.Vb 4
\& nbdkit data \*(Aq <( i=0
\&                  while :; do
\&                      printf "%04d" $i; i=$((i+1))
\&                  done )[:32768] \*(Aq
.Ve
.Sp
The script may contain \f(CW\*(C`(\*(C'\fR and \f(CW\*(C`)\*(C'\fR characters, but they must be in
matching pairs.  A script can produce a finite amount of output; or
(as in the example) an infinite amount which must be truncated using
the \f(CW\*(C`[:len]\*(C'\fR slice operator.
.Sp
Scripts must be idempotent, producing the same output each time they
are run.  This is because optimizations might change the order of
evaluation or number of times the script is called and you could get
different output in a future version of nbdkit.
.Sp
Note that the script is passed to \fI/bin/sh\fR.  On some platforms like
Debian this might not be a full\-featured shell.
.IP "\fB""\fRSTRING\fB""\fR" 4
.IX Item """STRING"""
(nbdkit ≥ 1.22)
.Sp
Write a string into the image at the current offset and advance the
offset by the length of the string.  To include special characters in
the string you can escape them in the same way as C strings (eg. a
double quote character within the string should be written \f(CW\*(C`\e"\*(C'\fR).  Be
careful with shell quoting around the whole data parameter.
.IP "\fB(\fR ... \fB)\fR" 4
.IX Item "( ... )"
(nbdkit ≥ 1.24)
.Sp
Group a set of expressions into a single expression.
.Sp
\&\f(CW\*(C`(\ ...\ )\*(C'\fR recursively creates a new data parser so any expression
can appear inside, including nested \f(CW\*(C`(\ ...\ )\*(C'\fR.  Note that offsets
and alignments within the subpattern are relative to the start of the
subpattern, not relative to the final disk image.
.IP "expression \fB*\fR N" 4
.IX Item "expression * N"
(nbdkit ≥ 1.24)
.Sp
Repeat the expression \f(CW\*(C`N\*(C'\fR times.  The offset is incremented by the
length of the expression × N.  For example to create a repeating
pattern of 0x55, 0xAA for 512 (2×256) bytes do:
.Sp
.Vb 1
\& nbdkit data \*(Aq( 0x55 0xAA ) * 256\*(Aq
.Ve
.IP "expression \fB[\fRN\fB:\fRM\fB]\fR" 4
.IX Item "expression [N:M]"
.PD 0
.IP "expression \fB[\fRstart\fB:]\fR" 4
.IX Item "expression [start:]"
.IP "expression \fB[:\fRlen\fB]\fR" 4
.IX Item "expression [:len]"
.PD
(nbdkit ≥ 1.24)
.Sp
Take a slice of the expression.  Slices are \fB[\fRstart\fB:\fRend+1\fB]\fR
where \fIstart\fR and \fIend\fR are the first and last byte offsets of the
expression desired.  Either or both may be omitted.
.Sp
\&\fB[\fRstart\fB:]\fR means to take bytes from offset \fIstart\fR to the end
of the expression.  \fB[:\fRlen\fB]\fR means truncate the expression to
\&\fIlen\fR bytes.
.IP "expression \fB\-> \e\fRNAME" 4
.IX Item "expression -> NAME"
.PD 0
.IP \fB\e\fRNAME 4
.IX Item "NAME"
.PD
(nbdkit ≥ 1.24)
.Sp
Assign an expression to a name which can be used later.  Names can be
used in the current scope (or any scopes nested within the current
scope), but disappear at the end of the current scope.  Names start
with a backslash character followed by one or more alphanumeric, dash
and underscore.  For example this makes two identical sectors both
containing a boot signature at the end:
.Sp
.Vb 3
\& nbdkit data \*(Aq ( 0x55 0xAA ) \-> \eboot\-signature
\&               ( @0x1fe \eboot\-signature ) \-> \esector
\&               \esector \esector \*(Aq
.Ve
.IP \fB$\fRVAR 4
.IX Item "$VAR"
(nbdkit ≥ 1.24)
.Sp
Substitute command line parameters or environment variables.  The
variable is written in the same language as the \f(CW\*(C`data\*(C'\fR parameter, and
when substituted it creates a nested scope like \f(CW\*(C`(\ ...\ )\*(C'\fR
expressions.  These three commands do the same thing:
.Sp
.Vb 1
\& nbdkit data \*(Aq$pattern*16\*(Aq pattern=\*(Aq0x55 0xAA\*(Aq
.Ve
.Sp
.Vb 1
\& export pattern=\*(Aq0x55 0xAA\*(Aq ; nbdkit data \*(Aq$pattern*16\*(Aq
.Ve
.Sp
.Vb 1
\& nbdkit data \*(Aq( 0x55 0xAA )*16\*(Aq
.Ve
.IP "\fB#\fR COMMENT" 4
.IX Item "# COMMENT"
(nbdkit ≥ 1.24)
.Sp
\&\f(CW\*(C`#\*(C'\fR begins a comment stretching to the end of the current line.
.SS "disk2data.pl script"
.IX Subsection "disk2data.pl script"
This script can convert from small disk images into the data format
described above.
.PP
It is provided in the nbdkit sources.  See
https://gitlab.com/nbdkit/nbdkit/blob/master/plugins/data/disk2data.pl
.SH FILES
.IX Header "FILES"
.ie n .IP \fR\fI$plugindir\fR\fI/nbdkit\-data\-plugin.so\fR 4
.el .IP \fR\f(CI$plugindir\fR\fI/nbdkit\-data\-plugin.so\fR 4
.IX Item "$plugindir/nbdkit-data-plugin.so"
The plugin.
.Sp
Use \f(CW\*(C`nbdkit \-\-dump\-config\*(C'\fR to find the location of \f(CW$plugindir\fR.
.SH VERSION
.IX Header "VERSION"
\&\f(CW\*(C`nbdkit\-data\-plugin\*(C'\fR first appeared in nbdkit 1.6.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fBnbdkit\fR\|(1),
\&\fBnbdkit\-captive\fR\|(1),
\&\fBnbdkit\-plugin\fR\|(3),
\&\fBnbdkit\-info\-plugin\fR\|(1),
\&\fBnbdkit\-memory\-plugin\fR\|(1),
\&\fBnbdkit\-null\-plugin\fR\|(1),
\&\fBnbdkit\-ones\-plugin\fR\|(1),
\&\fBnbdkit\-partitioning\-plugin\fR\|(1),
\&\fBnbdkit\-pattern\-plugin\fR\|(1),
\&\fBnbdkit\-random\-plugin\fR\|(1),
\&\fBnbdkit\-sparse\-random\-plugin\fR\|(1),
\&\fBnbdkit\-tmpdisk\-plugin\fR\|(1),
\&\fBnbdkit\-zero\-plugin\fR\|(1),
https://gitlab.com/nbdkit/nbdkit/blob/master/plugins/data/disk2data.pl,
https://en.wikipedia.org/wiki/Base64.
.SH AUTHORS
.IX Header "AUTHORS"
Richard W.M. Jones
.SH COPYRIGHT
.IX Header "COPYRIGHT"
Copyright Red Hat
.SH LICENSE
.IX Header "LICENSE"
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
.IP \(bu 4
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
.IP \(bu 4
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
.IP \(bu 4
Neither the name of Red Hat nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
.PP
THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS \*(Aq\*(AqAS IS\*(Aq\*(Aq AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
