gpt-auto-generator.c revision 7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2013 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <unistd.h>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <stdlib.h>
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering#include <sys/statfs.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <blkid/blkid.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "sd-id128.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "libudev.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "path-util.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "util.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "mkdir.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "missing.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "udev-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "special.h"
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering#include "unit-name.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "virt.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "generator.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "gpt.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "fileio.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "efivars.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "blkid-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "btrfs-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic const char *arg_dest = "/tmp";
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_enabled = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_root_enabled = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_root_rw = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_cryptsetup(const char *id, const char *what, bool rw, char **device) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *from, *ret;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(device);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = unit_name_from_path(what, ".device", &d);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering e = unit_name_escape(id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e)
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = unit_name_build("systemd-cryptsetup", e, ".service", &n);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strjoin(arg_dest, "/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!p)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering f = fopen(p, "wxe");
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering if (!f)
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return log_error_errno(errno, "Failed to create unit file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Unit]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Description=Cryptography Setup for %%I\n"
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "DefaultDependencies=no\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Conflicts=umount.target\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "BindsTo=dev-mapper-%%i.device %s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Before=umount.target cryptsetup.target\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "After=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "IgnoreOnIsolate=true\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Service]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Type=oneshot\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "RemainAfterExit=yes\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering d, d,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering id, what, rw ? "" : "read-only",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = fflush_and_check(f);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering from = strjoina("../", n);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!to)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mkdir_parents_label(to, 0755);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (symlink(from, to) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!to)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mkdir_parents_label(to, 0755);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (symlink(from, to) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!to)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mkdir_parents_label(to, 0755);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (symlink(from, to) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!p)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mkdir_parents_label(p, 0755);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = write_string_file(p,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Unit]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "JobTimeoutSec=0\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WRITE_STRING_FILE_CREATE); /* the binary handles timeouts anyway */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write device drop-in: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ret = strappend("/dev/mapper/", id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!ret)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *device = ret;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_mount(
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *id,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *what,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *where,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *fstype,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool rw,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *options,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *description,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *post) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(where);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(description);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Adding %s: %s %s", where, what, strna(fstype));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (streq_ptr(fstype, "crypto_LUKS")) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = add_cryptsetup(id, what, rw, &crypto_what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering what = crypto_what;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fstype = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = unit_name_from_path(where, ".mount", &unit);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strjoin(arg_dest, "/", unit, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!p)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering f = fopen(p, "wxe");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!f)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Unit]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Description=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering description);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (post)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "Before=%s\n", post);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Mount]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "What=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Where=%s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering what, where);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (fstype)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "Type=%s\n", fstype);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (options)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "Options=%s,%s\n", options, rw ? "rw" : "ro");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "Options=%s\n", rw ? "rw" : "ro");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = fflush_and_check(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write unit file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (post) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!lnk)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mkdir_parents_label(lnk, 0755);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (symlink(p, lnk) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool path_is_busy(const char *where) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* already a mountpoint; generators run during reload */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* the directory might not exist on a stateless system */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* not a mountpoint but it contains files */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (dir_is_empty(where) <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int probe_and_add_mount(
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *id,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *what,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *where,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool rw,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *description,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *post) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *fstype = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(where);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(description);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (path_is_busy(where)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s already populated, ignoring.", where);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering /* Let's check the partition type here, so that we know
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * whether to do LUKS magic. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering errno = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering b = blkid_new_probe_from_filename(what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!b) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(errno, "Failed to allocate prober: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_enable_superblocks(b, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering errno = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = blkid_do_safeprobe(b);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r != 0)
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* add_mount is OK with fstype being NULL. */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return add_mount(
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen id,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen what,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering where,
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering fstype,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rw,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen NULL,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering description,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering post);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int add_swap(const char *path) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_fclose_ FILE *f = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Adding swap: %s", path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersen r = unit_name_from_path(path, ".swap", &name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek unit = strjoin(arg_dest, "/", name, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!unit)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_oom();
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen f = fopen(unit, "wxe");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!f)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen fprintf(f,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "[Unit]\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Description=Swap Partition\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "[Swap]\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "What=%s\n",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen path);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = fflush_and_check(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(r, "Failed to write unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!lnk)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_oom();
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mkdir_parents_label(lnk, 0755);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (symlink(unit, lnk) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#ifdef ENABLE_EFI
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_automount(
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *id,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *what,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *where,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *fstype,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen bool rw,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen const char *options,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen const char *description,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen usec_t timeout) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *unit = NULL, *lnk = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *opt, *p = NULL;
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek int r;
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek assert(id);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(where);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(description);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (options)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen opt = strjoin(options, ",noauto", NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen else
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering opt = strdup("noauto");
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering if (!opt)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_oom();
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = add_mount(id,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen what,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering where,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering fstype,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering rw,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering opt,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering description,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen NULL);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = unit_name_from_path(where, ".automount", &unit);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p = strjoin(arg_dest, "/", unit, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!p)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_oom();
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen f = fopen(p, "wxe");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!f)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen fprintf(f,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "[Unit]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Description=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Automount]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Where=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "TimeoutIdleSec=%lld\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering description,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering where,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (unsigned long long)timeout / USEC_PER_SEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = fflush_and_check(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write unit file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!lnk)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_oom();
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering mkdir_parents_label(lnk, 0755);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (symlink(p, lnk) < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringstatic int add_boot(const char *what) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering const char *fstype = NULL, *uuid = NULL;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering sd_id128_t id, type_id;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(what);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!is_efi_boot()) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Not an EFI boot, ignoring /boot.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (in_initrd()) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("In initrd, ignoring /boot.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (detect_container(NULL) > 0) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering log_debug("In a container, ignoring /boot.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (path_is_busy("/boot")) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("/boot already populated, ignoring.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = efi_loader_get_device_part_uuid(&id);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r == -ENOENT) {
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering log_debug("EFI loader partition unknown.");
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(r, "Failed to read ESP partition UUID: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering errno = 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering b = blkid_new_probe_from_filename(what);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!b) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (errno == 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_oom();
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_error_errno(errno, "Failed to allocate prober: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return -errno;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_enable_partitions(b, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering errno = 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = blkid_do_safeprobe(b);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering else if (r != 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!streq(fstype, "vfat")) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r != 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug_errno(r, "Partition for /boot does not have a UUID, ignoring. %m");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (sd_id128_from_string(uuid, &type_id) < 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Partition for /boot does not have a valid UUID, ignoring.");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!sd_id128_equal(type_id, id)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Partition for /boot does not appear to be the partition we are booted from.");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = add_automount("boot",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen what,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "/boot",
b686acb27ea4de042320fa196cfb14e08f30165bTom Gundersen "vfat",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "EFI System Partition Automount",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen false,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "umask=0077",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering 120 * USEC_PER_SEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#else
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int add_boot(const char *what) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
b686acb27ea4de042320fa196cfb14e08f30165bTom Gundersen}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#endif
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int enumerate_partitions(dev_t devnum) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_udev_device_unref_ struct udev_device *d = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_blkid_free_probe_ blkid_probe b = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_udev_unref_ struct udev *udev = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *boot = NULL, *home = NULL, *srv = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen struct udev_list_entry *first, *item;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen struct udev_device *parent = NULL;
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersen const char *name, *node, *pttype, *devtype;
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersen int boot_nr = -1, home_nr = -1, srv_nr = -1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool home_rw = true, srv_rw = true;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen blkid_partlist pl;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r, k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dev_t pn;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering udev = udev_new();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!udev)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', devnum);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!d)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen name = udev_device_get_devnode(d);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!name)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen name = udev_device_get_syspath(d);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Device %u:%u does not have a name, ignoring.",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering major(devnum), minor(devnum));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering parent = udev_device_get_parent(d);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!parent) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_debug("%s: not a partitioned device, ignoring.", name);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering /* Does it have a devtype? */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering devtype = udev_device_get_devtype(parent);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!devtype) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: parent doesn't have a device type, ignoring.", name);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Is this a disk or a partition? We only care for disks... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!streq(devtype, "disk")) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: parent isn't a raw disk, ignoring.", name);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Does it have a device node? */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering node = udev_device_get_devnode(parent);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!node) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: parent device does not have device node, ignoring.", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: root device %s.", name, node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pn = udev_device_get_devnum(parent);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (major(pn) == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering errno = 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering b = blkid_new_probe_from_filename(node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!b) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno == 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_oom();
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "%s: failed to allocate prober: %m", node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering blkid_probe_enable_partitions(b, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering errno = 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = blkid_do_safeprobe(b);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r == -2 || r == 1) /* no result or uncertain */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r != 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering errno = 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r != 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno ?: EIO,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "%s: failed to determine partition table type: %m", node);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering /* We only do this all for GPT... */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!streq_ptr(pttype, "gpt")) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_debug("%s: not a GPT partition table, ignoring.", node);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering errno = 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering pl = blkid_probe_get_partitions(b);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!pl) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno == 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_error_errno(errno, "%s: failed to list partitions: %m", node);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering e = udev_enumerate_new(udev);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_oom();
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_oom();
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = udev_enumerate_scan_devices(e);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_error_errno(r, "%s: failed to enumerate partitions: %m", node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering first = udev_enumerate_get_list_entry(e);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering udev_list_entry_foreach(item, first) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering _cleanup_udev_device_unref_ struct udev_device *q;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *stype, *subnode;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering sd_id128_t type_id;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_partition pp;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dev_t qn;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering int nr;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!q)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering continue;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering qn = udev_device_get_devnum(q);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (major(qn) == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (qn == devnum)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering continue;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (qn == pn)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering subnode = udev_device_get_devnode(q);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!subnode)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering continue;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering pp = blkid_partlist_devno_to_partition(pl, qn);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!pp)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering continue;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering nr = blkid_partition_get_partno(pp);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (nr < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering continue;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering stype = blkid_partition_get_type_string(pp);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!stype)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (sd_id128_from_string(stype, &type_id) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (sd_id128_equal(type_id, GPT_SWAP)) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering unsigned long long flags;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering flags = blkid_partition_get_flags(pp);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (flags & GPT_FLAG_NO_AUTO)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (flags & GPT_FLAG_READ_ONLY) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering continue;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k = add_swap(subnode);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k < 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = k;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else if (sd_id128_equal(type_id, GPT_ESP)) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* We only care for the first /boot partition */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (boot && nr >= boot_nr)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering boot_nr = nr;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = free_and_strdup(&boot, subnode);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_oom();
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (sd_id128_equal(type_id, GPT_HOME)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned long long flags;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering flags = blkid_partition_get_flags(pp);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (flags & GPT_FLAG_NO_AUTO)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* We only care for the first /home partition */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (home && nr >= home_nr)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering continue;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering home_nr = nr;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering home_rw = !(flags & GPT_FLAG_READ_ONLY),
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = free_and_strdup(&home, subnode);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else if (sd_id128_equal(type_id, GPT_SRV)) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering unsigned long long flags;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering flags = blkid_partition_get_flags(pp);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (flags & GPT_FLAG_NO_AUTO)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* We only care for the first /srv partition */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (srv && nr >= srv_nr)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen srv_nr = nr;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering srv_rw = !(flags & GPT_FLAG_READ_ONLY),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = free_and_strdup(&srv, subnode);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_oom();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (boot) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k = add_boot(boot);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (k < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = k;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (home) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (k < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = k;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (srv) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct stat st;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct statfs sfs;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(dev);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (lstat(path, &st))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (major(st.st_dev) != 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *dev = st.st_dev;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (statfs(path, &sfs) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return btrfs_get_block_device(path, dev);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringstatic int parse_proc_cmdline_item(const char *key, const char *value) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering int r;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = parse_boolean(value);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_enabled = r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "root") && value) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* Disable root disk logic if there's a root= value
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering * specified (unless it happens to be "gpt-auto") */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_root_enabled = streq(value, "gpt-auto");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "rw") && !value)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_root_rw = true;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen else if (streq(key, "ro") && !value)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_root_rw = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_root_mount(void) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#ifdef ENABLE_EFI
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!is_efi_boot()) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Not a EFI boot, not creating root mount.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = efi_loader_get_device_part_uuid(NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -ENOENT) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("EFI loader partition unknown, exiting.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to read ESP partition UUID: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* OK, we have an ESP partition, this is fantastic, so let's
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * wait for a root device to show up. A udev rule will create
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * the link for us under the right name. */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return add_mount(
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "root",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "/dev/gpt-auto-root",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering in_initrd() ? "/sysroot" : "/",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering NULL,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_root_rw,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering NULL,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "Root Partition",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering#else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#endif
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_mounts(void) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dev_t devno;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = get_block_device("/", &devno);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to determine block device of root file system: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r == 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = get_block_device("/usr", &devno);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to determine block device of /usr file system: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r == 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Neither root nor /usr file system are on a (single) block device.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return enumerate_partitions(devno);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint main(int argc, char *argv[]) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (argc > 1 && argc != 4) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("This program takes three or no arguments.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return EXIT_FAILURE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (argc > 1)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_dest = argv[3];
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_set_target(LOG_TARGET_SAFE);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_parse_environment();
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_open();
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering umask(0022);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (detect_container(NULL) > 0) {
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering log_debug("In a container, exiting.");
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return EXIT_SUCCESS;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = parse_proc_cmdline(parse_proc_cmdline_item);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!arg_enabled) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_debug("Disabled, exiting.");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return EXIT_SUCCESS;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (arg_root_enabled)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = add_root_mount();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!in_initrd()) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k = add_mounts();
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering