Previously, the loader always attempted to:
1. Mount a rofs root filesystem.
2. Mount a zfs root filesystem, if the previous failed.
3. Do nothing (i.e. keep the ramfs mounted as bootfs) if the others
   failed.

This adds a new command line option to control this behaviour instead,
specifying which filesystem should be attempted for mounting root
(defaulting to zfs, to avoid surprises). This option is set by
scripts/build (scripts/run.py would be the obvious choice for setting a
command line option, but it would require the user specifying the root
fs type a run time in addition to build time).

In addition, in a way this formalizes supporting ramfs as the root
filesystem. As noted in the code, this support consists of simply
mounting the fstab entries when ramfs is selected (this is in sync with
what happened previously, when mounting zfs failed). So, there is no
functionality added here, just documenting the option and making the
code more clear and explicit.

Signed-off-by: Fotis Xenakis <fo...@windowslive.com>
---
 fs/vfs/main.cc |  2 +-
 loader.cc      | 44 +++++++++++++++++++++++++++++++++-----------
 scripts/build  |  3 +++
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
index 6cee319e..957333c2 100644
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -2330,7 +2330,7 @@ static void mount_fs(mntent *m)
 }
 
 extern std::vector<mntent> opt_mount_fs;
-void pivot_rootfs(const char* path)
+extern "C" void pivot_rootfs(const char* path)
 {
     int ret = sys_pivot_root(path, "/");
     if (ret)
diff --git a/loader.cc b/loader.cc
index 9d9d3173..60550344 100644
--- a/loader.cc
+++ b/loader.cc
@@ -86,6 +86,7 @@ void setup_tls(elf::init_table inittab)
 extern "C" {
     void premain();
     void vfs_init(void);
+    void pivot_rootfs(const char*);
     void unmount_devfs();
     int mount_zfs_rootfs(bool, bool);
     int mount_rofs_rootfs(bool);
@@ -134,6 +135,7 @@ bool opt_power_off_on_abort = false;
 static bool opt_log_backtrace = false;
 static bool opt_mount = true;
 static bool opt_pivot = true;
+static std::string opt_rootfs = "zfs";
 static bool opt_random = true;
 static bool opt_init = true;
 static std::string opt_console = "all";
@@ -161,8 +163,9 @@ static void usage()
     std::cout << "  --trace=arg           tracepoints to enable\n";
     std::cout << "  --trace-backtrace     log backtraces in the tracepoint 
log\n";
     std::cout << "  --leak                start leak detector after boot\n";
-    std::cout << "  --nomount             don't mount the ZFS file system\n";
-    std::cout << "  --nopivot             do not pivot the root from bootfs to 
the ZFS\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 << "  --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";
@@ -274,6 +277,14 @@ static void parse_options(int loader_argc, char** 
loader_argv)
         debug("console=%s\n", opt_console);
     }
 
+    if (options::option_value_exists(options_values, "rootfs")) {
+        auto v = options::extract_option_values(options_values, "rootfs");
+        if (v.size() > 1) {
+            printf("Ignoring '--rootfs' options after the first.");
+        }
+        opt_rootfs = v.front();
+    }
+
     if (options::option_value_exists(options_values, "mount-fs")) {
         auto mounts = options::extract_option_values(options_values, 
"mount-fs");
         for (auto m : mounts) {
@@ -397,23 +408,34 @@ void* do_main_thread(void *_main_args)
     if (opt_mount) {
         unmount_devfs();
 
-        // Try to mount rofs
-        if (mount_rofs_rootfs(opt_pivot) != 0) {
-            // Failed -> try to mount zfs
-            zfsdev::zfsdev_init();
-            auto error = mount_zfs_rootfs(opt_pivot, opt_extra_zfs_pools);
+        if (opt_rootfs.compare("rofs") == 0) {
+            auto error = mount_rofs_rootfs(opt_pivot);
             if (error) {
-                debug("Could not mount zfs root filesystem.\n");
+                debug("Could not mount rofs root filesystem.\n");
             }
-            bsd_shrinker_init();
 
-            boot_time.event("ZFS mounted");
-        } else {
             if (opt_disable_rofs_cache) {
                 debug("Disabling ROFS memory cache.\n");
                 rofs_disable_cache();
             }
             boot_time.event("ROFS mounted");
+        } else if (opt_rootfs.compare("ramfs") == 0) {
+            // NOTE: The ramfs is already mounted, we just need to mount fstab
+            // entries. That's the only difference between this and --nomount.
+
+            // TODO: Avoid the hack of using pivot_rootfs() just for mounting
+            // the fstab entries.
+            pivot_rootfs("/");
+        } else {
+            // Go with ZFS in all other cases
+            zfsdev::zfsdev_init();
+            auto error = mount_zfs_rootfs(opt_pivot, opt_extra_zfs_pools);
+            if (error) {
+                debug("Could not mount zfs root filesystem.\n");
+            }
+
+            bsd_shrinker_init();
+            boot_time.event("ZFS mounted");
         }
     }
 
diff --git a/scripts/build b/scripts/build
index 5d480d57..8fa18071 100755
--- a/scripts/build
+++ b/scripts/build
@@ -315,6 +315,9 @@ rofs)
 ramfs)
        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)
+cmdline=$(cat cmdline)
+echo -n "--rootfs=${fs_type} ${cmdline}" > cmdline
 
 if [[ -f "$OSV_BUILD_PATH/usr.img" ]]; then
        "$SRC"/scripts/imgedit.py setargs usr.img `cat cmdline`
-- 
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 osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/AM0PR03MB62926AE1D7F88A0364AC06BBA65D0%40AM0PR03MB6292.eurprd03.prod.outlook.com.

Reply via email to