gpt-auto-generator.c revision c51cf05646a11c65daf65c1123c77efb068f4f7b
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/***
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering This file is part of systemd.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Copyright 2013 Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering (at your option) any later version.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is distributed in the hope that it will be useful, but
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Lesser General Public License for more details.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering***/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <unistd.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <stdlib.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <fcntl.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <sys/ioctl.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <sys/statfs.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <blkid.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau#ifdef HAVE_LINUX_BTRFS_H
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau#include <linux/btrfs.h>
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau#endif
4b357e15876b730343db08719c877fdb45b6ad42Michael Marineau
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "path-util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "mkdir.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "missing.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "sd-id128.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "libudev.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "special.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "unit-name.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/* TODO:
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering * - Properly handle cryptsetup partitions
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering * - Define new partition type for encrypted swap
4b1b14a6a6acb1640596d5e9542829d32989d385Lennart Poettering * - Make /home automount rather than mount
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering */
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic const char *arg_dest = "/tmp";
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmekstatic inline void blkid_free_probep(blkid_probe *b) {
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (*b)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek blkid_free_probe(*b);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek}
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek#define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char **fstype) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *t = NULL;
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek _cleanup_blkid_freep_probe_ blkid_probe b = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering const char *v;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = asprintf(&t, "/dev/block/%u:%u", major(dev), minor(dev));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering b = blkid_new_probe_from_filename(t);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (!b)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno != 0 ? -errno : -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_enable_superblocks(b, 1);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_enable_partitions(b, 1);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_do_safeprobe(b);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r == -2)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return -ENODEV;
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek else if (r == 1)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return -ENODEV;
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek else if (r != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r != 0)
091526ab20485492124852dcf629787f35816df8Zbigniew Jędrzejewski-Szmek /* return 0 if we're not on GPT */
091526ab20485492124852dcf629787f35816df8Zbigniew Jędrzejewski-Szmek return errno ? -errno : 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (strcmp(v, "gpt") != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (type) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = sd_id128_from_string(v, type);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (nr) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (r != 0)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = safe_atou(v, nr);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fstype) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering char *fst;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering errno = 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r != 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering else {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fst = strdup(v);
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek if (!fst)
7384146530ac083efbef62b9ef5bb82c56565cd4Zbigniew Jędrzejewski-Szmek return -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *fstype = fst;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int add_swap(const char *path, const char *fstype) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_debug("Adding swap: %s %s", path, fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering name = unit_name_from_path(path, ".swap");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!name)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering unit = strjoin(arg_dest, "/", name, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!unit)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering f = fopen(unit, "wxe");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!f) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fprintf(f,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "[Unit]\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "DefaultDependencies=no\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n"
ee530d8b73246f29781bd54a707ca75c7ef5a6cbLennart Poettering "[Swap]\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "What=%s\n",
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fflush(f);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ferror(f)) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!lnk)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering mkdir_parents_label(lnk, 0755);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (symlink(unit, lnk) < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int add_home(const char *path, const char *fstype) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
4b1b14a6a6acb1640596d5e9542829d32989d385Lennart Poettering if (dir_is_empty("/home") <= 0)
4b1b14a6a6acb1640596d5e9542829d32989d385Lennart Poettering return 0;
4b1b14a6a6acb1640596d5e9542829d32989d385Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_debug("Adding home: %s %s", path, fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering unit = strappend(arg_dest, "/home.mount");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!unit)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering f = fopen(unit, "wxe");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!f) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fprintf(f,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "[Unit]\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "DefaultDependencies=no\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "After=" SPECIAL_LOCAL_FS_PRE_TARGET "\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "[Mount]\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "What=%s\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "Where=/home\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "Type=%s\n"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "FsckPassNo=2\n",
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering path, fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fflush(f);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ferror(f)) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/home.mount", NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!lnk)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering mkdir_parents_label(lnk, 0755);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (symlink(unit, lnk) < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int enumerate_partitions(dev_t dev) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev *udev;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_enumerate *e = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_device *parent = NULL, *d = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_list_entry *first, *item;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering unsigned home_nr = (unsigned) -1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *home = NULL, *home_fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev = udev_new();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!udev)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering e = udev_enumerate_new(udev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!e) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!d) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering parent = udev_device_get_parent(d);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!parent) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_scan_devices(e);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s",
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek major(dev), minor(dev), strerror(-r));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering first = udev_enumerate_get_list_entry(e);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_list_entry_foreach(item, first) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_free_ char *fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering const char *node = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_device *q;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering sd_id128_t type_id;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering unsigned nr;
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek dev_t sub;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!q) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (udev_device_get_devnum(q) == udev_device_get_devnum(d))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto skip;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (udev_device_get_devnum(q) == udev_device_get_devnum(parent))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto skip;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering node = udev_device_get_devnode(q);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!node) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek sub = udev_device_get_devnum(q);
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek r = verify_gpt_partition(sub, &type_id, &nr, &fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek log_error("Failed to verify GPT partition /dev/block/%u:%u: %s",
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek major(sub), minor(sub), strerror(-r));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_device_unref(q);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r == 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto skip;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (sd_id128_equal(type_id, SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering add_swap(node, fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering else if (sd_id128_equal(type_id, SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15))) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!home || nr < home_nr) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering free(home);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering home = strdup(node);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!home) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = log_oom();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering home_nr = nr;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering free(home_fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering home_fstype = fstype;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fstype = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering skip:
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_device_unref(q);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (home && home_fstype)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering add_home(home, home_fstype);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringfinish:
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (d)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_device_unref(d);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (e)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_enumerate_unref(e);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (udev)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering udev_unref(udev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int get_btrfs_block_device(const char *path, dev_t *dev) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct btrfs_ioctl_fs_info_args fsi;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering _cleanup_close_ int fd = -1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering uint64_t id;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering fd = open(path, O_DIRECTORY|O_CLOEXEC);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fd < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering zero(fsi);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering /* We won't do this for btrfs RAID */
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fsi.num_devices != 1)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering for (id = 1; id <= fsi.max_id; id++) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct btrfs_ioctl_dev_info_args di;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct stat st;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering zero(di);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering di.devid = id;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (errno == ENODEV)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering continue;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (stat((char*) di.path, &st) < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!S_ISBLK(st.st_mode))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENODEV;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (major(st.st_rdev) == 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENODEV;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *dev = st.st_rdev;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENODEV;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct stat st;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct statfs sfs;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(path);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (lstat("/", &st))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (major(st.st_dev) != 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *dev = st.st_dev;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 1;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (statfs("/", &sfs) < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -errno;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
c51cf05646a11c65daf65c1123c77efb068f4f7bZbigniew Jędrzejewski-Szmek if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return get_btrfs_block_device(path, dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringint main(int argc, char *argv[]) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering dev_t dev;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (argc > 1 && argc != 4) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("This program takes three or no arguments.");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return EXIT_FAILURE;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (argc > 1)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering arg_dest = argv[3];
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_set_target(LOG_TARGET_SAFE);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_parse_environment();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_open();
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering umask(0022);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (in_initrd())
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = get_block_device("/", &dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_error("Failed to determine block device of root file system: %s", strerror(-r));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return EXIT_FAILURE;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r == 0) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering log_debug("Root file system not on a (single) block device.");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek log_debug("Root device /dev/block/%u:%u.", major(dev), minor(dev));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = verify_gpt_partition(dev, NULL, NULL, NULL);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r < 0) {
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek log_error("Failed to verify GPT partition /dev/block/%u:%u: %s",
d98cc1c019651b895464161072894a02cc43daabZbigniew Jędrzejewski-Szmek major(dev), minor(dev), strerror(-r));
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return EXIT_FAILURE;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (r == 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = enumerate_partitions(dev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}