gpt-auto-generator.c revision 1a14a53cfded6e78c6e8dfb73fdff0039971d642
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering This file is part of systemd.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Copyright 2013 Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is free software; you can redistribute it and/or modify it
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering under the terms of the GNU Lesser General Public License as published by
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering (at your option) any later version.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is distributed in the hope that it will be useful, but
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Lesser General Public License for more details.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering You should have received a copy of the GNU Lesser General Public License
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering * - Properly handle cryptsetup partitions
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering * - Define new partition type for encrypted swap
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int verify_gpt_partition(dev_t dev, sd_id128_t *type, unsigned *nr, char **fstype) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const char *v;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = asprintf(&t, "/dev/block/%u:%u", major(dev), minor(dev));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r == -2) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else if (r == 1) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else if (r != 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int add_swap(const char *path, const char *fstype) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("Adding swap: %s %s", path, fstype);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering name = unit_name_from_path(path, ".swap");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unit = strjoin(arg_dest, "/", name, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "DefaultDependencies=no\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int add_home(const char *path, const char *fstype) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("Adding home: %s %s", path, fstype);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unit = strappend(arg_dest, "/home.mount");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "DefaultDependencies=no\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "After=" SPECIAL_LOCAL_FS_PRE_TARGET "\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Where=/home\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "FsckPassNo=2\n",
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to write unit file %s: %m", unit);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/home.mount", NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create symlink %s: %m", lnk);
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int enumerate_partitions(dev_t dev) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering struct udev_device *parent = NULL, *d = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *home = NULL, *home_fstype = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', dev);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to enumerate partitions: %s", strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = udev_enumerate_get_list_entry(e);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (udev_device_get_devnum(q) == udev_device_get_devnum(d))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (udev_device_get_devnum(q) == udev_device_get_devnum(parent))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = verify_gpt_partition(udev_device_get_devnum(q), &type_id, &nr, &fstype);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to verify GPT partition: %s", strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart 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)))
875c2e220e2611165e09051c4747971811f1de58Lennart 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))) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int get_btrfs_block_device(const char *path, dev_t *dev) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* We won't do this for btrfs RAID */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (F_TYPE_CMP(sfs.f_type, BTRFS_SUPER_MAGIC))
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return get_btrfs_block_device(path, dev);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_error("This program takes three or no arguments.");
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_error("Failed to determine block device of root file system: %s", strerror(-r));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_debug("Root file system not on a (single) block device.");
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_debug("Root device %u:%u.", major(dev), minor(dev));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering r = verify_gpt_partition(dev, NULL, NULL, NULL);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_error("Failed to verify GPT partition: %s", strerror(-r));