This allows us to treat /usr exactly the same as /. Namely, its options may be given on the kernel commandline rather than, say, being included in the initramfs or being read from the rootfs.
The new options are: usr=, usrfstype=, usrwait=, usrflags=, which have analogous semantics to their root counterparts. Moreover, the 'ro' and 'rw' options apply to root and usr both. If someone has a desire to support separate /usr without an initramfs (and witohut split-usr), they could easily add support for these options to the kernel. Cc: Harald Hoyer <[email protected]> Cc: Dave Reisner <[email protected]> --- src/fstab-generator/fstab-generator.c | 96 +++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 28 deletions(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 5c34de1..a2ab585 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -438,10 +438,12 @@ finish: static int parse_new_root_from_proc_cmdline(void) { char *w, *state; - _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL; - int r; + _cleanup_free_ char *line = NULL; + _cleanup_free_ char *root_what = NULL, *root_type = NULL, *root_opts = NULL; + _cleanup_free_ char *usr_what = NULL, *usr_type = NULL, *usr_opts = NULL; + bool root_wait = false, usr_wait = false; + int r = 0, k; size_t l; - bool wait = false; r = read_one_line_file("/proc/cmdline", &line); if (r < 0) { @@ -449,13 +451,16 @@ static int parse_new_root_from_proc_cmdline(void) { return 0; } - opts = strdup("ro"); - type = strdup("auto"); - if (!opts || !type) + root_opts = strdup("ro"); + root_type = strdup("auto"); + usr_opts = strdup("ro"); + usr_type = strdup("auto"); + if (!root_opts || !root_type || !usr_opts || !usr_type) return log_oom(); - /* root= and roofstype= may occur more than once, the last instance should take precedence. - * In the case of multiple rootflags= the arguments should be concatenated */ + /* root=, usr=, roofstype=and usrfstype= may occur more than once, the last + * instance should take precedence. In the case of multiple rootflags= or + * usrflags= the arguments should be concatenated */ FOREACH_WORD_QUOTED(w, l, line, state) { char *word, *tmp_word; @@ -464,49 +469,84 @@ static int parse_new_root_from_proc_cmdline(void) { return log_oom(); else if (startswith(word, "root=")) { - free(what); - what = fstab_node_to_udev_node(word+5); - if (!what) + free(root_what); + root_what = fstab_node_to_udev_node(word+5); + if (!root_what) + return log_oom(); + + } else if (startswith(word, "usr=")) { + free(usr_what); + usr_what = fstab_node_to_udev_node(word+4); + if (!usr_what) return log_oom(); } else if (startswith(word, "rootfstype=")) { - free(type); - type = strdup(word + 11); - if (!type) + free(root_type); + root_type = strdup(word + 11); + if (!root_type) + return log_oom(); + + } else if (startswith(word, "usrfstype=")) { + free(usr_type); + usr_type = strdup(word + 10); + if (!usr_type) return log_oom(); } else if (startswith(word, "rootflags=")) { - tmp_word = opts; - opts = strjoin(opts, ",", word + 10, NULL); + tmp_word = root_opts; + root_opts = strjoin(root_opts, ",", word + 10, NULL); + free(tmp_word); + if (!root_opts) + return log_oom(); + + } else if (startswith(word, "usrflags=")) { + tmp_word = usr_opts; + usr_opts = strjoin(usr_opts, ",", word + 9, NULL); free(tmp_word); - if (!opts) + if (!usr_opts) return log_oom(); } else if (streq(word, "ro") || streq(word, "rw")) { - tmp_word = opts; - opts = strjoin(opts, ",", word, NULL); + tmp_word = root_opts; + root_opts = strjoin(root_opts, ",", word, NULL); + free(tmp_word); + if (!root_opts) + return log_oom(); + + tmp_word = usr_opts; + usr_opts = strjoin(usr_opts, ",", word, NULL); free(tmp_word); - if (!opts) + if (!usr_opts) return log_oom(); } else if (streq(word, "rootwait")) - wait = true; + root_wait = true; + + else if (streq(word, "usrwait")) + usr_wait = true; free(word); } - if (what) { + if (root_what) { - log_debug("Found entry what=%s where=/sysroot type=%s", what, type); - r = add_mount(what, "/sysroot", type, opts, 0, wait, false, false, + log_debug("Found entry what=%s where=/sysroot type=%s", root_what, root_type); + r = add_mount(root_what, "/sysroot", root_type, root_opts, 0, root_wait, false, false, false, false, false, "/proc/cmdline"); - - if (r < 0) - return r; } else log_error("Could not find a root= entry on the kernel commandline."); - return 0; + if (usr_what) { + + log_debug("Found entry what=%s where=/sysroot/usr type=%s", usr_what, usr_type); + k = add_mount(usr_what, "/sysroot/usr", usr_type, usr_opts, 0, usr_wait, false, false, + false, false, false, "/proc/cmdline"); + + if (k < 0) + r = k; + } + + return r; } static int parse_proc_cmdline(void) { -- 1.8.1.4 _______________________________________________ systemd-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/systemd-devel
