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 https://github.com/cloudius-systems/osv/issues/1062.

Signed-off-by: Fotis Xenakis <[email protected]>
---
 fs/vfs/main.cc | 24 ++++++++++++++++++++++++
 loader.cc      | 10 +++++++++-
 scripts/build  | 22 +++++++++++++++-------
 3 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
index 957333c2..f26e2275 100644
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -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;
diff --git a/loader.cc b/loader.cc
index 60550344..a588af9a 100644
--- a/loader.cc
+++ b/loader.cc
@@ -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()
@@ -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";
@@ -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();
diff --git a/scripts/build b/scripts/build
index 8fa18071..24e930d3 100755
--- a/scripts/build
+++ b/scripts/build
@@ -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
@@ -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
 
@@ -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)
-- 
2.28.0

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/AM0PR03MB6292126D2649FD076CC79249A65D0%40AM0PR03MB6292.eurprd03.prod.outlook.com.

Reply via email to