gpt-auto-generator.c revision 8086ffacdb1bfec5ec115d24626538bda6cc372e
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>
96115cdfe0241ae9b4e7177cd3874c0a93d00b39Thomas Hindoe Paaboel Andersen#include <sys/ioctl.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <sys/statfs.h>
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include <blkid/blkid.h>
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#ifdef HAVE_LINUX_BTRFS_H
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <linux/btrfs.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#endif
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include "sd-id128.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "libudev.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "path-util.h"
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek#include "util.h"
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering#include "mkdir.h"
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering#include "missing.h"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include "udev-util.h"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#include "special.h"
1b9e5b126359a2a2ec37de1f94f046093abc74b8Lennart Poettering#include "unit-name.h"
f9ac15442e4132f00eca5495d53c17062aae13e0Lennart Poettering#include "virt.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "generator.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "gpt.h"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#include "fileio.h"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#include "efivars.h"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering#include "blkid-util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poetteringstatic const char *arg_dest = "/tmp";
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic bool arg_enabled = true;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic bool arg_root_enabled = true;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic bool arg_root_rw = false;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poetteringstatic int add_swap(const char *path) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering assert(path);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering log_debug("Adding swap: %s", path);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering name = unit_name_from_path(path, ".swap");
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!name)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering unit = strjoin(arg_dest, "/", name, NULL);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering if (!unit)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return log_oom();
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering f = fopen(unit, "wxe");
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!f) {
821b2e792159e237a1e5a1ea4bb6ae2e55d64be5Lukas Nykryn log_error("Failed to create unit file %s: %m", unit);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt fprintf(f,
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt "# Automatically generated by systemd-gpt-auto-generator\n\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "[Unit]\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Description=Swap Partition\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "[Swap]\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "What=%s\n",
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering path);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering fflush(f);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (ferror(f)) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (!lnk)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering mkdir_parents_label(lnk, 0755);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering if (symlink(unit, lnk) < 0) {
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return -errno;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering }
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return 0;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering}
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poetteringstatic int add_cryptsetup(const char *id, const char *what, bool rw, 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);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert(what);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt 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)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_oom();
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
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 (!p)
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return log_oom();
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt 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"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mack "DefaultDependencies=no\n"
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mack "Conflicts=umount.target\n"
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt "BindsTo=dev-mapper-%%i.device %s\n"
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt "Before=umount.target cryptsetup.target\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "After=%s\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "IgnoreOnIsolate=true\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' '' '%s'\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering d, d,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering id, what, rw ? "" : "read-only",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering id);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering fflush(f);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (ferror(f)) {
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering log_error("Failed to write file %s: %m", p);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering from = strappenda("../", n);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (!to)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart 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;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering free(to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
cca1dfddd4ce4357113663532696488427cc54e4Lennart 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 }
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering free(to);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!to)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return log_oom();
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering mkdir_parents_label(to, 0755);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (symlink(from, to) < 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_error("Failed to create symlink %s: %m", to);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return -errno;
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering free(p);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!p)
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering return log_oom();
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering mkdir_parents_label(p, 0755);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering r = write_string_file(p,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "[Unit]\n"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (r < 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_error("Failed to write device drop-in: %s", strerror(-r));
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return r;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering ret = strappend("/dev/mapper/", id);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!ret)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering *device = ret;
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering return 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering}
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int add_mount(
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *id,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *what,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *where,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *fstype,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering bool rw,
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering const char *description,
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering const char *post) {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering _cleanup_fclose_ FILE *f = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering assert(id);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(what);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering assert(where);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert(description);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_debug("Adding %s: %s %s", where, what, strna(fstype));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (streq_ptr(fstype, "crypto_LUKS")) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = add_cryptsetup(id, what, rw, &crypto_what);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return r;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers what = crypto_what;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers fstype = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers unit = unit_name_from_path(where, ".mount");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!unit)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers p = strjoin(arg_dest, "/", unit, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!p)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers f = fopen(p, "wxe");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!f) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to create unit file %s: %m", unit);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers fprintf(f,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "[Unit]\n"
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "Description=%s\n"
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n",
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering description);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (post)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fprintf(f, "Before=%s\n", post);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (r < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return r;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fprintf(f,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "\n"
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "[Mount]\n"
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering "What=%s\n"
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "Where=%s\n",
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering what, where);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (fstype)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fprintf(f, "Type=%s\n", fstype);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fprintf(f, "Options=%s\n", rw ? "rw" : "ro");
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fflush(f);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (ferror(f)) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering log_error("Failed to write unit file %s: %m", p);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (post) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!lnk)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return log_oom();
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering mkdir_parents_label(lnk, 0755);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (symlink(p, lnk) < 0) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek }
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return 0;
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek}
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic int probe_and_add_mount(
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *id,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *what,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *where,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering bool rw,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *description,
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering const char *post) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *fstype;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering int r;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(id);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(what);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(where);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(description);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (path_is_mount_point(where, true) <= 0 &&
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dir_is_empty(where) <= 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("%s already populated, ignoring.", where);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* Let's check the partition type here, so that we know
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers * whether to do LUKS magic. */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers errno = 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers b = blkid_new_probe_from_filename(what);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!b) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (errno == 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to allocate prober: %m");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers blkid_probe_enable_superblocks(b, 1);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers errno = 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = blkid_do_safeprobe(b);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r == -2 || r == 1) /* no result or uncertain */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering else if (r != 0) {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering if (errno == 0)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering errno = EIO;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to probe %s: %m", what);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return add_mount(
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers id,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers what,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers where,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers fstype,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers rw,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers description,
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen post);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen}
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersenstatic int enumerate_partitions(dev_t devnum) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen _cleanup_udev_device_unref_ struct udev_device *d = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen _cleanup_blkid_free_probe_ blkid_probe b = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen _cleanup_udev_unref_ struct udev *udev = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen _cleanup_free_ char *home = NULL, *srv = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen struct udev_list_entry *first, *item;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen struct udev_device *parent = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen const char *node, *pttype, *devtype;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen int home_nr = -1, srv_nr = -1;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen bool home_rw = true, srv_rw = true;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen blkid_partlist pl;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen int r, k;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen dev_t pn;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen udev = udev_new();
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!udev)
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_oom();
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen d = udev_device_new_from_devnum(udev, 'b', devnum);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!d)
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_oom();
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen parent = udev_device_get_parent(d);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!parent) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen log_debug("Not a partitioned device, ignoring.");
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen }
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen /* Does it have a devtype? */
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen devtype = udev_device_get_devtype(parent);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!devtype) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen log_debug("Parent doesn't have a device type, ignoring.");
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen }
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen /* Is this a disk or a partition? We only care for disks... */
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!streq(devtype, "disk")) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen log_debug("Parent isn't a raw disk, ignoring.");
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen }
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen /* Does it have a device node? */
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen node = udev_device_get_devnode(parent);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!node) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen log_debug("Parent device does not have device node, ignoring.");
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen }
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen log_debug("Root device %s.", node);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen pn = udev_device_get_devnum(parent);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (major(pn) == 0)
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen errno = 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen b = blkid_new_probe_from_filename(node);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (!b) {
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (errno == 0)
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_oom();
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen log_error("Failed allocate prober: %m");
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return -errno;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen }
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen blkid_probe_enable_partitions(b, 1);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen errno = 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen r = blkid_do_safeprobe(b);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (r == -2 || r == 1) /* no result or uncertain */
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return 0;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen else if (r != 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (errno == 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers errno = EIO;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to probe %s: %m", node);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers errno = 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r != 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (errno == 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers errno = EIO;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to determine partition table type of %s: %m", node);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* We only do this all for GPT... */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!streq_ptr(pttype, "gpt")) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("Not a GPT partition table, ignoring.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers errno = 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers pl = blkid_probe_get_partitions(b);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!pl) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (errno == 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to list partitions of %s: %m", node);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -errno;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers e = udev_enumerate_new(udev);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!e)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = udev_enumerate_add_match_parent(e, parent);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = udev_enumerate_add_match_subsystem(e, "block");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_oom();
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = udev_enumerate_scan_devices(e);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error("Failed to enumerate partitions on %s: %s", node, strerror(-r));
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return r;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers first = udev_enumerate_get_list_entry(e);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers udev_list_entry_foreach(item, first) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers _cleanup_udev_device_unref_ struct udev_device *q;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *stype, *subnode;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers sd_id128_t type_id;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers blkid_partition pp;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dev_t qn;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers int nr;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers unsigned long long flags;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!q)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers qn = udev_device_get_devnum(q);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (major(qn) == 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (qn == devnum)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (qn == pn)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers subnode = udev_device_get_devnode(q);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!subnode)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers pp = blkid_partlist_devno_to_partition(pl, qn);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!pp)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers flags = blkid_partition_get_flags(pp);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* Ignore partitions that are not marked for automatic
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers * mounting on discovery */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (flags & GPT_FLAG_NO_AUTO)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers nr = blkid_partition_get_partno(pp);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen if (nr < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers continue;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers stype = blkid_partition_get_type_string(pp);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!stype)
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen continue;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (sd_id128_from_string(stype, &type_id) < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering continue;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (sd_id128_equal(type_id, GPT_SWAP)) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (flags & GPT_FLAG_READ_ONLY) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("%s marked as read-only swap partition, which is bogus, ignoring.", subnode);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering continue;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers k = add_swap(subnode);
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering if (k < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = k;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering } else if (sd_id128_equal(type_id, GPT_HOME)) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* We only care for the first /home partition */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (home && nr >= home_nr)
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering home_nr = nr;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek home_rw = !(flags & GPT_FLAG_READ_ONLY),
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering free(home);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek home = strdup(subnode);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (!home)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return log_oom();
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek } else if (sd_id128_equal(type_id, GPT_SRV)) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek /* We only care for the first /srv partition */
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (srv && nr >= srv_nr)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering srv_nr = nr;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek srv_rw = !(flags & GPT_FLAG_READ_ONLY),
9c4495ca561624c2f0085507dd1288ed5f1247c5Tomasz Torcz
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering free(srv);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering srv = strdup(node);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!srv)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return log_oom();
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering }
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering if (home) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (k < 0)
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering r = k;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering if (srv) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (k < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = k;
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering }
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return r;
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering}
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmekstatic int get_btrfs_block_device(const char *path, dev_t *dev) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering struct btrfs_ioctl_fs_info_args fsi = {};
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering _cleanup_close_ int fd = -1;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering uint64_t id;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(path);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(dev);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fd = open(path, O_DIRECTORY|O_CLOEXEC);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (fd < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* We won't do this for btrfs RAID */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (fsi.num_devices != 1)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return 0;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering for (id = 1; id <= fsi.max_id; id++) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering struct btrfs_ioctl_dev_info_args di = {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering .devid = id,
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek };
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek struct stat st;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (errno == ENODEV)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek continue;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering if (stat((char*) di.path, &st) < 0)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering if (!S_ISBLK(st.st_mode))
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -ENODEV;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (major(st.st_rdev) == 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -ENODEV;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering *dev = st.st_rdev;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return 1;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -ENODEV;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering}
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering struct stat st;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct statfs sfs;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek assert(path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (lstat(path, &st))
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (major(st.st_dev) != 0) {
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt *dev = st.st_dev;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (statfs(path, &sfs) < 0)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return -errno;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return get_btrfs_block_device(path, dev);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmekstatic int parse_proc_cmdline_item(const char *key, const char *value) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(key);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = parse_boolean(value);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_warning("Failed to parse gpt-auto switch %s. Ignoring.", value);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering else
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering arg_enabled = r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering } else if (streq(key, "root") && value) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* Disable root disk logic if there's a root= value
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * specified (unless it happens to be "gpt-auto") */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering arg_root_enabled = streq(value, "gpt-auto");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering } else if (streq(key, "rw") && !value)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering arg_root_rw = true;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering else if (streq(key, "ro") && !value)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering arg_root_rw = false;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return 0;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering}
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic int add_root_mount(void) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#ifdef ENABLE_EFI
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers if (!is_efi_boot()) {
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers log_debug("Not a EFI boot, not creating root mount.");
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers return 0;
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers }
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = efi_loader_get_device_part_uuid(NULL);
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering if (r == -ENOENT) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("EFI loader partition unknown, exiting.");
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering return 0;
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering } else if (r < 0) {
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering log_error("Failed to read ESP partition UUID: %s", strerror(-r));
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering /* OK, we have an ESP partition, this is fantastic, so let's
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers * wait for a root device to show up. A udev rule will create
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers * the link for us under the right name. */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return add_mount(
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "root",
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "/dev/gpt-auto-root",
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers in_initrd() ? "/sysroot" : "/",
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers NULL,
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack arg_root_rw,
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack "Root Partition",
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers#else
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return 0;
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers#endif
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers}
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sieversstatic int add_mounts(void) {
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers dev_t devno;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering int r;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering r = get_block_device("/", &devno);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (r < 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_error("Failed to determine block device of root file system: %s", strerror(-r));
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return r;
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering } else if (r == 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_debug("Root file system not on a (single) block device.");
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack return 0;
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack }
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return enumerate_partitions(devno);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering}
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sieversint main(int argc, char *argv[]) {
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers int r = 0;
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers if (argc > 1 && argc != 4) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_error("This program takes three or no arguments.");
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering return EXIT_FAILURE;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (argc > 1)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering arg_dest = argv[3];
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering log_set_target(LOG_TARGET_SAFE);
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack log_parse_environment();
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack log_open();
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering umask(0022);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (detect_container(NULL) > 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("In a container, exiting.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return EXIT_SUCCESS;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = parse_proc_cmdline(parse_proc_cmdline_item);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!arg_enabled) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("Disabled, exiting.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return EXIT_SUCCESS;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering if (arg_root_enabled)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = add_root_mount();
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!in_initrd()) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int k;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering k = add_mounts();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (k < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = k;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering