[arch-projects] [mkinitcpio] systemd in initramfs
The Arch testing/systemd package recently added support for systemd in initramfs. This obsoletes the base, usr, udev and timestamp hooks. So, what about the rest? 0) autodetect, block, filesystems, fsck, keyboard and modconf work exactly as before. 1) mdadm: I see no hope for this hook working on systemd, however the mdadm_udev hook works out of the box. 2) lvm2: This is much simpler now. I created the sd-lvm2 hook, find it here: https://paste.xinu.at/3vezU/ - this works great, although it could be simplified a bit if one uses add_systemd_unit and add_udev_rule. 3) encrypt: I created the sd-encrypt hook, you can find it here: https://paste.xinu.at/8xUYPI/. This changes the command line syntax, the new syntax can be found in the manpage for systemd-cryptsetup-generator. However, the syntax is less powerful than before - for that reason, I added /etc/crypttab.initrd as /etc/crypttab to the initrd, which should support almost everything. There were some problems with adding the same crypttab for initrd and the main system, but that may be my stupiditiy - I hope the separate crypttab is something we can get rid of. 4) shutdown: I removed this from initramfs entirely - I now generate the shutdown ramfs on the fly during shutdown instead of generating one in the initrd. I'll post something when I polished it more. 5) consolefont/keymap: I tried by putting systemd-vconsole-setup to initramfs. Since keymaps are now loaded by loadkeys instead of busybox's setkmap, this had a few problems and I couldn't get it to work yet.
Am 17.08.2013 17:08, schrieb Thomas Bächler:
5) consolefont/keymap: I tried by putting systemd-vconsole-setup to initramfs. Since keymaps are now loaded by loadkeys instead of busybox's setkmap, this had a few problems and I couldn't get it to work yet.
Okay, this seems to work: https://paste.xinu.at/HUJk3/ It only supports KEYMAP, KEYMAP_TOGGLE and FONT, the latter untested. I didn't bother to look at FONT_MAP and FONT_UNIMAP whatsoever.
Am 17.08.2013 18:29, schrieb Thomas Bächler:
Am 17.08.2013 17:08, schrieb Thomas Bächler:
5) consolefont/keymap: I tried by putting systemd-vconsole-setup to initramfs. Since keymaps are now loaded by loadkeys instead of busybox's setkmap, this had a few problems and I couldn't get it to work yet.
Okay, this seems to work: https://paste.xinu.at/HUJk3/
It only supports KEYMAP, KEYMAP_TOGGLE and FONT, the latter untested. I didn't bother to look at FONT_MAP and FONT_UNIMAP whatsoever.
New version, Dave had some criticism: https://paste.xinu.at/7uf6/
Am 17.08.2013 19:21, schrieb Thomas Bächler:
Am 17.08.2013 18:29, schrieb Thomas Bächler:
Am 17.08.2013 17:08, schrieb Thomas Bächler:
5) consolefont/keymap: I tried by putting systemd-vconsole-setup to initramfs. Since keymaps are now loaded by loadkeys instead of busybox's setkmap, this had a few problems and I couldn't get it to work yet.
Okay, this seems to work: https://paste.xinu.at/HUJk3/
It only supports KEYMAP, KEYMAP_TOGGLE and FONT, the latter untested. I didn't bother to look at FONT_MAP and FONT_UNIMAP whatsoever.
New version, Dave had some criticism: https://paste.xinu.at/7uf6/
Forgot something else, let's use this: https://paste.xinu.at/OYIAN/
Am 17.08.2013 17:08, schrieb Thomas Bächler:
3) encrypt: I created the sd-encrypt hook, you can find it here: https://paste.xinu.at/8xUYPI/. This changes the command line syntax, the new syntax can be found in the manpage for systemd-cryptsetup-generator. However, the syntax is less powerful than before - for that reason, I added /etc/crypttab.initrd as /etc/crypttab to the initrd, which should support almost everything. There were some problems with adding the same crypttab for initrd and the main system, but that may be my stupiditiy - I hope the separate crypttab is something we can get rid of.
Okay, this one has the wrong help, but otherwise it's what I'm going to use now: https://paste.xinu.at/0PXjlV/ It now adds /etc/crypttab to initramfs. You can make sure that only the necessary devices are activated in initramfs by using the rd.luks.uuid= options on the command line. You can also use rd.luks.uuid= without any crypttab entries, but then you can't set extra options (for me: allow_discards).
Hi Thomas, Thanks for your work on all this, I was hoping someone would pick this up. On Sun, Aug 18, 2013 at 12:45 AM, Thomas Bächler <thomas@archlinux.org> wrote:
Am 17.08.2013 17:08, schrieb Thomas Bächler:
3) encrypt: I created the sd-encrypt hook, you can find it here: https://paste.xinu.at/8xUYPI/. This changes the command line syntax, the new syntax can be found in the manpage for systemd-cryptsetup-generator. However, the syntax is less powerful than before - for that reason, I added /etc/crypttab.initrd as /etc/crypttab to the initrd, which should support almost everything. There were some problems with adding the same crypttab for initrd and the main system, but that may be my stupiditiy - I hope the separate crypttab is something we can get rid of.
Okay, this one has the wrong help, but otherwise it's what I'm going to use now: https://paste.xinu.at/0PXjlV/
It now adds /etc/crypttab to initramfs. You can make sure that only the necessary devices are activated in initramfs by using the rd.luks.uuid= options on the command line. You can also use rd.luks.uuid= without any crypttab entries, but then you can't set extra options (for me: allow_discards).
We should make it possible to do this without having to put /etc/crypttab in the initramfs. I guess we basically want to mimic what the fstab generator does: 1) allow options to be specified on the kernel commandline and, optionally, 2) allow further options to be read from /sysroot/etc/cryttab once that has been mounted. For the first, we would need to extend the syntax, perhaps to {rd.,}luks.uuid.options= or something like that. The second could obviously not be used for partitions used to mount the rootfs (but only /usr), so maybe not that useful, but I guess it makes sense to be consistent. What do you think? Tom
On Sun, Aug 18, 2013 at 8:48 AM, Tom Gundersen <teg@jklm.no> wrote:
Hi Thomas,
Thanks for your work on all this, I was hoping someone would pick this up.
On Sun, Aug 18, 2013 at 12:45 AM, Thomas Bächler <thomas@archlinux.org> wrote:
Am 17.08.2013 17:08, schrieb Thomas Bächler:
3) encrypt: I created the sd-encrypt hook, you can find it here: https://paste.xinu.at/8xUYPI/. This changes the command line syntax, the new syntax can be found in the manpage for systemd-cryptsetup-generator. However, the syntax is less powerful than before - for that reason, I added /etc/crypttab.initrd as /etc/crypttab to the initrd, which should support almost everything. There were some problems with adding the same crypttab for initrd and the main system, but that may be my stupiditiy - I hope the separate crypttab is something we can get rid of.
Okay, this one has the wrong help, but otherwise it's what I'm going to use now: https://paste.xinu.at/0PXjlV/
It now adds /etc/crypttab to initramfs. You can make sure that only the necessary devices are activated in initramfs by using the rd.luks.uuid= options on the command line. You can also use rd.luks.uuid= without any crypttab entries, but then you can't set extra options (for me: allow_discards).
We should make it possible to do this without having to put /etc/crypttab in the initramfs.
I guess we basically want to mimic what the fstab generator does: 1) allow options to be specified on the kernel commandline and, optionally, 2) allow further options to be read from /sysroot/etc/cryttab once that has been mounted.
For the first, we would need to extend the syntax, perhaps to {rd.,}luks.uuid.options= or something like that.
Hm, that syntax doesn't make sense. I meant something like "{rd.,}luks.options=${UUID}=${options}".
The second could obviously not be used for partitions used to mount the rootfs (but only /usr), so maybe not that useful, but I guess it makes sense to be consistent.
What do you think?
Tom
On Sun, Aug 18, 2013 at 8:48 AM, Tom Gundersen <teg@jklm.no> wrote:
Hi Thomas,
Thanks for your work on all this, I was hoping someone would pick this up.
On Sun, Aug 18, 2013 at 12:45 AM, Thomas Bächler <thomas@archlinux.org> wrote:
Am 17.08.2013 17:08, schrieb Thomas Bächler:
3) encrypt: I created the sd-encrypt hook, you can find it here: https://paste.xinu.at/8xUYPI/. This changes the command line syntax, the new syntax can be found in the manpage for systemd-cryptsetup-generator. However, the syntax is less powerful than before - for that reason, I added /etc/crypttab.initrd as /etc/crypttab to the initrd, which should support almost everything. There were some problems with adding the same crypttab for initrd and the main system, but that may be my stupiditiy - I hope the separate crypttab is something we can get rid of.
Okay, this one has the wrong help, but otherwise it's what I'm going to use now: https://paste.xinu.at/0PXjlV/
It now adds /etc/crypttab to initramfs. You can make sure that only the necessary devices are activated in initramfs by using the rd.luks.uuid= options on the command line. You can also use rd.luks.uuid= without any crypttab entries, but then you can't set extra options (for me: allow_discards).
We should make it possible to do this without having to put /etc/crypttab in the initramfs.
What do you think about something like the below (totally untested and gmail will mess up the linebreaks, but you hopefully get the drift): commit ff87fedc9b76fc9108eaa9ec1a06c3b0ffac31d4 Author: Tom Gundersen <teg@jklm.no> Date: Sun Aug 18 14:59:00 2013 +0800 cryptsetup-generator: add support for adding options on the kernel commandline diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml index 7950032..2d84d44 100644 --- a/man/systemd-cryptsetup-generator.xml +++ b/man/systemd-cryptsetup-generator.xml @@ -137,6 +137,29 @@ will be activated in the initrd or the real root.</para> </listitem> </varlistentry> + + <varlistentry> + <term><varname>luks.options=</varname></term> + <term><varname>rd.luks.options=</varname></term> + + <listitem><para>Takes a LUKS super + block UUID followed by an '=' and a string + of options separated by commas as argument. + This will override the options for the given + UUID.</para> + <para>If only a list of options without an + UUID is specified, they apply to UUIDs not + specified elsewhere, and without an entry in + /etc/crypttab.</para> + <varname>rd.luks.options=</varname> + is honored only by initial RAM disk + (initrd) while + <varname>luks.options=</varname> is + honored by both the main system and + the initrd.</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>luks.key=</varname></term> <term><varname>rd.luks.key=</varname></term> diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 67460cb..b140f0d 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -233,7 +233,7 @@ static int create_disk( return 0; } -static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cmdline_keyfile) { +static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char ***arg_proc_cmdline_options, char **arg_proc_cmdline_keyfile) { _cleanup_free_ char *line = NULL; char *w = NULL, *state = NULL; int r; @@ -300,6 +300,17 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cm return log_oom(); } + } else if (startswith(word, "luks.options=")) { + if (strv_extend(arg_proc_cmdline_options, word + 13) < 0) + return log_oom(); + + } else if (startswith(word, "rd.luks.options=")) { + + if (in_initrd()) { + if (strv_extend(arg_proc_cmdline_options, word + 16) < 0) + return log_oom(); + } + } else if (startswith(word, "luks.key=")) { if (*arg_proc_cmdline_keyfile) free(*arg_proc_cmdline_keyfile); @@ -332,6 +343,7 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cm int main(int argc, char *argv[]) { _cleanup_strv_free_ char **arg_proc_cmdline_disks_done = NULL; _cleanup_strv_free_ char **arg_proc_cmdline_disks = NULL; + _cleanup_strv_free_ char **arg_proc_cmdline_options = NULL; _cleanup_free_ char *arg_proc_cmdline_keyfile = NULL; _cleanup_fclose_ FILE *f = NULL; unsigned n = 0; @@ -352,7 +364,7 @@ int main(int argc, char *argv[]) { umask(0022); - if (parse_proc_cmdline(&arg_proc_cmdline_disks, &arg_proc_cmdline_keyfile) < 0) + if (parse_proc_cmdline(&arg_proc_cmdline_disks, &arg_proc_cmdline_options, &arg_proc_cmdline_keyfile) < 0) return EXIT_FAILURE; if (!arg_enabled) @@ -407,6 +419,26 @@ int main(int argc, char *argv[]) { continue; } + if (arg_proc_cmdline_options) { + /* + If options are specified on the kernel commandline, let them override + the ones from crypttab. + */ + STRV_FOREACH(i, arg_proc_cmdline_options) { + _cleanup_free_ char *proc_uuid = NULL, *proc_options = NULL; + const char *p = *i; + + k = sscanf(p, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options); + if (k == 2 && streq(proc_uuid, device + 5)) { + if (options) + free(options); + options = strdup(p); + if (!proc_options) + return log_oom(); + } + } + } + if (arg_proc_cmdline_disks) { /* If luks UUIDs are specified on the kernel command line, use them as a filter @@ -447,7 +479,7 @@ next: on the kernel command line and not yet written. */ - _cleanup_free_ char *name = NULL, *device = NULL; + _cleanup_free_ char *name = NULL, *device = NULL, *options = NULL; const char *p = *i; if (startswith(p, "luks-")) @@ -462,7 +494,44 @@ next: if (!name || !device) return log_oom(); - if (create_disk(name, device, arg_proc_cmdline_keyfile, "timeout=0") < 0) + if (arg_proc_cmdline_options) { + /* + If options are specified on the kernel commandline, use them. + */ + char **j; + + STRV_FOREACH(j, arg_proc_cmdline_options) { + _cleanup_free_ char *proc_uuid = NULL, *proc_options = NULL; + const char *s = *j; + int k; + + k = sscanf(s, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options); + if (k == 2) { + if (streq(proc_uuid, device + 5)) { + if (options) + free(options); + options = strdup(proc_options); + if (!options) + return log_oom(); + } + } else if (!options) { + /* + Fall back to options without a specified UUID + */ + options = strdup(s); + if (!options) + return log_oom(); + } + } + } + + if (!options) { + options = strdup("timeout=0"); + if (!options) + return log_oom(); + } + + if (create_disk(name, device, arg_proc_cmdline_keyfile, options) < 0) r = EXIT_FAILURE; }
Am 18.08.2013 10:47, schrieb Tom Gundersen:
What do you think about something like the below (totally untested and gmail will mess up the linebreaks, but you hopefully get the drift):
Looks okay to me, but doesn't seem to work at all.
On Sun, Aug 18, 2013 at 11:08 PM, Thomas Bächler <thomas@archlinux.org> wrote:
Am 18.08.2013 10:47, schrieb Tom Gundersen:
What do you think about something like the below (totally untested and gmail will mess up the linebreaks, but you hopefully get the drift):
Looks okay to me, but doesn't seem to work at all.
For anyone else interested, this worked out in the end and the patch was submitted upstream: <http://lists.freedesktop.org/archives/systemd-devel/2013-August/012705.html>. -t
Am 18.08.2013 02:48, schrieb Tom Gundersen:
On Sun, Aug 18, 2013 at 12:45 AM, Thomas Bächler <thomas@archlinux.org> wrote:
Am 17.08.2013 17:08, schrieb Thomas Bächler:
3) encrypt: I created the sd-encrypt hook, you can find it here: https://paste.xinu.at/8xUYPI/. This changes the command line syntax, the new syntax can be found in the manpage for systemd-cryptsetup-generator. However, the syntax is less powerful than before - for that reason, I added /etc/crypttab.initrd as /etc/crypttab to the initrd, which should support almost everything. There were some problems with adding the same crypttab for initrd and the main system, but that may be my stupiditiy - I hope the separate crypttab is something we can get rid of.
Okay, this one has the wrong help, but otherwise it's what I'm going to use now: https://paste.xinu.at/0PXjlV/
It now adds /etc/crypttab to initramfs. You can make sure that only the necessary devices are activated in initramfs by using the rd.luks.uuid= options on the command line. You can also use rd.luks.uuid= without any crypttab entries, but then you can't set extra options (for me: allow_discards).
We should make it possible to do this without having to put /etc/crypttab in the initramfs.
There's more problems: When using the same crypttab in initrd and system, systemd tries to shut down the volume on shutdown, which leads to a delay of about 2 seconds. Right now, I am running with luks.crypttab=no rd.luks.crypttab=yes to avoid this. So either we need two separate crypttabs or we need to specify all options on the command line.
I guess we basically want to mimic what the fstab generator does: 1) allow options to be specified on the kernel commandline and, optionally, 2) allow further options to be read from /sysroot/etc/cryttab once that has been mounted.
Seems fine to me.
participants (2)
-
Thomas Bächler
-
Tom Gundersen