gpt-auto-generator.c revision 7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8
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/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_enabled = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_root_enabled = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_root_rw = false;
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 r = unit_name_from_path(what, ".device", &d);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = unit_name_build("systemd-cryptsetup", e, ".service", &n);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return log_error_errno(errno, "Failed to create unit file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\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 "IgnoreOnIsolate=true\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 return log_error_errno(r, "Failed to write file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", to);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "JobTimeoutSec=0\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WRITE_STRING_FILE_CREATE); /* the binary handles timeouts anyway */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write device drop-in: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *post) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Adding %s: %s %s", where, what, strna(fstype));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = add_cryptsetup(id, what, rw, &crypto_what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = unit_name_from_path(where, ".mount", &unit);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Description=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "Options=%s,%s\n", options, rw ? "rw" : "ro");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "Options=%s\n", rw ? "rw" : "ro");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write unit file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool path_is_busy(const char *where) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* already a mountpoint; generators run during reload */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* the directory might not exist on a stateless system */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* not a mountpoint but it contains files */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *post) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s already populated, ignoring.", where);
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering /* Let's check the partition type here, so that we know
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * whether to do LUKS magic. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(errno, "Failed to allocate prober: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r != 0)
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* add_mount is OK with fstype being NULL. */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersen r = unit_name_from_path(path, ".swap", &name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek unit = strjoin(arg_dest, "/", name, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Description=Swap Partition\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(r, "Failed to write unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_free_ char *unit = NULL, *lnk = NULL;
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = unit_name_from_path(where, ".automount", &unit);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Description=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "[Automount]\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "TimeoutIdleSec=%lld\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (unsigned long long)timeout / USEC_PER_SEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to write unit file %s: %m", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit, NULL);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Not an EFI boot, ignoring /boot.");
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering log_debug("In a container, ignoring /boot.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("/boot already populated, ignoring.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = efi_loader_get_device_part_uuid(&id);
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering log_debug("EFI loader partition unknown.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(r, "Failed to read ESP partition UUID: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_error_errno(errno, "Failed to allocate prober: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering else if (r != 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_debug_errno(r, "Partition for /boot does not have a UUID, ignoring. %m");
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.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Partition for /boot does not appear to be the partition we are booted from.");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "EFI System Partition Automount",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "umask=0077",
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int enumerate_partitions(dev_t devnum) {
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;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', devnum);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Device %u:%u does not have a name, ignoring.",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_debug("%s: not a partitioned device, ignoring.", name);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering /* Does it have a devtype? */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering devtype = udev_device_get_devtype(parent);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: parent doesn't have a device type, ignoring.", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Is this a disk or a partition? We only care for disks... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: parent isn't a raw disk, ignoring.", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Does it have a device node? */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: parent device does not have device node, ignoring.", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s: root device %s.", name, node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(errno, "%s: failed to allocate prober: %m", node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r == -2 || r == 1) /* no result or uncertain */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r != 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering "%s: failed to determine partition table type: %m", node);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering /* We only do this all for GPT... */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_debug("%s: not a GPT partition table, ignoring.", node);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_error_errno(errno, "%s: failed to list partitions: %m", node);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_error_errno(r, "%s: failed to enumerate partitions: %m", node);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering first = udev_enumerate_get_list_entry(e);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering _cleanup_udev_device_unref_ struct udev_device *q;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering pp = blkid_partlist_devno_to_partition(pl, qn);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering stype = blkid_partition_get_type_string(pp);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (sd_id128_from_string(stype, &type_id) < 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering unsigned long long flags;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else if (sd_id128_equal(type_id, GPT_ESP)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* We only care for the first /boot partition */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (sd_id128_equal(type_id, GPT_HOME)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned long long flags;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* We only care for the first /home partition */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else if (sd_id128_equal(type_id, GPT_SRV)) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering unsigned long long flags;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* We only care for the first /srv partition */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return btrfs_get_block_device(path, dev);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringstatic int parse_proc_cmdline_item(const char *key, const char *value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "root") && value) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering /* Disable root disk logic if there's a root= value
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering * specified (unless it happens to be "gpt-auto") */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_root_enabled = streq(value, "gpt-auto");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_root_mount(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Not a EFI boot, not creating root mount.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = efi_loader_get_device_part_uuid(NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("EFI loader partition unknown, exiting.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to read ESP partition UUID: %m");
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 "Root Partition",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int add_mounts(void) {
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 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 log_error("This program takes three or no arguments.");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = parse_proc_cmdline(parse_proc_cmdline_item);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");