gpt-auto-generator.c revision 9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64c
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2013 Lennart Poettering
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 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 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 * - Properly handle cryptsetup partitions
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * - Define new partition type for encrypted swap
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * - Make /home automount rather than mount
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic inline void blkid_free_probep(blkid_probe *b) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_blkid_freep_probe_ blkid_probe b = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen const char *v;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen else if (r == 1)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen else if (r != 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* return 0 if we're not on GPT */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
987d561fe202568c0a2880cf047c7833fd365c7aLennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int add_swap(const char *path, const char *fstype) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Adding swap: %s %s", path, fstype);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to create unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "DefaultDependencies=no\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to write unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to create symlink %s: %m", lnk);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int add_home(const char *path, const char *fstype) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *unit = NULL, *lnk = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Adding home: %s %s", path, fstype);
b686acb27ea4de042320fa196cfb14e08f30165bTom Gundersen log_error("Failed to create unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "DefaultDependencies=no\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Where=/home\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "FsckPassNo=2\n",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to write unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/home.mount", NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to create symlink %s: %m", lnk);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int enumerate_partitions(struct udev *udev, dev_t dev) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *home = NULL, *home_fstype = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen d = udev_device_new_from_devnum(udev, 'b', dev);
b686acb27ea4de042320fa196cfb14e08f30165bTom Gundersen r = udev_enumerate_add_match_parent(e, parent);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = udev_enumerate_add_match_subsystem(e, "block");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (udev_device_get_devnum(q) == udev_device_get_devnum(d))
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (udev_device_get_devnum(q) == udev_device_get_devnum(parent))
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = verify_gpt_partition(node, &type_id, &nr, &fstype);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to verify GPT partition %s: %s",
goto skip;
if (!home) {
r = log_oom();
goto finish;
skip:
if (fd < 0)
return -errno;
return -errno;
return -errno;
return -errno;
return -ENODEV;
return -ENODEV;
return -ENODEV;
return -errno;
return -errno;
r = log_oom();
goto finish;
t = udev_device_get_devnode(d);
r = -ENODEV;
goto finish;
n = strdup(t);
r = -ENOMEM;
goto finish;
*ret = n;
r = -EINVAL;
goto finish;
log_open();
if (in_initrd()) {
goto finish;
goto finish;
goto finish;
goto finish;
if (!udev) {
r = log_oom();
goto finish;
goto finish;
goto finish;
goto finish;
if (udev)