Skip to content

Commit

Permalink
loader: add support for booting from virtio-fs
Browse files Browse the repository at this point in the history
This makes the necessary and pretty straight-forward additions to the
laoder to support using virtio-fs as the root filesystem. It also makes
minimal changes to scripts/build to add support there as well. Note
that, to obtain a directory with contents specified by the manifest
files, usable as the virtio-fs host directory, one can use the existing
'export' and 'export_dir' (previously undocumented) options to
scripts/build.

Ref cloudius-systems#1062.
  • Loading branch information
foxeng committed Sep 2, 2020
1 parent 33f9165 commit 3943efc
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
24 changes: 24 additions & 0 deletions fs/vfs/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2424,6 +2424,30 @@ extern "C" int mount_zfs_rootfs(bool pivot_root, bool extra_zfs_pools)
return 0;
}

extern "C" int mount_virtiofs_rootfs(bool pivot_root)
{
constexpr char* mp = "/virtiofs";

if (mkdir(mp, 0755) < 0) {
int ret = errno;
kprintf("failed to create %s, error = %s\n", mp, strerror(errno));
return ret;
}

int ret = sys_mount("/dev/virtiofs0", mp, "virtiofs", MNT_RDONLY, nullptr);
if (ret) {
kprintf("failed to mount %s, error = %s\n", mp, strerror(ret));
rmdir(mp);
return ret;
}

if (pivot_root) {
pivot_rootfs(mp);
}

return 0;
}

extern "C" void unmount_rootfs(void)
{
int ret;
Expand Down
10 changes: 9 additions & 1 deletion loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ extern "C" {
int mount_zfs_rootfs(bool, bool);
int mount_rofs_rootfs(bool);
void rofs_disable_cache();
int mount_virtiofs_rootfs(bool);
}

void premain()
Expand Down Expand Up @@ -165,7 +166,7 @@ static void usage()
std::cout << " --leak start leak detector after boot\n";
std::cout << " --nomount don't mount the root file system\n";
std::cout << " --nopivot do not pivot the root from bootfs to the root fs\n";
std::cout << " --rootfs=arg root filesystem to use (zfs, rofs or ramfs)\n";
std::cout << " --rootfs=arg root filesystem to use (zfs, rofs, ramfs or virtiofs)\n";
std::cout << " --assign-net assign virtio network to the application\n";
std::cout << " --maxnic=arg maximum NIC number\n";
std::cout << " --norandom don't initialize any random device\n";
Expand Down Expand Up @@ -426,6 +427,13 @@ void* do_main_thread(void *_main_args)
// TODO: Avoid the hack of using pivot_rootfs() just for mounting
// the fstab entries.
pivot_rootfs("/");
} else if (opt_rootfs.compare("virtiofs") == 0) {
auto error = mount_virtiofs_rootfs(opt_pivot);
if (error) {
debug("Could not mount virtiofs root filesystem.\n");
}

boot_time.event("Virtio-fs mounted");
} else {
// Go with ZFS in all other cases
zfsdev::zfsdev_init();
Expand Down
22 changes: 15 additions & 7 deletions scripts/build
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ usage() {
--help|-h Print this help message
arch=x64|aarch64 Specify the build architecture; default is x64
mode=release|debug Specify the build mode; default is release
export=none|selected|all If 'selected' or 'all' export the app files to build/export
fs=zfs|rofs|ramfs Specify the filesystem of the image partition
export=none|selected|all If 'selected' or 'all' export the app files to <export_dir>
export_dir=<dir> The directory to export the files to; default is build/export
fs=zfs|rofs|ramfs|virtiofs Specify the filesystem of the image partition
fs_size=N Specify the size of the image in bytes
fs_size_mb=N Specify the size of the image in MiB
app_local_exec_tls_size=N Specify the size of app local TLS in bytes; the default is 64
Expand Down Expand Up @@ -182,12 +183,17 @@ manifest=bootfs.manifest.skel
fs_type=${vars[fs]-zfs}
usrskel_arg=
case $fs_type in
zfs);; # Nothing to change here. This is our default behavior
rofs) manifest=bootfs_empty.manifest.skel
zfs)
;; # Nothing to change here. This is our default behavior
rofs|virtiofs)
# Both are read-only (in OSv) and require nothing extra on bootfs to work
manifest=bootfs_empty.manifest.skel
usrskel_arg="--usrskel usr_rofs.manifest.skel";;
ramfs) manifest=$OUT/usr.manifest
ramfs)
manifest=$OUT/usr.manifest
usrskel_arg="--usrskel usr_ramfs.manifest.skel";;
*) echo "Unknown filesystem \"$fs_type\"" >&2
*)
echo "Unknown filesystem \"$fs_type\"" >&2
exit 2
esac

Expand Down Expand Up @@ -312,7 +318,9 @@ rofs)
partition_size=`stat --printf %s rofs.img`
image_size=$((partition_offset + partition_size))
create_rofs_disk ;;
ramfs)
ramfs|virtiofs)
# No need to create extra fs like above: ramfs is already created (as the
# bootfs) and virtio-fs is specified with virtiofsd at run time
qemu-img convert -f raw -O qcow2 loader.img usr.img ;;
esac
# Prepend the root fs type option to the command line (preserved by run.py)
Expand Down

0 comments on commit 3943efc

Please sign in to comment.