gpt-auto-generator.c revision 59512f21d77d984cf1363fb0d1770218c5e17020
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina This file is part of systemd.
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina Copyright 2013 Lennart Poettering
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina systemd is free software; you can redistribute it and/or modify it
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina under the terms of the GNU Lesser General Public License as published by
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina the Free Software Foundation; either version 2.1 of the License, or
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina (at your option) any later version.
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina systemd is distributed in the hope that it will be useful, but
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina WITHOUT ANY WARRANTY; without even the implied warranty of
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina Lesser General Public License for more details.
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina You should have received a copy of the GNU Lesser General Public License
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina along with systemd; If not, see <http://www.gnu.org/licenses/>.
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březinastatic bool arg_enabled = true;
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březinastatic bool arg_root_enabled = true;
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březinastatic bool arg_root_rw = false;
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březinastatic int add_cryptsetup(const char *id, const char *what, bool rw, char **device) {
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
9b74009c1260e6f3b1031a6ae110bf1d957cba81Pavel Březina return log_error_errno(r, "Failed to generate unit name: %m");
9b74009c1260e6f3b1031a6ae110bf1d957cba81Pavel Březina r = unit_name_build("systemd-cryptsetup", e, ".service", &n);
9b74009c1260e6f3b1031a6ae110bf1d957cba81Pavel Březina return log_error_errno(r, "Failed to generate unit name: %m");
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina return log_error_errno(errno, "Failed to create unit file %s: %m", p);
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "# Automatically generated by systemd-gpt-auto-generator\n\n"
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "Description=Cryptography Setup for %%I\n"
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "DefaultDependencies=no\n"
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek "Conflicts=umount.target\n"
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek "BindsTo=dev-mapper-%%i.device %s\n"
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek "Before=umount.target cryptsetup.target\n"
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek "After=%s\n"
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek "IgnoreOnIsolate=true\n"
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "[Service]\n"
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "Type=oneshot\n"
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina "RemainAfterExit=yes\n"
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek "TimeoutSec=0\n" /* the binary handles timeouts anyway */
552390afcc81af96ca201fa6c25ddefbbecbeb4eJakub Hrozek "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
552390afcc81af96ca201fa6c25ddefbbecbeb4eJakub Hrozek "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina return log_error_errno(errno, "Failed to write file %s: %m", p);
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
e157b9f6cb370e1b94bcac2044d26ad66d640fbaPavel Březina return log_error_errno(errno, "Failed to create symlink %s: %m", to);
488b455f6b7881ec108a127840b1c1f1523d937fMichal Židek to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
if (!to)
return log_oom();
free(p);
return log_oom();
r = write_string_file(p,
if (!ret)
return log_oom();
static int add_mount(
const char *id,
const char *what,
const char *where,
const char *fstype,
bool rw,
const char *options,
const char *description,
const char *post) {
return log_oom();
fprintf(f,
if (post)
fprintf(f,
if (fstype)
if (options)
fflush(f);
if (ferror(f))
if (post) {
if (!lnk)
return log_oom();
static int add_automount(
const char *id,
const char *what,
const char *where,
const char *fstype,
bool rw,
const char *options,
const char *description,
if (options)
if (!opt)
return log_oom();
what,
rw,
opt,
NULL);
return log_oom();
fprintf(f,
fflush(f);
if (ferror(f))
if (!lnk)
return log_oom();
if (r == -ENOENT)
static int probe_and_add_mount(
const char *id,
const char *what,
const char *where,
bool rw,
const char *description,
const char *post) {
errno = 0;
if (errno == 0)
return log_oom();
return -errno;
errno = 0;
r = blkid_do_safeprobe(b);
return add_mount(
id,
what,
rw,
NULL,
post);
if (!unit)
return log_oom();
fprintf(f,
path);
fflush(f);
if (ferror(f))
if (!lnk)
return log_oom();
#ifdef ENABLE_EFI
if (!is_efi_boot()) {
if (in_initrd()) {
if (r == -ENOENT) {
errno = 0;
if (errno == 0)
return log_oom();
return -errno;
errno = 0;
r = blkid_do_safeprobe(b);
what,
if (!udev)
return log_oom();
return log_oom();
if (!name)
if (!name) {
if (!parent) {
if (!devtype) {
if (!node) {
errno = 0;
if (errno == 0)
return log_oom();
errno = 0;
r = blkid_do_safeprobe(b);
errno = 0;
errno = 0;
if (!pl) {
if (errno == 0)
return log_oom();
return log_oom();
return log_oom();
return log_oom();
r = udev_enumerate_scan_devices(e);
int nr;
unsigned long long flags;
if (!subnode)
if (!pp)
if (nr < 0)
if (!stype)
if (!boot)
return log_oom();
if (!home)
return log_oom();
if (!srv)
return log_oom();
if (boot) {
if (home) {
if (srv) {
k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
return -errno;
return -errno;
arg_enabled = r;
arg_root_rw = true;
arg_root_rw = false;
static int add_root_mount(void) {
#ifdef ENABLE_EFI
if (!is_efi_boot()) {
if (r == -ENOENT) {
return add_mount(
"/dev/gpt-auto-root",
NULL,
NULL,
static int add_mounts(void) {
return EXIT_FAILURE;
log_open();
return EXIT_SUCCESS;
if (!arg_enabled) {
return EXIT_SUCCESS;
if (arg_root_enabled)
r = add_root_mount();
if (!in_initrd()) {
k = add_mounts();