Skip to content

Commit c04f226

Browse files
foxengwkozaczuk
authored andcommitted
loader: add rootfs type command line option
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>
1 parent 042485f commit c04f226

File tree

3 files changed

+54
-11
lines changed

3 files changed

+54
-11
lines changed

fs/vfs/main.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2310,7 +2310,7 @@ static void mount_fs(mntent *m)
23102310
}
23112311

23122312
extern std::vector<mntent> opt_mount_fs;
2313-
void pivot_rootfs(const char* path)
2313+
extern "C" void pivot_rootfs(const char* path)
23142314
{
23152315
int ret = sys_pivot_root(path, "/");
23162316
if (ret)

loader.cc

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ void setup_tls(elf::init_table inittab)
8686
extern "C" {
8787
void premain();
8888
void vfs_init(void);
89+
void pivot_rootfs(const char*);
8990
void unmount_devfs();
9091
int mount_zfs_rootfs(bool, bool);
9192
int mount_rofs_rootfs(bool);
@@ -134,6 +135,7 @@ bool opt_power_off_on_abort = false;
134135
static bool opt_log_backtrace = false;
135136
static bool opt_mount = true;
136137
static bool opt_pivot = true;
138+
static std::string opt_rootfs;
137139
static bool opt_random = true;
138140
static bool opt_init = true;
139141
static std::string opt_console = "all";
@@ -161,8 +163,9 @@ static void usage()
161163
std::cout << " --trace=arg tracepoints to enable\n";
162164
std::cout << " --trace-backtrace log backtraces in the tracepoint log\n";
163165
std::cout << " --leak start leak detector after boot\n";
164-
std::cout << " --nomount don't mount the ZFS file system\n";
165-
std::cout << " --nopivot do not pivot the root from bootfs to the ZFS\n";
166+
std::cout << " --nomount don't mount the root file system\n";
167+
std::cout << " --nopivot do not pivot the root from bootfs to the root fs\n";
168+
std::cout << " --rootfs=arg root filesystem to use (zfs, rofs or ramfs)\n";
166169
std::cout << " --assign-net assign virtio network to the application\n";
167170
std::cout << " --maxnic=arg maximum NIC number\n";
168171
std::cout << " --norandom don't initialize any random device\n";
@@ -274,6 +277,14 @@ static void parse_options(int loader_argc, char** loader_argv)
274277
debug("console=%s\n", opt_console);
275278
}
276279

280+
if (options::option_value_exists(options_values, "rootfs")) {
281+
auto v = options::extract_option_values(options_values, "rootfs");
282+
if (v.size() > 1) {
283+
printf("Ignoring '--rootfs' options after the first.");
284+
}
285+
opt_rootfs = v.front();
286+
}
287+
277288
if (options::option_value_exists(options_values, "mount-fs")) {
278289
auto mounts = options::extract_option_values(options_values, "mount-fs");
279290
for (auto m : mounts) {
@@ -397,23 +408,52 @@ void* do_main_thread(void *_main_args)
397408
if (opt_mount) {
398409
unmount_devfs();
399410

400-
// Try to mount rofs
401-
if (mount_rofs_rootfs(opt_pivot) != 0) {
402-
// Failed -> try to mount zfs
411+
if (opt_rootfs.compare("rofs") == 0) {
412+
auto error = mount_rofs_rootfs(opt_pivot);
413+
if (error) {
414+
debug("Could not mount rofs root filesystem.\n");
415+
}
416+
417+
if (opt_disable_rofs_cache) {
418+
debug("Disabling ROFS memory cache.\n");
419+
rofs_disable_cache();
420+
}
421+
boot_time.event("ROFS mounted");
422+
} else if (opt_rootfs.compare("zfs") == 0) {
403423
zfsdev::zfsdev_init();
404424
auto error = mount_zfs_rootfs(opt_pivot, opt_extra_zfs_pools);
405425
if (error) {
406426
debug("Could not mount zfs root filesystem.\n");
407427
}
408-
bsd_shrinker_init();
409428

429+
bsd_shrinker_init();
410430
boot_time.event("ZFS mounted");
431+
} else if (opt_rootfs.compare("ramfs") == 0) {
432+
// NOTE: The ramfs is already mounted, we just need to mount fstab
433+
// entries. That's the only difference between this and --nomount.
434+
435+
// TODO: Avoid the hack of using pivot_rootfs() just for mounting
436+
// the fstab entries.
437+
pivot_rootfs("/");
411438
} else {
412-
if (opt_disable_rofs_cache) {
413-
debug("Disabling ROFS memory cache.\n");
414-
rofs_disable_cache();
439+
// Fallback to original behavior for compatibility: try rofs -> zfs
440+
if (mount_rofs_rootfs(opt_pivot) == 0) {
441+
if (opt_disable_rofs_cache) {
442+
debug("Disabling ROFS memory cache.\n");
443+
rofs_disable_cache();
444+
}
445+
boot_time.event("ROFS mounted");
446+
} else {
447+
zfsdev::zfsdev_init();
448+
auto error = mount_zfs_rootfs(opt_pivot, opt_extra_zfs_pools);
449+
if (error) {
450+
debug("Could not mount zfs root filesystem (while "
451+
"auto-discovering).\n");
452+
}
453+
454+
bsd_shrinker_init();
455+
boot_time.event("ZFS mounted");
415456
}
416-
boot_time.event("ROFS mounted");
417457
}
418458
}
419459

scripts/build

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ rofs)
315315
ramfs)
316316
qemu-img convert -f raw -O qcow2 loader.img usr.img ;;
317317
esac
318+
# Prepend the root fs type option to the command line (preserved by run.py)
319+
cmdline=$(cat cmdline)
320+
echo -n "--rootfs=${fs_type} ${cmdline}" > cmdline
318321

319322
if [[ -f "$OSV_BUILD_PATH/usr.img" ]]; then
320323
"$SRC"/scripts/imgedit.py setargs usr.img `cat cmdline`

0 commit comments

Comments
 (0)