nbd_connect_command - connect to NBD server command
#include <libnbd.h>
int nbd_connect_command (
struct nbd_handle *h, char **argv
);
Run the command as a subprocess and connect to it over stdin/stdout. This is for use with NBD servers which can behave like inetd clients, such as nbdkit(1) using the -s/--single flag, and nbd-server(1) with port number set to 0.
To run qemu-nbd(1), use nbd_connect_systemd_socket_activation(3) instead.
Libnbd will fork the argv command and pass the NBD socket to it using file descriptors 0 and 1 (stdin/stdout):
┌─────────┬─────────┐ ┌────────────────┐
│ program │ libnbd │ │ NBD server │
│ │ │ │ (argv) │
│ │ socket ╍╍╍╍╍╍╍╍▶ stdin/stdout │
└─────────┴─────────┘ └────────────────┘
When the NBD handle is closed the server subprocess is killed.
If the call is successful the function returns 0.
On error -1 is returned.
Refer to "ERROR HANDLING" in libnbd(3) for how to get further details of the error.
The following parameters must not be NULL: h, argv. For more information see "Non-NULL parameters" in libnbd(3).
This call returns when the connection has been made. By default, this proceeds all the way to transmission phase, but nbd_set_opt_mode(3) can be used for manual control over option negotiation performed before transmission phase.
nbd_connect_command can be called when the handle is in the following state:
┌─────────────────────────────────────┬─────────────────────────┐
│ Handle created, before connecting │ ✅ allowed │
│ Connecting │ ❌ error │
│ Connecting & handshaking (opt_mode) │ ❌ error │
│ Connected to the server │ ❌ error │
│ Connection shut down │ ❌ error │
│ Handle dead │ ❌ error │
└─────────────────────────────────────┴─────────────────────────┘
This function first appeared in libnbd 1.0.
If you need to test if this function is available at compile time check if the following macro is defined:
#define LIBNBD_HAVE_NBD_CONNECT_COMMAND 1
This example is also available as examples/connect-command.c in the libnbd source code.
/* This example shows how to run an NBD server
* (nbdkit) as a subprocess of libnbd.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libnbd.h>
int
main (int argc, char *argv[])
{
struct nbd_handle *nbd;
char wbuf[512], rbuf[512];
size_t i;
/* Create the libnbd handle. */
nbd = nbd_create ();
if (nbd == NULL) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
/* Run nbdkit as a subprocess. */
char *args[] = {
"nbdkit",
/* You must use ‘-s’ (which tells nbdkit to serve
* a single connection on stdin/stdout).
*/
"-s",
/* It is recommended to use ‘--exit-with-parent’
* to ensure nbdkit is always cleaned up even
* if the main program crashes.
*/
"--exit-with-parent",
/* Use this to enable nbdkit debugging. */
"-v",
/* The nbdkit plugin name - this is a RAM disk. */
"memory", "size=1M",
/* Use NULL to terminate the arg list. */
NULL
};
if (nbd_connect_command (nbd, args) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
/* Write some random data to the first sector. */
for (i = 0; i < sizeof wbuf; ++i)
wbuf[i] = i % 13;
if (nbd_pwrite (nbd, wbuf, sizeof wbuf, 0, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
/* Read the first sector back. */
if (nbd_pread (nbd, rbuf, sizeof rbuf, 0, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
/* Close the libnbd handle. */
nbd_close (nbd);
/* What was read must be exactly the same as what
* was written.
*/
if (memcmp (rbuf, wbuf, sizeof rbuf) != 0) {
fprintf (stderr, "FAILED: "
"read data did not match written data\n");
exit (EXIT_FAILURE);
}
exit (EXIT_SUCCESS);
}
nbd_aio_connect_command(3), nbd_connect_systemd_socket_activation(3), nbd_create(3), nbd_get_subprocess_pid(3), nbd_kill_subprocess(3), nbd_set_opt_mode(3), libnbd(3), nbdkit(1).
Eric Blake
Richard W.M. Jones
Copyright Red Hat
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA