cryptsetup-generator.c revision 608d41f355d580a6f73e76b298bfc1b4e3155b80
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "log.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "util.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "unit-name.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "mkdir.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "virt.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "strv.h"
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "fileio.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poetteringstatic const char *arg_dest = "/tmp";
25300b5a1fcf54674a69d0f4ab08925be00b0227Lennart Poetteringstatic bool arg_enabled = true;
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringstatic bool arg_read_crypttab = true;
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poetteringstatic bool has_option(const char *haystack, const char *needle) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering const char *f = haystack;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size_t l;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(needle);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!haystack)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering l = strlen(needle);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt while ((f = strstr(f, needle))) {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (f > haystack && f[-1] != ',') {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering f++;
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering continue;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (f[l] != 0 && f[l] != ',') {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering f++;
afc6adb5ec7e73bc13156c43f52fb015cd80cc68Lennart Poettering continue;
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering return false;
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int create_disk(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *name,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *device,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *password,
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering const char *options) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char _cleanup_free_ *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering FILE _cleanup_fclose_ *f = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bool noauto, nofail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(device);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering noauto = has_option(options, "noauto");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering nofail = has_option(options, "nofail");
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service");
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering if (!n)
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering return log_oom();
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering p = strjoin(arg_dest, "/", n, NULL);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering if (!p)
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering return log_oom();
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering u = fstab_node_to_udev_node(device);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!u)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return log_oom();
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering d = unit_name_from_path(u, ".device");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!d)
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering return log_oom();
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering f = fopen(p, "wxe");
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering if (!f) {
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering log_error("Failed to create unit file %s: %m", p);
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering return -errno;
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering }
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering fprintf(f,
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "# Automatically generated by systemd-cryptsetup-generator\n\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "[Unit]\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "Description=Cryptography Setup for %%I\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "SourcePath=/etc/crypttab\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "Conflicts=umount.target\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "DefaultDependencies=no\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "BindsTo=%s dev-mapper-%%i.device\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "Before=umount.target\n",
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering d, d);
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering if (!nofail)
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering fprintf(f,
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "Before=cryptsetup.target\n");
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering if (password && (streq(password, "/dev/urandom") ||
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering streq(password, "/dev/random") ||
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering streq(password, "/dev/hw_random")))
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering fputs("After=systemd-random-seed-load.service\n", f);
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering else
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering fputs("Before=local-fs.target\n", f);
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering fprintf(f,
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "\n[Service]\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "Type=oneshot\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "RemainAfterExit=yes\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering name, u, strempty(password), strempty(options),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (has_option(options, "tmp"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering name);
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering if (has_option(options, "swap"))
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering fprintf(f,
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fflush(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (ferror(f)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to write file %s: %m", p);
e1427b138fbf7b7f13bb61187635b882be3ca2b2Michal Schmidt return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (asprintf(&from, "../%s", n) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!noauto) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!to)
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering return log_oom();
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering mkdir_parents_label(to, 0755);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering if (symlink(from, to) < 0) {
b9a8d250810d4803bc9bf6b36932b528cb991d1eLennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
b9a8d250810d4803bc9bf6b36932b528cb991d1eLennart Poettering return -errno;
b9a8d250810d4803bc9bf6b36932b528cb991d1eLennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(to);
fbe550738d03b178bb004a1390e74115e904118aLennart Poettering if (!nofail)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!to)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mkdir_parents_label(to, 0755);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (symlink(from, to) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = unit_name_escape(name);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!e)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(to);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!to)
76b543756ef69ce69784d571aefe8de65eaeb331Lennart Poettering return log_oom();
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt mkdir_parents_label(to, 0755);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (symlink(from, to) < 0) {
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return -errno;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering return 0;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt}
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic int parse_proc_cmdline(char ***arg_proc_cmdline_disks) {
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering char _cleanup_free_ *line = NULL;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt char *w = NULL, *state = NULL;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size_t l;
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering if (detect_container(NULL) > 0)
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering return 0;
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering r = read_one_line_file("/proc/cmdline", &line);
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering if (r < 0) {
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering FOREACH_WORD_QUOTED(w, l, line, state) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering char _cleanup_free_ *word = NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering word = strndup(w, l);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!word)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return log_oom();
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (startswith(word, "luks=")) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt r = parse_boolean(word + 5);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering else
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering arg_enabled = r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering } else if (startswith(word, "rd.luks=")) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (in_initrd()) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = parse_boolean(word + 8);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt else
943aca8efb39453e3994ccdd1e08534b788c5aeeLennart Poettering arg_enabled = r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering } else if (startswith(word, "luks.crypttab=")) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = parse_boolean(word + 14);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
11b90e69e5620c2483b019340eff121d504db115Lennart Poettering log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
11b90e69e5620c2483b019340eff121d504db115Lennart Poettering else
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering arg_read_crypttab = r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt } else if (startswith(word, "rd.luks.crypttab=")) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (in_initrd()) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = parse_boolean(word + 17);
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering else
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering arg_read_crypttab = r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering } else if (startswith(word, "luks.uuid=")) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering char **t;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt t = strv_append(*arg_proc_cmdline_disks, word + 10);
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering if (!t)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_free(*arg_proc_cmdline_disks);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *arg_proc_cmdline_disks = t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (startswith(word, "rd.luks.uuid=")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (in_initrd()) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char **t;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering t = strv_append(*arg_proc_cmdline_disks, word + 13);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!t)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
5bb658a1784a0fd4f0f32adb4b1fb636ff503f7dKay Sievers
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt strv_free(*arg_proc_cmdline_disks);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt *arg_proc_cmdline_disks = t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt } else if (startswith(word, "luks.") ||
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt (in_initrd() && startswith(word, "rd.luks."))) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning("Unknown kernel switch %s. Ignoring.", word);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_uniq(*arg_proc_cmdline_disks);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
71fda00f320379f5cbee8e118848de98caaa229dLennart Poetteringint main(int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering FILE _cleanup_fclose_ *f = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned n = 0;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering int r = EXIT_SUCCESS;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering char **i;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering char _cleanup_strv_free_ **arg_proc_cmdline_disks_done = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char _cleanup_strv_free_ **arg_proc_cmdline_disks = NULL;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering if (argc > 1 && argc != 4) {
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering log_error("This program takes three or no arguments.");
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering return EXIT_FAILURE;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering }
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (argc > 1)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_dest = argv[1];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_set_target(LOG_TARGET_SAFE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_parse_environment();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_open();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering umask(0022);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (parse_proc_cmdline(&arg_proc_cmdline_disks) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return EXIT_FAILURE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!arg_enabled)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return EXIT_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_read_crypttab) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering f = fopen("/etc/crypttab", "re");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!f) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (errno == ENOENT)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = EXIT_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = EXIT_FAILURE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to open /etc/crypttab: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering } else for (;;) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char line[LINE_MAX], *l;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char _cleanup_free_ *name = NULL, *device = NULL, *password = NULL, *options = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering if (!fgets(line, sizeof(line), f))
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering n++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering l = strstrip(line);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering if (*l == '#' || *l == 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering continue;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (k < 2 || k > 4) {
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering r = EXIT_FAILURE;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering continue;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering }
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering if (arg_proc_cmdline_disks) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /*
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering If luks UUIDs are specified on the kernel command line, use them as a filter
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for /etc/crypttab and only generate units for those.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering STRV_FOREACH(i, arg_proc_cmdline_disks) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char _cleanup_free_ *proc_device = NULL, *proc_name = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *p = *i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (startswith(p, "luks-"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p += 5;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering proc_name = strappend("luks-", p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering proc_device = strappend("UUID=", p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!proc_name || !proc_device)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(proc_device, device) || streq(proc_name, name)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char **t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (create_disk(name, device, password, options) < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = EXIT_FAILURE;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering t = strv_append(arg_proc_cmdline_disks_done, p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!t)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering strv_free(arg_proc_cmdline_disks_done);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_proc_cmdline_disks_done = t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (create_disk(name, device, password, options) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = EXIT_FAILURE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering STRV_FOREACH(i, arg_proc_cmdline_disks) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /*
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek Generate units for those UUIDs, which were specified
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering on the kernel command line and not yet written.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char _cleanup_free_ *name = NULL, *device = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *p = *i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (startswith(p, "luks-"))
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek p += 5;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (strv_contains(arg_proc_cmdline_disks_done, p))
3e044c492e3ebe64f4e3175c94f9db8a62557b82Markus Elfring continue;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering name = strappend("luks-", p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering device = strappend("UUID=", p);
if (!name || !device)
return log_oom();
if (create_disk(name, device, NULL, "timeout=0") < 0)
r = EXIT_FAILURE;
}
return r;
}