Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable virtio-blk to access hostOS /dev/ block devices #572

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ChinYikMing
Copy link
Collaborator

@ChinYikMing ChinYikMing commented Feb 20, 2025

The user may not always have a disk image but might have a /dev/x block device, such as a USB drive that they want to share with the guest OS. So, allowing this type of virtio-blk source is intuitive. To support this, ioctl is used to retrieve the actual size of the /dev/x block device. This implementation supports both Apple and Linux platforms.

Testing

  1. Clone the repo:
$ git clone https://github.com/ChinYikMing/rv32emu.git -b virtio-blk-ioctl --depth 1 && cd rv32emu
  1. Get the prebuilt images and build:
$ make ENABLE_SYSTEM=1 INITRD_SIZE=32 -j100 && make ENABLE_SYSTEM=1 artifact
  1. Prepare /dev/x device:

macOS:

# Might need to install file system utility
$ brew install e2fsprogs

# Create a disk image
$ dd if=/dev/zero of=disk.img bs=4M count=32
$ $(brew --prefix e2fsprogs)/sbin/mkfs.ext4 disk.img

# Setup a block device with the disk image
$ hdiutil attach -nomount disk.img              # this would output the <block-device>
$ sudo build/rv32emu -k build/linux-image/Image -i build/linux-image/rootfs.cpio -x vblk:<block-device>

Linux

# Create a disk image
$ dd if=/dev/zero of=disk.img bs=4M count=32
$ mkfs.ext4 disk.img

# Setup a loop back device with the disk image
$ sudo losetup -f              # this would output the <first-unused-loop-device>
$ sudo losetup <first-unused-loop-device> disk.img 
$ sudo build/rv32emu -k build/linux-image/Image -i build/linux-image/rootfs.cpio -x vblk:<first-unused-loop-device>
  1. Check the kernel boot log which should have something as the following:
...
...
[    0.583109] virtio_blk virtio0: 1/0/0 default/read/poll queues
[    0.584873] virtio_blk virtio0: [vda] 262144 512-byte logical blocks (134 MB/128 MiB)
...
...
  1. Mount the virtio block device and manipulate the device:
# mkdir mnt
# mount /dev/vda mnt
# echo "rv32emu" > mnt/emu.txt
# ls mnt

Might see:

emu.txt     lost+found
  1. Detach newly created block device:

macOS

$ hdiutil detach <block-device>

Linux

$ losetup -d <first-unused-loop-device>

Known Issue:

On macOS/arm64, OS v15.3.1, the /dev/ block device cannot be mmap with error log: ERROR src/devices/virtio-blk.c:475: Could not map disk <block-device>.

After some debugging, the errno is set to EINVAL. Then, reading the man page of mmap in the system:

[EINVAL]           MAP_FIXED was specified and the addr argument was not page aligned, or part of the desired address space resides out of the valid address space
                        for a user process.

[EINVAL]           flags does not include either MAP_PRIVATE or MAP_SHARED.

[EINVAL]           flags includes bits that are not part of any valid flags value.

[EINVAL]           The len argument was negative or zero. Historically, the system call would not return an error if the argument was zero.  See other potential
                        additional restrictions in the COMPATIBILITY section below.

[EINVAL]           The offset argument was not page-aligned based on the page size as returned by getpagesize(3).

The page size in my system is 16KiB, which the block device size aligned of (128MiB % 16KiB == 0). The rest of the requirements appear to be met, so this seems a bit strange to me. If anyone has a macOS/arm64 machine, maybe can give it a try.

Summary by Bito

This pull request enhances the virtio-blk driver to enable access to hostOS /dev/ block devices, including USB drives, for guest OS sharing. It introduces ioctl calls for device size retrieval and improves error handling and disk size logic for better reliability across platforms.

Unit tests added: True

Estimated effort to review (1-5, lower is better): 2

The user may not always have a disk image but might have a /dev/x block
device, such as a USB drive that they want to share with the guest OS.
So, allowing this type of virtio-blk source is intuitive. To support
this, ioctl is used to retrieve the actual size of the /dev/x block
device. This implementation supports both Apple and Linux platforms.

Close sysprog21#544
@ChinYikMing ChinYikMing marked this pull request as draft February 21, 2025 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant