QEMU NBD server and client in action

Purpose

Create a point-in-time (PIT) snapshot of a live disk, and export it via QEMU’s built-in NBD server. Then, using QEMU’s NBD client (qemu-nbd), copy off the content from the NBD export into a QCOW2 file. Finally, verify that the copy is not corrupted.

Environment

Tested with QEMU built from Git: v3.1.0-1473-g1c3d45df5e-dirty. But QEMU in Fedora-29 will also suffice.

Server side setup

Create a PIT snapshot, setup the NBD server, and export the PIT snapshot via the NBD.

  1. Launch QEMU with a QMP socket:

    $ ./x86_64-softmmu/qemu-system-x86_64 -display none \
        -M q35 -nodefaults -m 512 \
        -blockdev node-name=node-A,driver=qcow2,file.driver=file,file.node-name=file,file.filename=./a.qcow2 \
        -device virtio-blk,drive=node-A,id=virtio0 \
        -monitor stdio -qmp unix:/tmp/qmp-sock,server,nowait
    
  2. Following are the sequence of QMP commands to export a PIT “snapshot” and exported via NBD using the qmp-shell:

    $> qemu-img create -f qcow2 /export/target.qcow2 44M
    
    $ ./qmp-shell -v -p /tmp/qmp-sock
    (QEMU) query-version
    [...]
            "package": "v3.1.0-1473-g1c3d45df5e-dirty"
    [...]
    
    
    (QEMU) blockdev-add driver=qcow2 node-name=node-Target file={"driver":"file","filename":"/export/target.qcow2"} backing=node-A
    (QEMU) blockdev-backup device=node-A target=node-Target sync=none job-id=job1
    (QEMU) nbd-server-start addr={"type":"unix","data":{"path":"./nbd-sock"}}
    (QEMU) nbd-server-add device=node-Target
    

Connect with the NBD client

As a simple first step prove that the NBD server is actually offering an export (since we didn’t choose any name, the export is named ‘node-Target’ after the device):

$> ./qemu-nbd --list --socket /tmp/nbd-sock
exports available: 1
 export: 'node-Target'
  size:  16384
  flags: 0x4ef ( readonly flush fua trim zeroes df cache )
  min block: 512
  opt block: 4096
  max block: 33554432
  available meta contexts: 1
   base:allocation

Then, copy off the content from the NBD export into a QCOW2 file:

$> qemu-img convert -f raw -O qcow2 \
    "nbd+unix:///node-Target?socket=/tmp/nbd-sock" copy.qcow2
$> echo $?
0

Test the copy

Do a “sanity check” by observing the presence of guest OS in the copy:

$> ls -lash /export/a.qcow2 copy.qcow2
22M -rw-r--r--. 1 kashyapc kashyapc 22M Feb  5 21:02 copy.qcow2
16M -rw-rw-r--. 1 kashyapc kashyapc 16M Feb  5 20:45 /export/a.qcow2

$> guestfish --rw -i -a copy.qcow2

Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.

Type: ‘help’ for help on commands
      ‘man’ to read the manual
      ‘quit’ to quit the shell

Operating system: 0.3.5
/dev/sda1 mounted on /

><fs

Stop the NBD server

Finally, stop the NBD server (on the ‘qmp-shell’):

(QEMU) nbd-server-stop