cryptsetup-generator.c revision d0d6944cdc17295b17875054ac05e667fe496fed
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/***
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering This file is part of systemd.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Copyright 2010 Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering (at your option) any later version.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is distributed in the hope that it will be useful, but
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Lesser General Public License for more details.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering***/
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <string.h>
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <errno.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <unistd.h>
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include "log.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include "util.h"
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering#include "unit-name.h"
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering#include "mkdir.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "virt.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include "strv.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic const char *arg_dest = "/tmp";
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic bool arg_enabled = true;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensenstatic bool arg_read_crypttab = true;
a09abc4ae0bdc0200324eaa0416f23ff2170ec4eLennart Poetteringstatic char **arg_proc_cmdline_disks = NULL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmekstatic bool has_option(const char *haystack, const char *needle) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *f = haystack;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering size_t l;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(needle);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!haystack)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering l = strlen(needle);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering while ((f = strstr(f, needle))) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (f > haystack && f[-1] != ',') {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering f++;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek if (f[l] != 0 && f[l] != ',') {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering f++;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return true;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return false;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek}
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmekstatic int create_disk(
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *name,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *device,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *password,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *options) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek int r;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek FILE *f = NULL;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek bool noauto, nofail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(name);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering assert(device);
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering noauto = has_option(options, "noauto");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering nofail = has_option(options, "nofail");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (!n) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_error("Failed to allocate unit name.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering p = join(arg_dest, "/", n, NULL);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!p) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to allocate unit file name.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering u = fstab_node_to_udev_node(device);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!u) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to allocate device node.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering d = unit_name_from_path(u, ".device");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!d) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to allocate device name.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek f = fopen(p, "wxe");
8c0b803b97bb0ee6603d9be85fb6b69cd6081eafLennart Poettering if (!f) {
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek r = -errno;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_error("Failed to create unit file: %m");
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek goto fail;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fprintf(f,
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek "# Automatically generated by systemd-cryptsetup-generator\n\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "[Unit]\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Description=Cryptography Setup for %%I\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Documentation=man:systemd-cryptsetup@.service(8)\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "SourcePath=/etc/crypttab\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Conflicts=umount.target\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "DefaultDependencies=no\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "BindTo=%s dev-mapper-%%i.device\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Before=umount.target\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering d, d);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!nofail)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fprintf(f,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Before=cryptsetup.target\n");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (password && (streq(password, "/dev/urandom") ||
12a717f8347f3daf0ae46a2b71c7d011d9c12feaZbigniew Jędrzejewski-Szmek streq(password, "/dev/random") ||
92ee6447b1deef7c79962a8121fdf8e58acb3a83Zbigniew Jędrzejewski-Szmek streq(password, "/dev/hw_random")))
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek fputs("After=systemd-random-seed-load.service\n", f);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fputs("Before=local-fs.target\n", f);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fprintf(f,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "\n[Service]\n"
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek "Type=oneshot\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "RemainAfterExit=yes\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering name, u, strempty(password), strempty(options),
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering name);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (has_option(options, "tmp"))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fprintf(f,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek name);
a174f94d529c7ae9be589867308b669ec9b4dcc0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (has_option(options, "swap"))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fprintf(f,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering name);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden fflush(f);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (ferror(f)) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -errno;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to write file: %m");
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (asprintf(&from, "../%s", n) < 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!noauto) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = join(arg_dest, "/", d, ".wants/", n, NULL);
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden if (!to) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering mkdir_parents_label(to, 0755);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (symlink(from, to) < 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -errno;
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!nofail)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = join(arg_dest, "/cryptsetup.target.requires/", n, NULL);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek to = join(arg_dest, "/cryptsetup.target.wants/", n, NULL);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (!to) {
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden r = -ENOMEM;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek goto fail;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek mkdir_parents_label(to, 0755);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (symlink(from, to) < 0) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_error("Failed to create symlink '%s' to '%s': %m", from, to);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = -errno;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = NULL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering e = unit_name_escape(name);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = join(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!to) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering mkdir_parents_label(to, 0755);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (symlink(from, to) < 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -errno;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto fail;
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering }
fa1c4b518ec7d8ec2d647213ee651cde4d6c9d7eZbigniew Jędrzejewski-Szmek
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering r = 0;
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poetteringfail:
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering free(p);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(n);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(d);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(e);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(from);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (f)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering fclose(f);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic int parse_proc_cmdline(void) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *line, *w, *state;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek int r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering size_t l;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek if (detect_container(NULL) > 0)
a174f94d529c7ae9be589867308b669ec9b4dcc0Lennart Poettering return 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = read_one_line_file("/proc/cmdline", &line);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (r < 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering FOREACH_WORD_QUOTED(w, l, line, state) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *word;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering word = strndup(w, l);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!word) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = -ENOMEM;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek goto finish;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek }
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek if (startswith(word, "luks=")) {
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek r = parse_boolean(word + 5);
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek if (r < 0)
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering arg_enabled = r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "rd.luks=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (in_initrd()) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = parse_boolean(word + 8);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (r < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen arg_enabled = r;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen }
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "luks.crypttab=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = parse_boolean(word + 14);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (r < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering arg_read_crypttab = r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "rd.luks.crypttab=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (in_initrd()) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = parse_boolean(word + 17);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (r < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering arg_read_crypttab = r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "luks.uuid=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char **t;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering t = strv_append(arg_proc_cmdline_disks, word + 10);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!t) {
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering log_error("Out of memory");
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering r = -ENOMEM;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto finish;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering strv_free(arg_proc_cmdline_disks);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering arg_proc_cmdline_disks = t;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "rd.luks.uuid=")) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (in_initrd()) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering char **t;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering t = strv_append(arg_proc_cmdline_disks, word + 13);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!t) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_error("Out of memory");
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering r = -ENOMEM;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering goto finish;
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering }
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering strv_free(arg_proc_cmdline_disks);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering arg_proc_cmdline_disks = t;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering } else if (startswith(word, "luks.") ||
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering (in_initrd() && startswith(word, "rd.luks."))) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_warning("Unknown kernel switch %s. Ignoring.", word);
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering free(word);
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering r = 0;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidtfinish:
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering free(line);
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering return r;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering}
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poetteringint main(int argc, char *argv[]) {
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering FILE *f = NULL;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering int r = EXIT_SUCCESS;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering unsigned n = 0;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering char **i;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (argc > 1 && argc != 4) {
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering log_error("This program takes three or no arguments.");
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering return EXIT_FAILURE;
ae6c3cc009a21df4b51851fb8fe3fde0b7d6d8f0Lennart Poettering }
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering if (argc > 1)
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering arg_dest = argv[1];
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering log_set_target(LOG_TARGET_SAFE);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_parse_environment();
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_open();
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering umask(0022);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (parse_proc_cmdline() < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return EXIT_FAILURE;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!arg_enabled) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = EXIT_SUCCESS;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto finish;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering STRV_FOREACH(i, arg_proc_cmdline_disks) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *name, *device;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *p = *i;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (startswith(p, "luks-"))
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering p += 5;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering name = strappend("luks-", *i);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering device = strappend("UUID=", *i);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!name || !device) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_error("Out of memory");
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering r = EXIT_FAILURE;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering free(name);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt free(device);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering goto finish;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering }
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (create_disk(name, device, NULL, NULL) < 0)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering r = EXIT_FAILURE;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering free(name);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering free(device);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering }
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!arg_read_crypttab)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering return r;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering f = fopen("/etc/crypttab", "re");
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!f) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (errno == ENOENT)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering r = EXIT_SUCCESS;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering else {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering r = EXIT_FAILURE;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_error("Failed to open /etc/crypttab: %m");
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt }
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering goto finish;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering for (;;) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char line[LINE_MAX], *l;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering int k;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!fgets(line, sizeof(line), f))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek n++;
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek l = strstrip(line);
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek if (*l == '#' || *l == 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (k < 2 || k > 4) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = EXIT_FAILURE;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto next;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (create_disk(name, device, password, options) < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = EXIT_FAILURE;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering next:
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(name);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(device);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(password);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt free(options);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringfinish:
6baa7db00812437bbc87e73faa1a11b6cf631958Lennart Poettering if (f)
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering fclose(f);
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt strv_free(arg_proc_cmdline_disks);
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering