qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

blockdev-snapshot


From: Peter Krempa
Subject: blockdev-snapshot
Date: Wed, 23 Oct 2019 13:20:21 +0200
User-agent: Mutt/1.12.1 (2019-06-15)

Hi,

I've come accross a problem when libvirt tries to do an external
snapshot in blockdev mode:

Libvirt uses the following commandline:

The VM is started with one disk with a single image:
-blockdev {"driver":"file",
           "filename":"/tmp/pull4.qcow2",
           "node-name":"libvirt-1-storage",
           "auto-read-only":true,
           "discard":"unmap"}
-blockdev {"node-name":"libvirt-1-format",
           "read-only":false,
           "driver":"qcow2",
           "file":"libvirt-1-storage",
           "backing":null}

We then want to create two external snapshots. Libvirt uses the
following monitor commands to achieve that in the current
implementation:

{"execute":"blockdev-add",
 "arguments":{"driver":"file",
              "filename":"/tmp/pull4.s1",
              "node-name":"libvirt-3-storage",
              "auto-read-only":true,
              "discard":"unmap"},
 "id":"libvirt-381"}

{"execute":"blockdev-create",
 "arguments":{"job-id":"create-libvirt-3-format",
              "options":{"driver":"qcow2",
                         "file":"libvirt-3-storage",
                         "size":10485760,
                         "backing-file":"/tmp/pull4.qcow2",
                         "backing-fmt":"qcow2"}},
 "id":"libvirt-382"}

 [1]

 (create job handling snipped)

{"execute":"blockdev-add",
 "arguments":{"node-name":"libvirt-3-format",
              "read-only":false,
              "driver":"qcow2",
              "file":"libvirt-3-storage",
              "backing":null},
 "id":"libvirt-385"}

 [2]

{"execute":"transaction",
 "arguments":{"actions":[ {"type":"blockdev-snapshot",
                           "data":{"node":"libvirt-1-format",
                                   "overlay":"libvirt-3-format"}}]},
 "id":"libvirt-386"}

After this step everything is as expected. query blockstats (which
handily reports node name hierarchy shows that the chain is as expected:

(I've truncated the irrelevant info, libvirt-2-* is an cdrom image which
I've snipped off):

    {
      "device": "",
      "parent": {
        "node-name": "libvirt-3-storage"
      },
      "backing": {
        "parent": {
          "node-name": "libvirt-1-storage"
        },
        "node-name": "libvirt-1-format"
      },
      "node-name": "libvirt-3-format",
      "qdev": "/machine/peripheral/virtio-disk0/virtio-backend"
    }

So then when I attempt to create a second snapshot with basically the
same commands just with the nodenames/filenames tweaked:

{"execute":"blockdev-add",
 "arguments":{"driver":"file",
              "filename":"/tmp/pull4.s2",
              "node-name":"libvirt-4-storage",
              "auto-read-only":true,"
              discard":"unmap"},
 "id":"libvirt-389"}
{"execute":"blockdev-create",
 "arguments":{"job-id":"create-libvirt-4-format",
              "options":{"driver":"qcow2",
                         "file":"libvirt-4-storage",
                         "size":10485760,
                         "backing-file":"/tmp/pull4.s1",
                         "backing-fmt":"qcow2"}},
 "id":"libvirt-390"}
{"execute":"blockdev-add",
 "arguments":{"node-name":"libvirt-4-format",
              "read-only":false,
              "driver":"qcow2",
              "file":"libvirt-4-storage",
              "backing":null},
 "id":"libvirt-393"}
{"execute":"transaction",
 "arguments":{"actions":[{"type":"blockdev-snapshot",
                          "data":{"node":"libvirt-3-format",
                                  "overlay":"libvirt-4-format"}}]},
"id":"libvirt-394"}

After this step the problem is visible:

    {
      "device": "",
      "parent": {
        "node-name": "libvirt-4-storage"
      },
      "backing": {
        "parent": {
          "node-name": "libvirt-3-storage"
        },
        "node-name": "libvirt-3-format"
      },
      "node-name": "libvirt-4-format",
      "qdev": "/machine/peripheral/virtio-disk0/virtio-backend"
    }

QEMU now does not consider 'libvirt-1-format' part of the backing chain.
I presume this happens as the blockdev-add step above [1] has
backing:null and blockdev-snapshot does not fix it in any way. Then once
a reopen happens the backing is dropped as per the specification.

Libvirt uses backing:null to prevent qemu from opening the images in the
backing-file field as that would fail anyways due to image locking.

Similarly we can't use backing:nodename-of-the-currently-active-image
as it's currently in write mode and using it as a backing fails:

Node 'libvirt-1-format' is busy: node is used as backing hd of 
'libvirt-3-format'

So this leaves us with one option only. We can omit the backing file
name and format during blockdev-create, blockdev-add it and then use
change-backing-file QMP command to update the backing store string once
the image is opened.

Since I'm not a fan of hacks I'd like to know whether this is expected
behaviour of blockdev-snapshot.

If it is expected and thus we'll have to resort to using
change-backing-file, I'd like to also know whether the undocumented
detail that change-backing-file also writes the backing-fmt field is
expected and whether it perhaps can be documented to prevent regressing
in the future.

Thanks.

Peter




reply via email to

[Prev in Thread] Current Thread [Next in Thread]