cryptsetup: allow configuration of LUKS disks via the kernel cmdline

This generalizes a bit of the functionality already available in dracut.
This commit is contained in:
Lennart Poettering 2012-06-22 10:11:06 +02:00
parent 601913d616
commit 66a78c2b95
6 changed files with 189 additions and 12 deletions

View File

@ -203,10 +203,10 @@
<varlistentry>
<term><varname>udev.log-priority=</varname></term>
<term><varname>udev.children-max=</varname></term>
<term><varname>udev.udev.exec-delay=</varname></term>
<term><varname>rd.udev.log-priority=</varname></term>
<term><varname>udev.children-max=</varname></term>
<term><varname>rd.udev.children-max=</varname></term>
<term><varname>udev.udev.exec-delay=</varname></term>
<term><varname>rd.udev.udev.exec-delay=</varname></term>
<listitem>
@ -216,8 +216,35 @@
<citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
</variablelist>
<varlistentry>
<term><varname>plymouth.enable=</varname></term>
<listitem>
<para>May be used to disable
the Plymouth boot splash. For
details see
<citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>luks=</varname></term>
<term><varname>rd.luks=</varname></term>
<term><varname>luks.crypttab=</varname></term>
<term><varname>rd.luks.crypttab=</varname></term>
<term><varname>luks.uuid=</varname></term>
<term><varname>rd.luks.uuid=</varname></term>
<listitem>
<para>Configures the LUKS
full-disk encryption logic at
boot. For details see
<citerefentry><refentrytitle>cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -374,7 +374,8 @@ static int parse_proc_cmdline_word(const char *word) {
arg_sysv_console = r;
#endif
} else if (startswith(word, "systemd.")) {
} else if (startswith(word, "systemd.") ||
(in_initrd() && startswith(word, "rd.systemd."))) {
log_warning("Unknown kernel switch %s. Ignoring.", word);

View File

@ -27,8 +27,13 @@
#include "util.h"
#include "unit-name.h"
#include "mkdir.h"
#include "virt.h"
#include "strv.h"
const char *arg_dest = "/tmp";
static const char *arg_dest = "/tmp";
static bool arg_enabled = true;
static bool arg_read_crypttab = true;
static char **arg_proc_cmdline_disks = NULL;
static bool has_option(const char *haystack, const char *needle) {
const char *f = haystack;
@ -235,10 +240,111 @@ fail:
return r;
}
static int parse_proc_cmdline(void) {
char *line, *w, *state;
int r;
size_t l;
if (detect_container(NULL) > 0)
return 0;
r = read_one_line_file("/proc/cmdline", &line);
if (r < 0) {
log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
return 0;
}
FOREACH_WORD_QUOTED(w, l, line, state) {
char *word;
word = strndup(w, l);
if (!word) {
r = -ENOMEM;
goto finish;
}
if (startswith(word, "luks=")) {
r = parse_boolean(word + 5);
if (r < 0)
log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
else
arg_enabled = r;
} else if (startswith(word, "rd.luks=")) {
if (in_initrd()) {
r = parse_boolean(word + 8);
if (r < 0)
log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
else
arg_enabled = r;
}
} else if (startswith(word, "luks.crypttab=")) {
r = parse_boolean(word + 14);
if (r < 0)
log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
else
arg_read_crypttab = r;
} else if (startswith(word, "rd.luks.crypttab=")) {
if (in_initrd()) {
r = parse_boolean(word + 17);
if (r < 0)
log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
else
arg_read_crypttab = r;
}
} else if (startswith(word, "luks.uuid=")) {
char **t;
t = strv_append(arg_proc_cmdline_disks, word + 10);
if (!t) {
log_error("Out of memory");
r = -ENOMEM;
goto finish;
}
strv_free(arg_proc_cmdline_disks);
arg_proc_cmdline_disks = t;
} else if (startswith(word, "rd.luks.uuid=")) {
if (in_initrd()) {
char **t;
t = strv_append(arg_proc_cmdline_disks, word + 13);
if (!t) {
log_error("Out of memory");
r = -ENOMEM;
goto finish;
}
strv_free(arg_proc_cmdline_disks);
arg_proc_cmdline_disks = t;
}
} else if (startswith(word, "luks.") ||
(in_initrd() && startswith(word, "rd.luks."))) {
log_warning("Unknown kernel switch %s. Ignoring.", word);
}
free(word);
}
r = 0;
finish:
free(line);
return r;
}
int main(int argc, char *argv[]) {
FILE *f;
FILE *f = NULL;
int r = EXIT_SUCCESS;
unsigned n = 0;
char **i;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
@ -254,6 +360,42 @@ int main(int argc, char *argv[]) {
umask(0022);
if (parse_proc_cmdline() < 0)
return EXIT_FAILURE;
if (!arg_enabled) {
r = EXIT_SUCCESS;
goto finish;
}
STRV_FOREACH(i, arg_proc_cmdline_disks) {
char *name, *device;
const char *p = *i;
if (startswith(p, "luks-"))
p += 5;
name = strappend("luks-", *i);
device = strappend("UUID=", *i);
if (!name || !device) {
log_error("Out of memory");
r = EXIT_FAILURE;
free(name);
free(device);
goto finish;
}
if (create_disk(name, device, NULL, NULL) < 0)
r = EXIT_FAILURE;
free(name);
free(device);
}
if (!arg_read_crypttab)
return r;
f = fopen("/etc/crypttab", "re");
if (!f) {
@ -299,5 +441,10 @@ int main(int argc, char *argv[]) {
}
finish:
if (f)
fclose(f);
strv_free(arg_proc_cmdline_disks);
return r;
}

View File

@ -112,7 +112,8 @@ static int parse_proc_cmdline(void) {
if (detect_container(NULL) > 0)
return 0;
if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
r = read_one_line_file("/proc/cmdline", &line);
if (r < 0) {
log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
return 0;
}
@ -125,8 +126,8 @@ static int parse_proc_cmdline(void) {
arg_force = true;
else if (strneq(w, "fsck.mode=skip", l))
arg_skip = true;
else if (startswith(w, "fsck.mode"))
log_warning("Invalid fsck.mode= parameter. Ignoring.");
else if (startswith(w, "fsck"))
log_warning("Invalid fsck parameter. Ignoring.");
#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
else if (strneq(w, "fastboot", l))
arg_skip = true;

View File

@ -2648,7 +2648,8 @@ static int server_parse_proc_cmdline(Server *s) {
log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
else
s->forward_to_console = r;
}
} else if (startswith(word, "systemd.journald"))
log_warning("Invalid systemd.journald parameter. Ignoring.");
free(word);
}

View File

@ -52,8 +52,8 @@ static int parse_proc_cmdline(void) {
arg_force = true;
else if (strneq(w, "quotacheck.mode=skip", l))
arg_skip = true;
else if (startswith(w, "quotacheck.mode"))
log_warning("Invalid quotacheck.mode= parameter. Ignoring.");
else if (startswith(w, "quotacheck"))
log_warning("Invalid quotacheck parameter. Ignoring.");
#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
else if (strneq(w, "forcequotacheck", l))
arg_force = true;