Skip to content

Commit

Permalink
loader: add rootfs type command line option
Browse files Browse the repository at this point in the history
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 better control this behaviour,
specifying which filesystem should be attempted for mounting root,
falling back to the above if not specified. 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 <foxen@windowslive.com>
Message-Id: <AM0PR03MB62926D4644E51479D0A075E2A62C0@AM0PR03MB6292.eurprd03.prod.outlook.com>
  • Loading branch information
foxeng authored and wkozaczuk committed Sep 9, 2020
1 parent 042485f commit c04f226
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
2 changes: 1 addition & 1 deletion fs/vfs/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2310,7 +2310,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)
Expand Down
60 changes: 50 additions & 10 deletions loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
static bool opt_random = true;
static bool opt_init = true;
static std::string opt_console = "all";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -397,23 +408,52 @@ 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
if (opt_rootfs.compare("rofs") == 0) {
auto error = mount_rofs_rootfs(opt_pivot);
if (error) {
debug("Could not mount rofs root filesystem.\n");
}

if (opt_disable_rofs_cache) {
debug("Disabling ROFS memory cache.\n");
rofs_disable_cache();
}
boot_time.event("ROFS mounted");
} else if (opt_rootfs.compare("zfs") == 0) {
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();

bsd_shrinker_init();
boot_time.event("ZFS 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 {
if (opt_disable_rofs_cache) {
debug("Disabling ROFS memory cache.\n");
rofs_disable_cache();
// Fallback to original behavior for compatibility: try rofs -> zfs
if (mount_rofs_rootfs(opt_pivot) == 0) {
if (opt_disable_rofs_cache) {
debug("Disabling ROFS memory cache.\n");
rofs_disable_cache();
}
boot_time.event("ROFS mounted");
} else {
zfsdev::zfsdev_init();
auto error = mount_zfs_rootfs(opt_pivot, opt_extra_zfs_pools);
if (error) {
debug("Could not mount zfs root filesystem (while "
"auto-discovering).\n");
}

bsd_shrinker_init();
boot_time.event("ZFS mounted");
}
boot_time.event("ROFS mounted");
}
}

Expand Down
3 changes: 3 additions & 0 deletions scripts/build
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down

0 comments on commit c04f226

Please sign in to comment.