Suppose you want to edit or read or write the data inside a qcow2 file? One way is to use libguestfs, and that’s the recommended way if you need to mount a filesystem inside the file.
But for accessing the data blocks alone, you can now use the libnbd API and qemu-nbd together and this has a couple of advantages: It’s faster and you can open snapshots (which libguestfs cannot do).
We start by creating a libnbd handle and connecting it to a qemu-nbd instance. The qemu-nbd instance is linked with qemu’s internal drivers that know how to read and write qcow2.
const char *filename;
struct nbd_handle *nbd;
nbd = nbd_create ();
if (nbd == NULL) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
char *args[] = {
"qemu-nbd", "-f", "qcow2",
// "-s", snapshot,
(char *) filename,
NULL
};
if (nbd_connect_systemd_socket_activation (nbd, args) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
Now you can get the virtual size:
int64_t size = nbd_get_size (nbd);
printf ("virtual size = %" PRIi64 "\n", size);
Or read and write sectors from the file:
if (nbd_pread (nbd, buf, sizeof buf, 0, 0) == -1) {
fprintf (stderr, "%s\n", nbd_get_error ());
exit (EXIT_FAILURE);
}
Once you’re done with the file, call nbd_close on the handle which will also shut down the qemu-nbd process.

Pingback: libnbd + FUSE = nbdfuse | Richard WM Jones