nbd_pread(3)

πŸ’… nbd_pread(3) β€” ok so this is the libnbd read situation

Alright bestie, grab a snack πŸ“ because we're talking about nbd_pread from the LIBNBD manual (section 3, iykyk). It's the "just read the whole thing please" call, and honestly it's giving main character energy in the NBD world.


✨ NAME ✨

nbd_pread β€” read from the NBD server πŸ“–


✨ SYNOPSIS ✨

#include <libnbd.h>

int nbd_pread (
      struct nbd_handle *h, void *buf, size_t count,
      uint64_t offset, uint32_t flags
    );

✨ DESCRIPTION ✨

So basically πŸ’β€β™€οΈ you're issuing a read command to the NBD server for the range that starts at offset and ends at offset + count - 1. And like β€” NBD can only read all or nothing with this call. No lil' partials, no half-a-vibe. The call comes back once the data has been read fully into buf, or once there's an error. Periodt.

Also go look at nbd_pread_structured(3) if you want finer visibility into what the server's actually replying with, or if you wanna use LIBNBD_CMD_FLAG_DF πŸ‘€

Heads up bestie 🚨 β€” libnbd currently enforces a maximum read buffer of 64MiB, even if the server would let you have a bigger buffer in a single transaction. Try to exceed it and you get an ERANGE error, no cap. And the server might enforce a smaller limit than that too β€” you can find out what it is with nbd_get_block_size(3).

The flags parameter must be 0 for now (it's just sitting there existing for future NBD protocol extensions, we love a forward-thinking icon).

Also, important: if this command fails, and nbd_get_pread_initialize(3) returns true, then libnbd sanitized buf β€” but it is unspecified whether the contents of buf will read as zero or as partial results from the server. If nbd_get_pread_initialize(3) returns false, then libnbd did not sanitize buf, and the contents are undefined on failure 😭 so don't go reading garbage and blaming us.


✨ RETURN VALUE ✨

If the call is successful, the function returns 0. Slay.


✨ ERRORS ✨

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, buf. For more info, see "Non-NULL parameters" in libnbd(3).


✨ NOTES ✨

πŸŽ€ Strict call

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure β€” like, say, requesting an unknown command flag πŸ‘€. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.


✨ HANDLE STATE ✨

nbd_pread can be called when the handle is in the following state:

  • Handle created, before connecting β€” ❌ error
  • Connecting β€” ❌ error
  • Connecting & handshaking (opt_mode) β€” ❌ error
  • Connected to the server β€” βœ… allowed
  • Connection shut down β€” ❌ error
  • Handle dead β€” ❌ error

So yeah, the handle has to actually be connected. Vibe check: failed for everything else 🫢


✨ VERSION ✨

This function first appeared in libnbd 1.0. OG behavior, honestly.

If you need to test if this function is available at compile time, check if the following macro is defined:

#define LIBNBD_HAVE_NBD_PREAD 1

✨ EXAMPLE ✨

This example is also available as examples/fetch-first-sector.c in the libnbd source code πŸ”₯

/* This example shows how to connect to an NBD server
 * and fetch and print the first sector (usually the
 * boot sector or partition table or filesystem
 * superblock).
 *
 * You can test it with nbdkit like this:
 *
 * nbdkit -U - floppy . \
 *   --run './fetch-first-sector $unixsocket'
 *
 * The nbdkit floppy plugin creates an MBR disk so the
 * first sector is the partition table.
 */

#include <stdio.h>
#include <stdlib.h>

#include <libnbd.h>

int
main (int argc, char *argv[])
{
  struct nbd_handle *nbd;
  char buf[512];
  FILE *pp;

  if (argc != 2) {
    fprintf (stderr, "%s socket\n", argv[0]);
    exit (EXIT_FAILURE);
  }

  /* Create the libnbd handle. */
  nbd = nbd_create ();
  if (nbd == NULL) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Connect to the NBD server over a
   * Unix domain socket.
   */
  if (nbd_connect_unix (nbd, argv[1]) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Read the first sector synchronously. */
  if (nbd_pread (nbd, buf, sizeof buf, 0, 0) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Close the libnbd handle. */
  nbd_close (nbd);

  /* Print the first sector. */
  pp = popen ("hexdump -C", "w");
  if (pp == NULL) {
    perror ("popen: hexdump");
    exit (EXIT_FAILURE);
  }
  fwrite (buf, sizeof buf, 1, pp);
  pclose (pp);

  exit (EXIT_SUCCESS);
}

✨ SEE ALSO ✨

nbd_aio_pread(3), nbd_create(3), nbd_get_block_size(3), nbd_get_pread_initialize(3), nbd_pread_structured(3), nbd_set_pread_initialize(3), nbd_set_strict_mode(3), libnbd(3). Go read them all, they're icons πŸ’œ


✨ AUTHORS ✨

Eric Blake

Richard W.M. Jones


Copyright Red Hat


✨ LICENSE ✨

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


okay that's the whole page bestie πŸ’– bye!! πŸ¦‹

Much love from the libnbd girlies β€” this was libnbd-1.25.8, dated 2026-10-13, and yes nbd_pread(3) is the manual page you just read πŸŽ€

πŸ“¦ where this page comes from