3

I'm working on a custom OS, and the make recipe I wrote for creating a new disk image requires sudo for connecting/disconnecting the virtual HDD image to a /dev/nbdN device. Because I don't want sudo in the recipe, I've just been using sudo make disk.

I thought I could just add myself to the disk group (as stat /dev/nbd0 shows the UID of the file is root, and GID is disk) so I could attach and detach the /dev/nbdN devices without sudo, but it still doesn't work (yes, I've logged out and logged back in, and id shows me in group disk).

Do I still have to be root for ioctl calls to succeed (this is where it seems to fail if I'm not root)? Or is there something else specific to qemu-nbd that I need to do to avoid having use root?

Edit: my command is this (I have R/W permissions for hda.qcow2):

$ qemu-nbd -c /dev/nbd0 hda.qcow2

And the output is this:

/build/buildd/qemu-2.0.0+dfsg/nbd.c:nbd_init():L504: Failed to set NBD socket
/build/buildd/qemu-2.0.0+dfsg/nbd.c:nbd_receive_request():L638: read failed

Running the same command with sudo executes successfully with no output.

OS is Ubuntu 14.04 x64.

4
  • What command(s) are you exactly running and what is the exact error that qemu-nbd gives you?
    – agtoever
    Aug 15, 2014 at 20:00
  • @agtoever updated Aug 15, 2014 at 20:24
  • Is the nbd module already inserted into the kernel? Maybe you just need root to insmod it and then group disk to actually attach it to the /dev/ndb* device.
    – Steve
    Aug 15, 2014 at 21:29
  • @Steve nbd module is already loaded Aug 15, 2014 at 21:35

2 Answers 2

3

Here’s my non-straightforward solution: don’t connect qemu-nbd to the kernel NBD driver. Even when it works, it can be quite fragile: I managed to trap a couple of processes in the dreaded ‘uninterruptible sleep’ state this way. (Probably a race condition somewhere.)

Instead, use nbdfuse from the nbdkit project. With nbdfuse, you can make the contents of the image available via a virtual file node under a directory of your choice. Here’s how to use it:

mkdir ~/tmp
nbdfuse ~/tmp/image --socket-activation qemu-nbd hda.qcow2 &

The image is now available at ~/tmp/image. If you want to access a specific partition, you can achieve this by filtering the NBD connection through nbdkit:

mkdir ~/tmp
qemu-nbd --socket="$PWD/qemu-img.sock" hda.qcow2 &
nbdfuse ~/tmp/part1 --command \
    nbdkit -s nbd socket=qemu-nbd.sock \
    --filter=partition partition=1 &

This makes the partition available at ~/tmp/part1.

When you’re done with the image, use fusermount -u on the directory.

2

You need CAP_SYS_ADMIN (see nbd_ioctl()), e.g. by granting it to the binary: setcap 'cap_sys_admin=ep' qemu-nbd - although CAP_SYS_ADMIN is basically root.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .