X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcryptsetup%2Fcryptsetup-generator.c;h=228039d91f0ea2bd2560fc2ce0e12718551fb765;hp=0a51db8939dcfe5e123106fe436bd70907d73f94;hb=c79bb9e4e2e5b96b2ae2c432bf8b0ff9674fce60;hpb=24a988e9aa17a476cb5381e2334aaa2a9972ddd2 diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 0a51db893..228039d91 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -70,8 +70,8 @@ static int create_disk( const char *password, const char *options) { - char _cleanup_free_ *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; - FILE _cleanup_fclose_ *f = NULL; + _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; + _cleanup_fclose_ FILE *f = NULL; bool noauto, nofail; assert(name); @@ -102,29 +102,44 @@ static int create_disk( return -errno; } - fprintf(f, + fputs( "# Automatically generated by systemd-cryptsetup-generator\n\n" "[Unit]\n" - "Description=Cryptography Setup for %%I\n" + "Description=Cryptography Setup for %I\n" "Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)\n" "SourcePath=/etc/crypttab\n" "Conflicts=umount.target\n" "DefaultDependencies=no\n" - "BindsTo=%s dev-mapper-%%i.device\n" - "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n" - "Before=umount.target\n", - d, d); + "BindsTo=dev-mapper-%i.device\n" + "After=systemd-readahead-collect.service systemd-readahead-replay.service\n", + f); if (!nofail) fprintf(f, "Before=cryptsetup.target\n"); - if (password && (streq(password, "/dev/urandom") || - streq(password, "/dev/random") || - streq(password, "/dev/hw_random"))) - fputs("After=systemd-random-seed-load.service\n", f); + if (password) { + if (streq(password, "/dev/urandom") || + streq(password, "/dev/random") || + streq(password, "/dev/hw_random")) + fputs("After=systemd-random-seed-load.service\n", f); + else if (!streq(password, "-") && + !streq(password, "none")) + fprintf(f, + "RequiresMountsFor=%s\n", + password); + } + + if (is_device_path(u)) + fprintf(f, + "BindsTo=%s\n" + "After=%s\n" + "Before=umount.target\n", + d, d); else - fputs("Before=local-fs.target\n", f); + fprintf(f, + "RequiresMountsFor=%s\n", + u); fprintf(f, "\n[Service]\n" @@ -164,13 +179,11 @@ static int create_disk( mkdir_parents_label(to, 0755); if (symlink(from, to) < 0) { - log_error("Failed to create symlink '%s' to '%s': %m", from, to); + log_error("Failed to create symlink %s: %m", to); return -errno; } free(to); - to = NULL; - if (!nofail) to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL); else @@ -180,30 +193,48 @@ static int create_disk( mkdir_parents_label(to, 0755); if (symlink(from, to) < 0) { - log_error("Failed to create symlink '%s' to '%s': %m", from, to); + log_error("Failed to create symlink %s: %m", to); return -errno; } - - free(to); - to = NULL; } e = unit_name_escape(name); + if (!e) + return log_oom(); + + free(to); to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL); if (!to) return log_oom(); mkdir_parents_label(to, 0755); if (symlink(from, to) < 0) { - log_error("Failed to create symlink '%s' to '%s': %m", from, to); + log_error("Failed to create symlink %s: %m", to); return -errno; } + if (!noauto && !nofail) { + int r; + free(p); + p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL); + if (!p) + return log_oom(); + + mkdir_parents_label(p, 0755); + + r = write_string_file(p, + "# Automatically generated by systemd-cryptsetup-generator\n\n" + "[Unit]\n" + "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */ + if (r) + return r; + } + return 0; } -static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { - char _cleanup_free_ *line = NULL; +static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cmdline_keyfile) { + _cleanup_free_ char *line = NULL; char *w = NULL, *state = NULL; int r; size_t l; @@ -218,7 +249,7 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { } FOREACH_WORD_QUOTED(w, l, line, state) { - char _cleanup_free_ *word = NULL; + _cleanup_free_ char *word = NULL; word = strndup(w, l); if (!word) @@ -259,26 +290,29 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { } } else if (startswith(word, "luks.uuid=")) { - char **t; - - t = strv_append(*arg_proc_cmdline_disks, word + 10); - if (!t) + if (strv_extend(arg_proc_cmdline_disks, word + 10) < 0) return log_oom(); - 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) + if (strv_extend(arg_proc_cmdline_disks, word + 13) < 0) return log_oom(); + } - strv_free(*arg_proc_cmdline_disks); - *arg_proc_cmdline_disks = t; + } else if (startswith(word, "luks.key=")) { + *arg_proc_cmdline_keyfile = strdup(word + 9); + if (!*arg_proc_cmdline_keyfile) + return log_oom(); + + } else if (startswith(word, "rd.luks.key=")) { + + if (in_initrd()) { + if (*arg_proc_cmdline_keyfile) + free(*arg_proc_cmdline_keyfile); + *arg_proc_cmdline_keyfile = strdup(word + 12); + if (!*arg_proc_cmdline_keyfile) + return log_oom(); } } else if (startswith(word, "luks.") || @@ -294,12 +328,13 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { } int main(int argc, char *argv[]) { - FILE _cleanup_fclose_ *f = NULL; + _cleanup_fclose_ FILE *f = NULL; unsigned n = 0; int r = EXIT_SUCCESS; char **i; - char _cleanup_strv_free_ **arg_proc_cmdline_disks_done = NULL; - char _cleanup_strv_free_ **arg_proc_cmdline_disks = NULL; + _cleanup_strv_free_ char **arg_proc_cmdline_disks_done = NULL; + _cleanup_strv_free_ char **arg_proc_cmdline_disks = NULL; + _cleanup_free_ char *arg_proc_cmdline_keyfile = NULL; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); @@ -315,7 +350,7 @@ int main(int argc, char *argv[]) { umask(0022); - if (parse_proc_cmdline(&arg_proc_cmdline_disks) < 0) + if (parse_proc_cmdline(&arg_proc_cmdline_disks, &arg_proc_cmdline_keyfile) < 0) return EXIT_FAILURE; if (!arg_enabled) @@ -333,7 +368,7 @@ int main(int argc, char *argv[]) { } } else for (;;) { char line[LINE_MAX], *l; - char _cleanup_free_ *name = NULL, *device = NULL, *password = NULL, *options = NULL; + _cleanup_free_ char *name = NULL, *device = NULL, *password = NULL, *options = NULL; int k; if (!fgets(line, sizeof(line), f)) @@ -358,7 +393,7 @@ int main(int argc, char *argv[]) { for /etc/crypttab and only generate units for those. */ STRV_FOREACH(i, arg_proc_cmdline_disks) { - char _cleanup_free_ *proc_device = NULL, *proc_name = NULL; + _cleanup_free_ char *proc_device = NULL, *proc_name = NULL; const char *p = *i; if (startswith(p, "luks-")) @@ -371,17 +406,11 @@ int main(int argc, char *argv[]) { return log_oom(); if (streq(proc_device, device) || streq(proc_name, name)) { - char **t; - if (create_disk(name, device, password, options) < 0) r = EXIT_FAILURE; - t = strv_append(arg_proc_cmdline_disks_done, p); - if (!t) + if (strv_extend(&arg_proc_cmdline_disks_done, p) < 0) return log_oom(); - - strv_free(arg_proc_cmdline_disks_done); - arg_proc_cmdline_disks_done = t; } } } else { @@ -397,7 +426,7 @@ int main(int argc, char *argv[]) { on the kernel command line and not yet written. */ - char _cleanup_free_ *name = NULL, *device = NULL; + _cleanup_free_ char *name = NULL, *device = NULL; const char *p = *i; if (startswith(p, "luks-")) @@ -412,7 +441,7 @@ int main(int argc, char *argv[]) { if (!name || !device) return log_oom(); - if (create_disk(name, device, NULL, "timeout=0") < 0) + if (create_disk(name, device, arg_proc_cmdline_keyfile, "timeout=0") < 0) r = EXIT_FAILURE; }