1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
=head1 NAME
nbdkit-captive - run nbdkit under another process and have it
reliably cleaned up
=head1 SYNOPSIS
nbdkit PLUGIN [...] [-e|--exportname EXPORTNAME] \
--run 'COMMAND ARGS ...'
=for paragraph
nbdkit --exit-with-parent PLUGIN [...]
=head1 DESCRIPTION
You can run nbdkit under another process and have nbdkit reliably
clean up. There are two techniques depending on whether you want
nbdkit to start the other process (L</CAPTIVE NBDKIT>), or if you want
the other process to start nbdkit (L</EXIT WITH PARENT>). Another way
is to have nbdkit exit after the last client connection
(L<nbdkit-exitlast-filter(1)>) or after an event
(L<nbdkit-exitwhen-filter(1)>).
=head1 CAPTIVE NBDKIT
You can run nbdkit as a "captive process", using the I<--run> option.
This means that nbdkit runs as long as (for example) L<qemu(1)> or
L<guestfish(1)> is running. When those exit, nbdkit is killed.
Some examples should make this clear.
To run nbdkit captive under qemu:
nbdkit file disk.img --run 'qemu -drive file="$uri",if=virtio'
On the qemu command line, C<$uri> is substituted automatically with
the right NBD path so it can connect to nbdkit. When qemu exits,
nbdkit is killed and cleaned up automatically.
Running nbdkit captive under guestfish:
nbdkit file disk.img --run 'guestfish --format=raw -a "$uri" -i'
When guestfish exits, nbdkit is killed.
Running nbdkit captive under nbdsh for unit testing:
nbdkit memory 1 --run 'nbdsh -u "$uri" -c "print(h.pread(1, 0))"'
Running an fio benchmark:
nbdkit -f null 1G --run 'export uri; fio fio.git/examples/nbd.fio'
The following shell variables are available in the I<--run> argument
(local to the run script unless you use C<export>):
=over 4
=item C<$uri>
=item C<$nbd>
A URI that refers to the nbdkit port or socket in the preferred form
documented by the NBD project.
As this variable may contain a bare C<?> for Unix sockets, it is
safest to use $uri within double quotes to avoid unintentional
globbing. For plugins that support distinct data based on export
names, the I<-e> option to nbdkit controls which export name will be
set in the URI.
In nbdkit E<le> 1.22 C<$nbd> tried to guess if you were using qemu or
guestfish and expanded differently. Since NBD URIs are now widely
supported this magic is no longer necessary. In nbdkit E<ge> 1.24
both variables expand to the same URI.
See also L<nbdkit(1)/NBD URIs and endpoints>.
=item C<$port>
If E<ne> "", the port number that nbdkit is listening on.
=item C<$unixsocket>
If E<ne> "", the Unix domain socket that nbdkit is listening on.
=item C<$exportname>
The export name (which may be "") that the process should use when
connecting to nbdkit, as set by the I<-e> (I<--exportname>) command
line option of nbdkit. This only matters to plugins that
differentiate what they serve based on the export name requested by
the client.
=item C<$tls>
Corresponds to the I<--tls> option passed to nbdkit. If I<--tls=off>
this is not set. If I<--tls=on> this is set to C<"1">. If
I<--tls=require> this is set to C<"2">.
=item C<$tls_certificates>
If I<--tls-certificates> was passed to nbdkit, the value is copied
here. It is usually the directory containing PKI certificates. Note
that the path might not be an absolute path, or even valid.
=item C<$tls_psk>
If I<--tls-psk> was passed to nbdkit, the value is copied here. It is
usually the filename of a TLS Pre-Shared Keys (PSK) file. Note that
the filename might not be an absolute path, or even valid.
=back
I<--run> implies I<--foreground>. It is not possible, and probably
not desirable, to have nbdkit fork into the background when using
I<--run>.
=head2 Copying data in and out of plugins with captive nbdkit
Captive nbdkit + L<qemu-img(1)> can be used to copy data into and out
of nbdkit plugins. For example L<nbdkit-example1-plugin(1)> contains
an embedded disk image. To copy it out:
nbdkit example1 --run 'qemu-img convert "$uri" disk.img'
If the source suffers from temporary network failures
L<nbdkit-retry-filter(1)> or L<nbdkit-retry-request-filter(1)> may
help.
To overwrite a file inside an uncompressed tar file (the file being
overwritten must be the same size), use L<nbdkit-tar-filter(1)> like
this:
nbdkit file data.tar --filter=tar tar-entry=disk.img \
--run 'qemu-img convert -n disk.img "$uri"'
=head1 EXIT WITH PARENT
The I<--exit-with-parent> option is almost the opposite of
L</CAPTIVE NBDKIT> described in the previous section.
Running nbdkit with this option, for example from a script:
nbdkit --exit-with-parent plugin ... &
means that nbdkit will exit automatically if the parent program exits
for any reason. This can be used to avoid complicated cleanups or
orphaned nbdkit processes.
I<--exit-with-parent> is incompatible with forking into the background
(because when we fork into the background we lose track of the parent
process). Therefore I<-f> / I<--foreground> is implied.
If the parent application is multithreaded, then (in the Linux
implementation) if the parent I<thread> exits, that will cause nbdkit
to exit. Thus in multithreaded applications you usually want to run
C<nbdkit --exit-with-parent> only from the main thread (unless you
actually want nbdkit to exit with the thread, but that may not work
reliably on all operating systems).
To exit when an unrelated process exits, use
L<nbdkit-exitwhen-filter(1)> C<exit-when-process-exits> feature.
=head2 Support for --exit-with-parent
This is currently implemented using a non-POSIX feature available in
S<Linux ≥ 2.1.57>, S<FreeBSD ≥ 11.2> and macOS. It won't work on
other operating systems (patches welcome to make it work).
To test if the current binary supports this feature the most backwards
compatible way is:
nbdkit --exit-with-parent --version && echo "supported"
In nbdkit E<ge> 1.34, S<C<nbdkit --dump-config>> prints either
C<exit_with_parent=yes> or C<exit_with_parent=no> but earlier versions
did not have this.
=head1 SEE ALSO
L<nbdkit(1)>,
L<nbdkit-exitlast-filter(1)>,
L<nbdkit-exitwhen-filter(1)>,
L<prctl(2)> (on Linux),
L<procctl(2)> (on FreeBSD).
=head1 AUTHORS
Eric Blake
Richard W.M. Jones
Pino Toscano
=head1 COPYRIGHT
Copyright Red Hat
|