gpt-auto-generator.c revision 73b80ec2d999c45ce13f3e034704249d80829f7e
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/***
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering This file is part of systemd.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Copyright 2013 Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering (at your option) any later version.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is distributed in the hope that it will be useful, but
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Lesser General Public License for more details.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering***/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <unistd.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <stdlib.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <fcntl.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <sys/ioctl.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <sys/statfs.h>
96115cdfe0241ae9b4e7177cd3874c0a93d00b39Thomas Hindoe Paaboel Andersen#include <blkid/blkid.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau#ifdef HAVE_LINUX_BTRFS_H
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau#include <linux/btrfs.h>
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau#endif
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include "sd-id128.h"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include "libudev.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "path-util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "mkdir.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "missing.h"
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include "udev-util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "special.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "unit-name.h"
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek#include "virt.h"
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering#include "generator.h"
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering#include "gpt.h"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include "fileio.h"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#include "efivars.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic const char *arg_dest = "/tmp";
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic bool arg_enabled = true;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic bool arg_root_enabled = true;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic bool arg_root_rw = false;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
14bf2c9d375db6a4670bc0ef0e521e35a939a498Lennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek#define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek
3db604b907323b8df0fc810216f6112056d26a02Lennart Poetteringstatic int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) {
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek _cleanup_blkid_freep_probe_ blkid_probe b = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering const char *v;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering b = blkid_new_probe_from_filename(node);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (!b)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno != 0 ? -errno : -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_enable_superblocks(b, 1);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_enable_partitions(b, 1);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_do_safeprobe(b);
b94801803417c23d099cb7e508754181ecd27f9cZbigniew Jędrzejewski-Szmek if (r == -2 || r == 1) /* no result or uncertain */
b94801803417c23d099cb7e508754181ecd27f9cZbigniew Jędrzejewski-Szmek return -EBADSLT;
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek else if (r != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r != 0)
091526ab20485492124852dcf629787f35816df8Zbigniew Jędrzejewski-Szmek /* return 0 if we're not on GPT */
091526ab20485492124852dcf629787f35816df8Zbigniew Jędrzejewski-Szmek return errno ? -errno : 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (strcmp(v, "gpt") != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (type) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = sd_id128_from_string(v, type);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (nr) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = safe_atou(v, nr);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fstype) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r != 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering else {
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek char *fst;
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fst = strdup(v);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (!fst)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *fstype = fst;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int add_swap(const char *path, const char *fstype) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_debug("Adding swap: %s %s", path, fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering name = unit_name_from_path(path, ".swap");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!name)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering unit = strjoin(arg_dest, "/", name, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!unit)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering f = fopen(unit, "wxe");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!f) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fprintf(f,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1ebab691c7749779072741f71865bd0e055b7ecfLennart Poettering "[Unit]\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Description=Swap Partition\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
ee530d8b73246f29781bd54a707ca75c7ef5a6cbLennart Poettering "[Swap]\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "What=%s\n",
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fflush(f);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ferror(f)) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!lnk)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering mkdir_parents_label(lnk, 0755);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (symlink(unit, lnk) < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic int add_cryptsetup(const char *id, const char *what, char **device) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering char *from, *ret;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering int r;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(id);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(what);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(device);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering d = unit_name_from_path(what, ".device");
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!d)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering e = unit_name_escape(id);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!e)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering n = unit_name_build("systemd-cryptsetup", e, ".service");
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!n)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering p = strjoin(arg_dest, "/", n, NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!n)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering f = fopen(p, "wxe");
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!f) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to create unit file %s: %m", p);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering fprintf(f,
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "[Unit]\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Description=Cryptography Setup for %%I\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "DefaultDependencies=no\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Conflicts=umount.target\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "BindsTo=dev-mapper-%%i.device %s\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Before=umount.target cryptsetup.target\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "After=%s\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "IgnoreOnIsolate=true\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "After=systemd-readahead-collect.service systemd-readahead-replay.service\n\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "[Service]\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Type=oneshot\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "RemainAfterExit=yes\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s'\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering d, d,
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering id, what,
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering id);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering fflush(f);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (ferror(f)) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to write file %s: %m", p);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering from = strappenda("../", n);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!to)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering mkdir_parents_label(to, 0755);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (symlink(from, to) < 0) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to create symlink %s: %m", to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering free(to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!to)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering mkdir_parents_label(to, 0755);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (symlink(from, to) < 0) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to create symlink %s: %m", to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering free(to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!to)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering mkdir_parents_label(to, 0755);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (symlink(from, to) < 0) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to create symlink %s: %m", to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering free(p);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!p)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering mkdir_parents_label(p, 0755);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering r = write_string_file(p,
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "[Unit]\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (r < 0) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to write device drop-in: %s", strerror(-r));
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return r;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering ret = strappend("/dev/mapper/", id);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!ret)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering *device = ret;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return 0;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering}
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int add_mount(
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *id,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *what,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *where,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *fstype,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *options,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *description,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *post) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(id);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(what);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(where);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(description);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
6d26dfe11c853d612b84abe858520bbcb62c2e96Lennart Poettering if (path_is_mount_point(where, true) <= 0 &&
6d26dfe11c853d612b84abe858520bbcb62c2e96Lennart Poettering dir_is_empty(where) <= 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_debug("%s already populated, ignoring.", where);
4b1b14a6a6acb1640596d5e9542829d32989d385Lennart Poettering return 0;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
4b1b14a6a6acb1640596d5e9542829d32989d385Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("Adding %s: %s %s", where, what, strna(fstype));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (streq_ptr(fstype, "crypto_LUKS")) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering r = add_cryptsetup(id, what, &crypto_what);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (r < 0)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return r;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering what = crypto_what;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering fstype = NULL;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering unit = unit_name_from_path(where, ".mount");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!unit)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering p = strjoin(arg_dest, "/", unit, NULL);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (!p)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return log_oom();
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering f = fopen(p, "wxe");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!f) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fprintf(f,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "[Unit]\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Description=%s\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n",
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering description);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (post)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering fprintf(f, "Before=%s\n", post);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (r < 0)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return r;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering fprintf(f,
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering "\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "[Mount]\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "What=%s\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Where=%s\n",
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering what, where);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (fstype)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering fprintf(f, "Type=%s\n", fstype);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (options)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering fprintf(f, "Options=%s\n", options);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fflush(f);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ferror(f)) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_error("Failed to write unit file %s: %m", p);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (post) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!lnk)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering mkdir_parents_label(lnk, 0755);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (symlink(p, lnk) < 0) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_error("Failed to create symlink %s: %m", lnk);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return -errno;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poetteringstatic int enumerate_partitions(struct udev *udev, dev_t dev) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek _cleanup_udev_device_unref_ struct udev_device *d = NULL;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering _cleanup_free_ char *home = NULL, *home_fstype = NULL, *srv = NULL, *srv_fstype = NULL;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering unsigned home_nr = (unsigned) -1, srv_nr = (unsigned )-1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_list_entry *first, *item;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering struct udev_device *parent = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r, k;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering e = udev_enumerate_new(udev);
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek if (!e)
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', dev);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (!d)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering parent = udev_device_get_parent(d);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (!parent)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (r < 0)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (r < 0)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_scan_devices(e);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s", major(dev), minor(dev), strerror(-r));
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering first = udev_enumerate_get_list_entry(e);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_list_entry_foreach(item, first) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *q;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering const char *node = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering sd_id128_t type_id;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering unsigned nr;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (!q)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (udev_device_get_devnum(q) == udev_device_get_devnum(d))
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (udev_device_get_devnum(q) == udev_device_get_devnum(parent))
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering node = udev_device_get_devnode(q);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (!node)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering k = verify_gpt_partition(node, &type_id, &nr, &fstype);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k < 0) {
843f737ade9c73609a2280dd3dd16e18222a5dcbŁukasz Stelmach /* skip child devices which are not detected properly */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k == -EBADSLT)
843f737ade9c73609a2280dd3dd16e18222a5dcbŁukasz Stelmach continue;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_error("Failed to verify GPT partition %s: %s", node, strerror(-k));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = k;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k == 0)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (sd_id128_equal(type_id, GPT_SWAP)) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering k = add_swap(node, fstype);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = k;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } else if (sd_id128_equal(type_id, GPT_HOME)) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering /* We only care for the first /home partition */
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (home && nr >= home_nr)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering continue;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering home_nr = nr;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering free(home);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering home = strdup(node);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (!home)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return log_oom();
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering free(home_fstype);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering home_fstype = fstype;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering fstype = NULL;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering } else if (sd_id128_equal(type_id, GPT_SRV)) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering /* We only care for the first /srv partition */
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (srv && nr >= srv_nr)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering continue;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering srv_nr = nr;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering free(srv);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering srv = strdup(node);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (!srv)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return log_oom();
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering free(srv_fstype);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering srv_fstype = fstype;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (home && home_fstype) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering k = add_mount("home", home, "/home", home_fstype, NULL, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = k;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (srv && srv_fstype) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering k = add_mount("srv", srv, "/srv", srv_fstype, NULL, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = k;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int get_btrfs_block_device(const char *path, dev_t *dev) {
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek struct btrfs_ioctl_fs_info_args fsi = {};
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_close_ int fd = -1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering uint64_t id;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fd = open(path, O_DIRECTORY|O_CLOEXEC);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fd < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering /* We won't do this for btrfs RAID */
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fsi.num_devices != 1)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering for (id = 1; id <= fsi.max_id; id++) {
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek struct btrfs_ioctl_dev_info_args di = {
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek .devid = id,
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek };
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct stat st;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (errno == ENODEV)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (stat((char*) di.path, &st) < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!S_ISBLK(st.st_mode))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENODEV;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (major(st.st_rdev) == 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENODEV;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *dev = st.st_rdev;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENODEV;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct stat st;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct statfs sfs;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (lstat(path, &st))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (major(st.st_dev) != 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *dev = st.st_dev;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (statfs(path, &sfs) < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
c51cf05646a11c65daf65c1123c77efb068f4f7bZbigniew Jędrzejewski-Szmek if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return get_btrfs_block_device(path, dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poetteringstatic int devno_to_devnode(struct udev *udev, dev_t devno, char **ret) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek _cleanup_udev_device_unref_ struct udev_device *d;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering const char *t;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering char *n;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', devno);
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek if (!d)
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek return log_oom();
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering t = udev_device_get_devnode(d);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (!t)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return -ENODEV;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering n = strdup(t);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (!n)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return -ENOMEM;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering *ret = n;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return 0;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering}
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int parse_proc_cmdline_item(const char *key, const char *value) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering assert(key);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = parse_boolean(value);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (r < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_warning("Failed to parse gpt-auto switch %s. Ignoring.", value);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_enabled = r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } else if (streq(key, "root") && value) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering /* Disable root disk logic if there's a root= value
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * specified (unless it happens to be "gpt-auto") */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_root_enabled = streq(value, "gpt-auto");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } else if (streq(key, "rw") && !value)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_root_rw = true;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering else if (streq(key, "ro") && !value)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_root_rw = false;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering else if (startswith(key, "systemd.gpt-auto.") || startswith(key, "rd.systemd.gpt-auto."))
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_warning("Unknown kernel switch %s. Ignoring.", key);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering}
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int add_root_mount(void) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#ifdef ENABLE_EFI
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!is_efi_boot()) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("Not a EFI boot, not creating root mount.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek }
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = efi_loader_get_device_part_uuid(NULL);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (r == -ENOENT) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("EFI loader partition unknown, exiting.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } else if (r < 0) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_error("Failed to read ESP partition UUID: %s", strerror(-r));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return r;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering /* OK, we have an ESP partition, this is fantastic, so let's
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * wait for a root device to show up. A udev rule will create
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * the link for us under the right name. */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return add_mount(
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "root",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "/dev/disk/by-id/gpt-auto-root",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering in_initrd() ? "/sysroot" : "/",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering NULL,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_root_rw ? "rw" : "ro",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "Root Partition",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#else
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#endif
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering}
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int add_mounts(void) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering _cleanup_free_ char *node = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering dev_t devno;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering r = get_block_device("/", &devno);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to determine block device of root file system: %s", strerror(-r));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return r;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering } else if (r == 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_debug("Root file system not on a (single) block device.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering }
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering udev = udev_new();
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!udev)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return log_oom();
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering r = devno_to_devnode(udev, devno, &node);
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering if (r < 0) {
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering log_error("Failed to determine block device node from major/minor: %s", strerror(-r));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering log_debug("Root device %s.", node);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering r = verify_gpt_partition(node, NULL, NULL, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering log_error("Failed to verify GPT partition %s: %s", node, strerror(-r));
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return r;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (r == 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_debug("Not a GPT disk, exiting.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return enumerate_partitions(udev, devno);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering}
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringint main(int argc, char *argv[]) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r = 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (argc > 1 && argc != 4) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_error("This program takes three or no arguments.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return EXIT_FAILURE;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (argc > 1)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_dest = argv[3];
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_set_target(LOG_TARGET_SAFE);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_parse_environment();
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_open();
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering umask(0022);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (detect_container(NULL) > 0) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("In a container, exiting.");
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return EXIT_FAILURE;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!arg_enabled) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("Disabled, exiting.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return EXIT_SUCCESS;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (arg_root_enabled)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = add_root_mount();
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!in_initrd()) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int k;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering k = add_mounts();
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (k < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = k;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}