2

I want to transfer block device contents over the network directly into a qcow2 image. I started with a small simulation:

[root@okvmh1 default]# dd if=/dev/zero bs=1M count=100 | qemu-img convert -p -f raw -O qcow2 /dev/stdin aaa.qcow2
qemu-img: Could not open '/dev/stdin': Could not refresh total sector count: Operation not permitted
qemu-img: Could not open '/dev/stdin'

It seems that qemu-img does not know the desired image size. In VirtualBox I would do:

<net-command> | VBoxManage convertfromraw stdin aaa.vdi $size --format VDI

But qemu-img convert does not accept the size parameter.

basin
  • 558
  • 1
  • 5
  • 22

3 Answers3

3

Standard input is not seekable, which is what qemu-img convert is trying to do here.

To work around the problem, use an input image which is a file on the filesystem or a block device, both of which are seekable.

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
2

Emulate a Device over a QCOW2 image

Although this is an old question I think it should be worth to show an interesting alternative. I had the same problem, but the provided answer from Michael Hampton would not fit for me as the amount of data I had to transfer was too big and the time I had to do the operation would not be enough. So below is what I made:

Create an empty QCOW2 image

In destination, create an empty QCOW2 image, for example:

$ qemu-img create -f qcow2 myimage.qcow2 500g

Connect the QCOW2 image using NBD to a device

There is a tool that allows you to emulate a device on top of a QCOW2 image. This is mostly used to get access to QCOW2 contents, but the device is read-writable so you can treat it as a standard block device:

$ modprobe nbd
$ qemu-nbd --connect /dev/nbd0 myimage.qcow2

Now you have a /dev/nbd0 device that is a block device just like any block device but any operation done over it will be performed on the QCOW2 image

Perform the transfer over the emulated device

You can use any network command, for example ssh and dd to make the magic work:

$ dd if=myoriginalimg bs=100M | pv -tebrap --size 500g | ssh myhost dd of=/dev/nbd0 bs=100M

I added a plus using pv so you can monitor the progress. I further advice you to run this command inside a screen or tmux session if it may take very long so you do not loose your job!

Close the emulator

After the transfer is complete, you have a ready and converted QCOW2 image on myimage.qcow2, but make sure you disconnect the emulator so kernel don't get angry on you!

$ qemu-nbd --disconnect /dev/nbd0

You are done! Now you have a ready converted image transmitted from a raw format from a network origin directly to a QCOW2 file without intermediates

RDP
  • 388
  • 3
  • 6
0

Streaming disk images using dd or similar is not a good idea because it doesn't preserve sparseness. Nevertheless if you don't care about that there is an nbdkit plugin which can do exactly what you want. You will still need to know the virtual size in advance because qcow2 needs to know that in order to create the qcow2 container.

Rich
  • 101
  • 1