From: Waldemar Kozaczuk <[email protected]> Committer: Waldemar Kozaczuk <[email protected]> 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 <[email protected]> --- diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc --- 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 --- 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); -- 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/00000000000062321205a4b34385%40google.com.
