On Fri, Feb 20, 2015 at 11:15:36AM +0100, Przemyslaw Rudy wrote: > Could you use the rd.luks.key.tout= instead of hardcoded > JobTimeoutSec=30, as the dracut does? Maybe we could rename it to rd.luks.key.device-timeout= ? tout is not really descriptive. (Old name should be kept for comptibility, the new one should be documented.)
Zbyszek > On 02/20/2015 10:56 AM, Jan Synacek wrote: > > To be more consistent with how dracut parses rd.luks.key, it is now > > allowed to specified it in the format "keyfile[:keyfile_device]". > > > > Should keyfile_device be provided, it needs to be in "UUID=uuid-here" > > format. Also, keyfile path is then treated relatively to the root of the > > keyfile device. > > > > If no keyfile_device appears on the command line, keyfile is then > > treated as an absolute path. > > > > Examples: > > > > rd.luks.key=/etc/key/secret-partition.key > > > > The keyfile is treated as an absolute path. > > > > rd.luks.key=/root.key:UUID=dead-beef > > > > First, the device UUID=dead-beef is temporarily mounted in /mnt and the > > absolute path to the keyfile is constructed as /mnt/root.key. > > --- > > src/cryptsetup/cryptsetup-generator.c | 163 > > +++++++++++++++++++++++++++++++--- > > 1 file changed, 150 insertions(+), 13 deletions(-) > > > > diff --git a/src/cryptsetup/cryptsetup-generator.c > > b/src/cryptsetup/cryptsetup-generator.c > > index 05061c0..3590787 100644 > > --- a/src/cryptsetup/cryptsetup-generator.c > > +++ b/src/cryptsetup/cryptsetup-generator.c > > @@ -43,6 +43,12 @@ typedef struct crypto_device { > > bool create; > > } crypto_device; > > > > +typedef struct key_device { > > + const crypto_device *device; > > + char *keyfile; > > + char *name; > > +} key_device; > > + > > static const char *arg_dest = "/tmp"; > > static bool arg_enabled = true; > > static bool arg_read_crypttab = true; > > @@ -50,6 +56,39 @@ static bool arg_whitelist = false; > > static Hashmap *arg_disks = NULL; > > static char *arg_default_options = NULL; > > static char *arg_default_keyfile = NULL; > > +static key_device *arg_key_device = NULL; > > + > > +static char *crypt_service_name_build(const char *name) > > +{ > > + _cleanup_free_ char *e = NULL; > > + > > + e = unit_name_escape(name); > > + if (!e) > > + return e; > > + > > + return unit_name_build("systemd-cryptsetup", e, ".service"); > > +} > > + > > +static key_device *get_key_device(void) > > +{ > > + key_device *d; > > + > > + if (arg_key_device) > > + return arg_key_device; > > + > > + d = new0(struct key_device, 1); > > + if (!d) > > + return NULL; > > + > > + arg_key_device = d; > > + return arg_key_device; > > +} > > + > > +static void free_key_device(key_device *kd) > > +{ > > + free(kd->keyfile); > > + free(kd->name); > > +} > > > > static int create_disk( > > const char *name, > > @@ -77,11 +116,7 @@ static int create_disk( > > return -EINVAL; > > } > > > > - e = unit_name_escape(name); > > - if (!e) > > - return log_oom(); > > - > > - n = unit_name_build("systemd-cryptsetup", e, ".service"); > > + n = crypt_service_name_build(name); > > if (!n) > > return log_oom(); > > > > @@ -233,6 +268,76 @@ static int create_disk( > > return 0; > > } > > > > +static int create_temporary_mount(void) > > +{ > > + _cleanup_fclose_ FILE *f = NULL; > > + _cleanup_free_ char *p = NULL, *n = NULL, *c = NULL, *wants_dir = > > NULL, *to = NULL, *u = NULL; > > + const char *m = "mnt.mount"; > > + key_device *kd; > > + > > + kd = get_key_device(); > > + if (!kd) > > + return log_oom(); > > + > > + /* no uuid where we should search for the key was specified */ > > + if (!kd->name) > > + return 0; > > + > > + > > + if (!kd->device) { > > + log_warning("No rd.luks.uuid specified. Can't generate a > > temporary mount unit"); > > + return 0; > > + } > > + > > + p = strjoin(arg_dest, "/", m, NULL); > > + if (!p) > > + return log_oom(); > > + > > + > > + f = fopen(p, "wxe"); > > + if (!f) > > + return log_error_errno(errno, "Failed to open %s: %m", p); > > + > > + fprintf(f, "# Automatically generated by > > systemd-cryptsetup-generator\n\n" > > + "[Unit]\n" > > + "Description=Temporary keyfile mount point.\n" > > + "JobTimeoutSec=30\n"); > > + > > + n = strjoin("luks-", kd->device->uuid, NULL); > > + if (!n) > > + return log_oom(); > > + > > + c = crypt_service_name_build(n); > > + if (!c) > > + return log_oom(); > > + > > + u = fstab_node_to_udev_node(kd->name); > > + if (!u) > > + return log_oom(); > > + > > + fprintf(f, "Before=%s\n\n" > > + "[Mount]\n" > > + "What=%s\n" > > + "Where=/mnt\n", > > + c, u); > > + > > + wants_dir = strjoin(arg_dest, "/", c, ".wants", NULL); > > + if (!wants_dir) > > + return log_oom(); > > + > > + to = strjoin(wants_dir, "/", m, NULL); > > + if (!to) > > + return log_oom(); > > + > > + if (mkdir_safe(wants_dir, 0700, 0, 0) < 0) > > + log_error("Failed to create %s: %m", wants_dir); > > + > > + if (symlink("../mnt.mount", to) < 0) > > + return log_error_errno(errno, "Failed to create symlink > > %s: %m", to); > > + > > + return 0; > > +} > > + > > static void free_arg_disks(void) { > > crypto_device *d; > > > > @@ -282,6 +387,7 @@ static crypto_device *get_crypto_device(const char > > *uuid) { > > static int parse_proc_cmdline_item(const char *key, const char *value) { > > int r; > > crypto_device *d; > > + key_device *kd; > > _cleanup_free_ char *uuid = NULL, *uuid_value = NULL; > > > > if (STR_IN_SET(key, "luks", "rd.luks") && value) { > > @@ -308,6 +414,12 @@ static int parse_proc_cmdline_item(const char *key, > > const char *value) { > > > > d->create = arg_whitelist = true; > > > > + kd = get_key_device(); > > + if (!kd) > > + return log_oom(); > > + > > + kd->device = d; > > + > > } else if (STR_IN_SET(key, "luks.options", "rd.luks.options") && > > value) { > > > > r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, > > &uuid_value); > > @@ -324,16 +436,37 @@ static int parse_proc_cmdline_item(const char *key, > > const char *value) { > > > > } else if (STR_IN_SET(key, "luks.key", "rd.luks.key") && value) { > > > > - r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, > > &uuid_value); > > - if (r == 2) { > > - d = get_crypto_device(uuid); > > - if (!d) > > + char **parts = NULL; > > + int l; > > + > > + parts = strv_split(value, ":"); > > + if (!parts) > > + return log_oom(); > > + l = strv_length(parts); > > + > > + if (l > 1) { > > + kd = get_key_device(); > > + if (!kd) > > return log_oom(); > > > > - free(d->keyfile); > > - d->keyfile = uuid_value; > > - uuid_value = NULL; > > - } else if (free_and_strdup(&arg_default_keyfile, value)) > > + kd->keyfile = strdup(parts[0]); > > + if (!kd->keyfile) > > + return log_oom(); > > + > > + if (!startswith(parts[1], "UUID=")) > > + log_warning("Keyfile device should start > > with \"UUID=\""); > > + else { > > + kd->name = strdup(parts[1]); > > + if (!kd->name) > > + return log_oom(); > > + > > + value = strjoin("/mnt", parts[0], NULL); > > + if (!value) > > + return log_oom(); > > + } > > + } > > + > > + if (free_and_strdup(&arg_default_keyfile, value) < 0) > > return log_oom(); > > > > } else if (STR_IN_SET(key, "luks.name", "rd.luks.name") && value) { > > @@ -504,12 +637,16 @@ int main(int argc, char *argv[]) { > > if (add_proc_cmdline_devices() < 0) > > goto cleanup; > > > > + if (create_temporary_mount() < 0) > > + goto cleanup; > > + > > r = EXIT_SUCCESS; > > > > cleanup: > > free_arg_disks(); > > free(arg_default_options); > > free(arg_default_keyfile); > > + free_key_device(arg_key_device); > > > > return r; > > } > > > _______________________________________________ > systemd-devel mailing list > systemd-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel