[systemd-devel] [PATCH 1/2] fstab-generator: mount /usr in the initrd if specified on /proc/cmdline
Tom Gundersen
teg at jklm.no
Fri Mar 1 09:15:36 PST 2013
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 <harald.hoyer at gmail.com>
Cc: Dave Reisner <d at falconindy.com>
---
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
More information about the systemd-devel
mailing list