[PATCH] loader: add option to mount extra filesystem

10 views
Skip to first unread message

Waldemar Kozaczuk

unread,
May 1, 2020, 4:15:13 PM5/1/20
to osv...@googlegroups.com, Waldemar Kozaczuk
This patch adds new loader option '--mount-fs=arg' where arg is in format
'<fs_type,url,path>'. It allows adding arbitrary mount points for filesystems
like NFS, Virtio-FS or even ramfs on top of functionality based on /etc/fstab.
This options becomes more handy than appending to /etc/fstab or using /tools/mountfs
which has to be already present in the image.

Here is a cmdline example of mounting virtio-fs filesystem:

'--mount-fs=virtiofs,/dev/virtiofs1,/tmp/virtiofs /tmp/virtiofs/hello'

Signed-off-by: Waldemar Kozaczuk <jwkoz...@gmail.com>
---
fs/vfs/main.cc | 56 ++++++++++++++++++++++++++++++++++----------------
loader.cc | 24 +++++++++++++++++++++-
2 files changed, 61 insertions(+), 19 deletions(-)

diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
index 46dcb62f..3c8b327b 100644
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -2300,6 +2300,36 @@ static void import_extra_zfs_pools(void)
}
}

+static void mount_fs(mntent *m)
+{
+ if (!strcmp(m->mnt_dir, "/")) {
+ return;
+ }
+
+ auto mount_dir = opendir(m->mnt_dir);
+ if (!mount_dir) {
+ if (mkdir(m->mnt_dir, 0755) < 0) {
+ kprintf("failed to create missing mount point %s, error = %s\n", m->mnt_dir, strerror(errno));
+ return;
+ } else {
+ kprintf("created missing mount point %s\n", m->mnt_dir);
+ }
+ } else {
+ closedir(mount_dir);
+ }
+
+ if ((m->mnt_opts != nullptr) && strcmp(m->mnt_opts, MNTOPT_DEFAULTS)) {
+ printf("Warning: opts %s, ignored for fs %s\n", m->mnt_opts, m->mnt_type);
+ }
+
+ // FIXME: Right now, ignoring mntops. In the future we may have an option parser
+ auto ret = sys_mount(m->mnt_fsname, m->mnt_dir, m->mnt_type, 0, nullptr);
+ if (ret) {
+ printf("failed to mount %s, error = %s\n", m->mnt_type, strerror(ret));
+ }
+}
+
+extern std::vector<mntent> opt_mount_fs;
void pivot_rootfs(const char* path)
{
int ret = sys_pivot_root(path, "/");
@@ -2323,27 +2353,17 @@ void pivot_rootfs(const char* path)
}

auto ent = setmntent("/etc/fstab", "r");
- if (!ent) {
- return;
- }
-
- struct mntent *m = nullptr;
- while ((m = getmntent(ent)) != nullptr) {
- if (!strcmp(m->mnt_dir, "/")) {
- continue;
- }
-
- if ((m->mnt_opts != nullptr) && strcmp(m->mnt_opts, MNTOPT_DEFAULTS)) {
- printf("Warning: opts %s, ignored for fs %s\n", m->mnt_opts, m->mnt_type);
+ if (ent) {
+ struct mntent *m = nullptr;
+ while ((m = getmntent(ent)) != nullptr) {
+ mount_fs(m);
}
+ endmntent(ent);
+ }

- // FIXME: Right now, ignoring mntops. In the future we may have an option parser
- ret = sys_mount(m->mnt_fsname, m->mnt_dir, m->mnt_type, 0, nullptr);
- if (ret) {
- printf("failed to mount %s, error = %s\n", m->mnt_type, strerror(ret));
- }
+ for (auto m: opt_mount_fs) {
+ mount_fs(&m);
}
- endmntent(ent);
}

extern "C" void unmount_devfs()
diff --git a/loader.cc b/loader.cc
index 758e4bf9..66bfb52c 100644
--- a/loader.cc
+++ b/loader.cc
@@ -48,6 +48,7 @@
#include <dirent.h>
#include <iostream>
#include <fstream>
+#include <mntent.h>

#include "drivers/zfs.hh"
#include "drivers/random.hh"
@@ -144,6 +145,7 @@ static std::string opt_defaultgw;
static std::string opt_nameserver;
static std::string opt_redirect;
static std::chrono::nanoseconds boot_delay;
+std::vector<mntent> opt_mount_fs;
bool opt_maxnic = false;
int maxnic;
bool opt_pci_disabled = false;
@@ -180,7 +182,8 @@ static void usage()
std::cout << " --redirect=arg redirect stdout and stderr to file\n";
std::cout << " --disable_rofs_cache disable ROFS memory cache\n";
std::cout << " --nopci disable PCI enumeration\n";
- std::cout << " --extra-zfs-pools import extra ZFS pools\n\n";
+ std::cout << " --extra-zfs-pools import extra ZFS pools\n";
+ std::cout << " --mount-fs=arg mount extra filesystem, format:<fs_type,url,path>\n\n";
}

static void handle_parse_error(const std::string &message)
@@ -271,6 +274,25 @@ static void parse_options(int loader_argc, char** loader_argv)
debug("console=%s\n", opt_console);
}

+ if (options::option_value_exists(options_values, "mount-fs")) {
+ auto mounts = options::extract_option_values(options_values, "mount-fs");
+ for (auto m : mounts) {
+ std::vector<std::string> tmp;
+ boost::split(tmp, m, boost::is_any_of(","), boost::token_compress_on);
+ if (tmp.size() != 3 || tmp[0].empty() || tmp[1].empty() || tmp[2].empty()) {
+ printf("Ignoring value: '%s' for option mount-fs, expected in format: <fs_type,url,path>\n", m.c_str());
+ continue;
+ }
+ mntent mount = {
+ .mnt_fsname = strdup(tmp[1].c_str()),
+ .mnt_dir = strdup(tmp[2].c_str()),
+ .mnt_type = strdup(tmp[0].c_str()),
+ .mnt_opts = nullptr
+ };
+ opt_mount_fs.push_back(mount);
+ }
+ }
+
if (options::option_value_exists(options_values, "env")) {
for (auto t : options::extract_option_values(options_values, "env")) {
debug("Setting in environment: %s\n", t);
--
2.20.1

Commit Bot

unread,
May 2, 2020, 8:12:02 PM5/2/20
to osv...@googlegroups.com, Waldemar Kozaczuk
From: Waldemar Kozaczuk <jwkoz...@gmail.com>
Committer: Waldemar Kozaczuk <jwkoz...@gmail.com>
Branch: master

loader: add option to mount extra filesystem

This patch adds new loader option '--mount-fs=arg' where arg is in format
'<fs_type,url,path>'. It allows adding arbitrary mount points for filesystems
like NFS, Virtio-FS or even ramfs on top of functionality based on /etc/fstab.
This options becomes more handy than appending to /etc/fstab or using /tools/mountfs
which has to be already present in the image.

Here is a cmdline example of mounting virtio-fs filesystem:

'--mount-fs=virtiofs,/dev/virtiofs1,/tmp/virtiofs /tmp/virtiofs/hello'

Signed-off-by: Waldemar Kozaczuk <jwkoz...@gmail.com>

---
diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
Reply all
Reply to author
Forward
0 new messages