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