San Mehat
2011-Nov-22 18:57 UTC
[klibc] [PATCH] kinit: Add ability to mount filesystems via /etc/fstab or cmdline
This patch adds the ability to mount filesystems via an embedded fstab or via the kernel command line. When using the kernel command-line, the following format is required: 'kinit_mount=<fs_name>;<fs_dir>;<fs_type>;<fs_opts>' Multiple mount options can be specified; they are evaluated in the order they appear in the command-line. Signed-off-by: San Mehat <san at google.com> --- Things I'd like to change: - Move string option parsing into mount_block() - ro, bind - Handle bind mounts in /etc/fstab entries --- usr/kinit/do_mounts.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 104 insertions(+), 2 deletions(-) diff --git a/usr/kinit/do_mounts.c b/usr/kinit/do_mounts.c index 3ffac91..5d36385 100644 --- a/usr/kinit/do_mounts.c +++ b/usr/kinit/do_mounts.c @@ -7,6 +7,7 @@ #include <string.h> #include <unistd.h> #include <inttypes.h> +#include <mntent.h> #include "do_mounts.h" #include "kinit.h" @@ -199,12 +200,97 @@ mount_root(int argc, char *argv[], dev_t root_dev, const char *root_dev_name) return ret; } +int do_cmdline_mounts(int argc, char *argv[]) +{ + int arg_i; + + for (arg_i = 0; arg_i < argc; arg_i++) { + const char *fs_name, *fs_dir, *fs_type; + char *fs_opts; + unsigned long flags = 0; + char new_fs_opts[128] = { 0 }; + char *saveptr = NULL; + char *fs_opts_savedptr = NULL; + int opt_first = 1; + const char *opt; + + if (strncmp(argv[arg_i], "kinit_mount=", 12)) + continue; + /* + * Format: + * <fs_name>;<dir>;<fs_type>;[opt1],[optn...] + */ + fs_name = strtok_r(&argv[arg_i][12], ";", &saveptr); + if (!fs_name) { + fprintf(stderr, "Failed to parse fs_name\n"); + continue; + } + fs_dir = strtok_r(NULL, ";", &saveptr); + if (!fs_dir) { + fprintf(stderr, "Failed to parse fs_dir\n"); + continue; + } + fs_type = strtok_r(NULL, ";", &saveptr); + if (!fs_type) { + fprintf(stderr, "Failed to parse fs_type\n"); + continue; + } + fs_opts = strtok_r(NULL, ";", &saveptr); + if (!fs_opts) { + fprintf(stderr, "Failed to parse fs_opts\n"); + continue; + } + + /* If 'fs_opts' specifies 'ro' or 'bind', gobble it up. */ + while ((opt = strtok_r((opt_first ? fs_opts : NULL), + ",", &fs_opts_savedptr))) { + if (!strcmp(opt, "ro")) + flags |= MS_RDONLY; + else if (!strcmp(opt, "bind")) + flags |= MS_BIND; + else { + if (!opt_first) + strcat(new_fs_opts, ","); + strcat(new_fs_opts, opt); + } + if (opt_first) + opt_first = 0; + } + + if (!mount_block(fs_name, fs_dir, fs_type, + flags, new_fs_opts)) { + fprintf(stderr, "Skipping failed mount '%s'\n", + fs_name); + } + } + return 0; +} + +int do_fstab_mounts(FILE *fp) +{ + struct mntent *ent = NULL; + + while ((ent = getmntent(fp))) { + if (!mount_block(ent->mnt_fsname, + ent->mnt_dir, + ent->mnt_type, + 0, + ent->mnt_opts)) { + fprintf(stderr, "Skipping failed mount '%s'\n", + ent->mnt_fsname); + } + } + return 0; +} + int do_mounts(int argc, char *argv[]) { const char *root_dev_name = get_arg(argc, argv, "root="); const char *root_delay = get_arg(argc, argv, "rootdelay="); const char *load_ramdisk = get_arg(argc, argv, "load_ramdisk="); dev_t root_dev = 0; + int err; + FILE *fp; dprintf("kinit: do_mounts\n"); @@ -241,6 +327,22 @@ int do_mounts(int argc, char *argv[]) } if (root_dev == Root_MULTI) - return mount_roots(argc, argv, root_dev_name); - return mount_root(argc, argv, root_dev, root_dev_name); + err = mount_roots(argc, argv, root_dev_name); + else + err = mount_root(argc, argv, root_dev, root_dev_name); + + if (err) + return err; + + if ((fp = fopen("/etc/fstab", "r"))) { + err = do_fstab_mounts(fp); + fclose(fp); + } + + if (err) + return err; + + if (get_arg(argc, argv, "kinit_mount=")) + err = do_cmdline_mounts(argc, argv); + return err; } -- 1.7.3.1
Reasonably Related Threads
- [PATCH 0/3] kinit: Allow mount options
- Form of \item{arg_i}{Description of arg_i.} in \arguments
- [PATCH] test-charset-fidelity: allow to skip testing specific FSes
- [klibc:master] fstype: Drop obsolete support for "ext4dev"
- [PATCH] fstype: Fix ext4/ext4dev probing