gpt-auto-generator.c revision 9c4495ca561624c2f0085507dd1288ed5f1247c5
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/***
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering This file is part of systemd.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Copyright 2013 Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is free software; you can redistribute it and/or modify it
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering under the terms of the GNU Lesser General Public License as published by
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering (at your option) any later version.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is distributed in the hope that it will be useful, but
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Lesser General Public License for more details.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering You should have received a copy of the GNU Lesser General Public License
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering***/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <unistd.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <stdlib.h>
8bb3626dac93c0157989fb87afe0212958d7dbb4Zbigniew Jędrzejewski-Szmek#include <fcntl.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <sys/ioctl.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <sys/statfs.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <blkid/blkid.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#ifdef HAVE_LINUX_BTRFS_H
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <linux/btrfs.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#endif
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "sd-id128.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "libudev.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "path-util.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "util.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "mkdir.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "missing.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "udev-util.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "special.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "unit-name.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "virt.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "generator.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "gpt.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "fileio.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "efivars.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "blkid-util.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic const char *arg_dest = "/tmp";
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic bool arg_enabled = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic bool arg_root_enabled = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic bool arg_root_rw = false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int add_swap(const char *path) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("Adding swap: %s", path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering name = unit_name_from_path(path, ".swap");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!name)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unit = strjoin(arg_dest, "/", name, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!unit)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering f = fopen(unit, "wxe");
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (!f) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Unit]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Description=Swap Partition\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Swap]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "What=%s\n",
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fflush(f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (ferror(f)) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!lnk)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering mkdir_parents_label(lnk, 0755);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (symlink(unit, lnk) < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int add_cryptsetup(const char *id, const char *what, char **device) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *from, *ret;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(id);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(what);
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering assert(device);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering d = unit_name_from_path(what, ".device");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!d)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering e = unit_name_escape(id);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!e)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering n = unit_name_build("systemd-cryptsetup", e, ".service");
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (!n)
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering return log_oom();
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering p = strjoin(arg_dest, "/", n, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!n)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering f = fopen(p, "wxe");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!f) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create unit file %s: %m", p);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Unit]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Description=Cryptography Setup for %%I\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "DefaultDependencies=no\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Conflicts=umount.target\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "BindsTo=dev-mapper-%%i.device %s\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Before=umount.target cryptsetup.target\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "After=%s\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "IgnoreOnIsolate=true\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "After=systemd-readahead-collect.service systemd-readahead-replay.service\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Service]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Type=oneshot\n"
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "RemainAfterExit=yes\n"
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s'\n"
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering d, d,
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering id, what,
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering id);
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fflush(f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (ferror(f)) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to write file %s: %m", p);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering from = strappenda("../", n);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!to)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering mkdir_parents_label(to, 0755);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (symlink(from, to) < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create symlink %s: %m", to);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering free(to);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!to)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering mkdir_parents_label(to, 0755);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (symlink(from, to) < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create symlink %s: %m", to);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering free(to);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering if (!to)
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering return log_oom();
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering mkdir_parents_label(to, 0755);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering if (symlink(from, to) < 0) {
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering log_error("Failed to create symlink %s: %m", to);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering return -errno;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering }
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(p);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!p)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering mkdir_parents_label(p, 0755);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = write_string_file(p,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Unit]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to write device drop-in: %s", strerror(-r));
f131770b1465fbf423881f16ba85523a05f846feVeres Lajos return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering ret = strappend("/dev/mapper/", id);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!ret)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering *device = ret;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int add_mount(
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *id,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *what,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *where,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *fstype,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *options,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *description,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *post) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(id);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(what);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(where);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(description);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("Adding %s: %s %s", where, what, strna(fstype));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (streq_ptr(fstype, "crypto_LUKS")) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = add_cryptsetup(id, what, &crypto_what);
f131770b1465fbf423881f16ba85523a05f846feVeres Lajos if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering what = crypto_what;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fstype = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unit = unit_name_from_path(where, ".mount");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!unit)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering p = strjoin(arg_dest, "/", unit, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!p)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering f = fopen(p, "wxe");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!f) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Unit]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Description=%s\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n",
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering description);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (post)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "Before=%s\n", post);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "[Mount]\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "What=%s\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Where=%s\n",
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering what, where);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (fstype)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "Type=%s\n", fstype);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (options)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "Options=%s\n", options);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fflush(f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (ferror(f)) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to write unit file %s: %m", p);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (post) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!lnk)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering mkdir_parents_label(lnk, 0755);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (symlink(p, lnk) < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidtstatic int probe_and_add_mount(
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *id,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *what,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *where,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *description,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *post) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *fstype;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt assert(id);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt assert(what);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(where);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(description);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (path_is_mount_point(where, true) <= 0 &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dir_is_empty(where) <= 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("%s already populated, ignoring.", where);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering /* Let's check the partition type here, so that we know
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering * whether to do LUKS magic. */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering b = blkid_new_probe_from_filename(what);
8bb3626dac93c0157989fb87afe0212958d7dbb4Zbigniew Jędrzejewski-Szmek if (!b) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (errno == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to allocate prober: %m");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
25b3245fb483e52766867dfe33ce271011caaca9Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_enable_superblocks(b, 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_do_safeprobe(b);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else if (r != 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (errno == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = EIO;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to probe %s: %m", what);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return add_mount(
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek id,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering what,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering where,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fstype,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering NULL,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering description,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering post);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poetteringstatic int enumerate_partitions(dev_t devnum) {
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
cd556b6ca8aec8dd371806afedec45f852f8f724Zbigniew Jędrzejewski-Szmek _cleanup_blkid_free_probe_ blkid_probe b = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *home = NULL, *srv = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering struct udev_list_entry *first, *item;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering struct udev_device *parent = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *node, *pttype, *devtype;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int home_nr = -1, srv_nr = -1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_partlist pl;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r, k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dev_t pn;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering udev = udev_new();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!udev)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', devnum);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!d)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
cd556b6ca8aec8dd371806afedec45f852f8f724Zbigniew Jędrzejewski-Szmek parent = udev_device_get_parent(d);
cd556b6ca8aec8dd371806afedec45f852f8f724Zbigniew Jędrzejewski-Szmek if (!parent)
cd556b6ca8aec8dd371806afedec45f852f8f724Zbigniew Jędrzejewski-Szmek return 0;
cd556b6ca8aec8dd371806afedec45f852f8f724Zbigniew Jędrzejewski-Szmek
8bb3626dac93c0157989fb87afe0212958d7dbb4Zbigniew Jędrzejewski-Szmek /* Does it have a devtype? */
8bb3626dac93c0157989fb87afe0212958d7dbb4Zbigniew Jędrzejewski-Szmek devtype = udev_device_get_devtype(parent);
8bb3626dac93c0157989fb87afe0212958d7dbb4Zbigniew Jędrzejewski-Szmek if (!devtype)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Is this a disk or a partition? We only care for disks... */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!streq(devtype, "disk"))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Does it have a device node? */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering node = udev_device_get_devnode(parent);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!node)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering log_debug("Root device %s.", node);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering pn = udev_device_get_devnum(parent);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (major(pn) == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering b = blkid_new_probe_from_filename(node);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!b) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (errno == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed allocate prober: %m");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_enable_superblocks(b, 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_enable_partitions(b, 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_do_safeprobe(b);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else if (r != 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (errno == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = EIO;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to probe %s: %m", node);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r != 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (errno == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = EIO;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to determine partition table type of %s: %m", node);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* We only do this all for GPT... */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!streq_ptr(pttype, "gpt"))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering errno = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering pl = blkid_probe_get_partitions(b);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!pl) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (errno == 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to list partitions of %s: %m", node);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering e = udev_enumerate_new(udev);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!e)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return log_oom();
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (r < 0)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return log_oom();
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (r < 0)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return log_oom();
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering r = udev_enumerate_scan_devices(e);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (r < 0) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_error("Failed to enumerate partitions on %s: %s", node, strerror(-r));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return r;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering }
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering first = udev_enumerate_get_list_entry(e);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering udev_list_entry_foreach(item, first) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *q;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering const char *stype, *subnode;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering sd_id128_t type_id;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering blkid_partition pp;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering dev_t qn;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering int nr;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (!q)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering continue;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering qn = udev_device_get_devnum(q);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (major(qn) == 0)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering continue;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (qn == devnum)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering continue;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (qn == pn)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering continue;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering subnode = udev_device_get_devnode(q);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (!subnode)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering continue;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering pp = blkid_partlist_devno_to_partition(pl, qn);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (!pp)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering nr = blkid_partition_get_partno(pp);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (nr < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering stype = blkid_partition_get_type_string(pp);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!stype)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (sd_id128_from_string(stype, &type_id) < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (sd_id128_equal(type_id, GPT_SWAP)) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k = add_swap(subnode);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt if (k < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else if (sd_id128_equal(type_id, GPT_HOME)) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* We only care for the first /home partition */
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (home && nr >= home_nr)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering home_nr = nr;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(home);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt home = strdup(subnode);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (!home)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poettering
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt } else if (sd_id128_equal(type_id, GPT_SRV)) {
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* We only care for the first /srv partition */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (srv && nr >= srv_nr)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering continue;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt srv_nr = nr;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(srv);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering srv = strdup(node);
if (!srv)
return log_oom();
}
}
if (home) {
k = probe_and_add_mount("home", home, "/home", "Home Partition", SPECIAL_LOCAL_FS_TARGET);
if (k < 0)
r = k;
}
if (srv) {
k = probe_and_add_mount("srv", srv, "/srv", "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
if (k < 0)
r = k;
}
return r;
}
static int get_btrfs_block_device(const char *path, dev_t *dev) {
struct btrfs_ioctl_fs_info_args fsi = {};
_cleanup_close_ int fd = -1;
uint64_t id;
assert(path);
assert(dev);
fd = open(path, O_DIRECTORY|O_CLOEXEC);
if (fd < 0)
return -errno;
if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0)
return -errno;
/* We won't do this for btrfs RAID */
if (fsi.num_devices != 1)
return 0;
for (id = 1; id <= fsi.max_id; id++) {
struct btrfs_ioctl_dev_info_args di = {
.devid = id,
};
struct stat st;
if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) {
if (errno == ENODEV)
continue;
return -errno;
}
if (stat((char*) di.path, &st) < 0)
return -errno;
if (!S_ISBLK(st.st_mode))
return -ENODEV;
if (major(st.st_rdev) == 0)
return -ENODEV;
*dev = st.st_rdev;
return 1;
}
return -ENODEV;
}
static int get_block_device(const char *path, dev_t *dev) {
struct stat st;
struct statfs sfs;
assert(path);
assert(dev);
if (lstat(path, &st))
return -errno;
if (major(st.st_dev) != 0) {
*dev = st.st_dev;
return 1;
}
if (statfs(path, &sfs) < 0)
return -errno;
if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
return get_btrfs_block_device(path, dev);
return 0;
}
static int parse_proc_cmdline_item(const char *key, const char *value) {
int r;
assert(key);
if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
r = parse_boolean(value);
if (r < 0)
log_warning("Failed to parse gpt-auto switch %s. Ignoring.", value);
arg_enabled = r;
} else if (streq(key, "root") && value) {
/* Disable root disk logic if there's a root= value
* specified (unless it happens to be "gpt-auto") */
arg_root_enabled = streq(value, "gpt-auto");
} else if (streq(key, "rw") && !value)
arg_root_rw = true;
else if (streq(key, "ro") && !value)
arg_root_rw = false;
else if (startswith(key, "systemd.gpt-auto.") || startswith(key, "rd.systemd.gpt-auto."))
log_warning("Unknown kernel switch %s. Ignoring.", key);
return 0;
}
static int add_root_mount(void) {
#ifdef ENABLE_EFI
int r;
if (!is_efi_boot()) {
log_debug("Not a EFI boot, not creating root mount.");
return 0;
}
r = efi_loader_get_device_part_uuid(NULL);
if (r == -ENOENT) {
log_debug("EFI loader partition unknown, exiting.");
return 0;
} else if (r < 0) {
log_error("Failed to read ESP partition UUID: %s", strerror(-r));
return r;
}
/* OK, we have an ESP partition, this is fantastic, so let's
* wait for a root device to show up. A udev rule will create
* the link for us under the right name. */
return add_mount(
"root",
"/dev/gpt-auto-root",
in_initrd() ? "/sysroot" : "/",
NULL,
arg_root_rw ? "rw" : "ro",
"Root Partition",
in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
#else
return 0;
#endif
}
static int add_mounts(void) {
dev_t devno;
int r;
r = get_block_device("/", &devno);
if (r < 0) {
log_error("Failed to determine block device of root file system: %s", strerror(-r));
return r;
} else if (r == 0) {
log_debug("Root file system not on a (single) block device.");
return 0;
}
return enumerate_partitions(devno);
}
int main(int argc, char *argv[]) {
int r = 0;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
return EXIT_FAILURE;
}
if (argc > 1)
arg_dest = argv[3];
log_set_target(LOG_TARGET_SAFE);
log_parse_environment();
log_open();
umask(0022);
if (detect_container(NULL) > 0) {
log_debug("In a container, exiting.");
return EXIT_SUCCESS;
}
if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
return EXIT_FAILURE;
if (!arg_enabled) {
log_debug("Disabled, exiting.");
return EXIT_SUCCESS;
}
if (arg_root_enabled)
r = add_root_mount();
if (!in_initrd()) {
int k;
k = add_mounts();
if (k < 0)
r = k;
}
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}