1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering This file is part of systemd.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Copyright 2013 Lennart 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 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 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/>.
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poetteringstatic int add_cryptsetup(const char *id, const char *what, bool rw, char **device) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering r = unit_name_from_path(what, ".device", &d);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering r = unit_name_build("systemd-cryptsetup", e, ".service", &n);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to create unit file %s: %m", p);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Description=Cryptography Setup for %%I\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "DefaultDependencies=no\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Conflicts=umount.target\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "BindsTo=dev-mapper-%%i.device %s\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Before=umount.target cryptsetup.target\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "IgnoreOnIsolate=true\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "Type=oneshot\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "RemainAfterExit=yes\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return log_error_errno(r, "Failed to write file %s: %m", p);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to create symlink %s: %m", to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to create symlink %s: %m", to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to create symlink %s: %m", to);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mack "JobTimeoutSec=0\n",
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mack WRITE_STRING_FILE_CREATE); /* the binary handles timeouts anyway */
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to write device drop-in: %m");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *post) {
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("Adding %s: %s %s", where, what, strna(fstype));
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering r = add_cryptsetup(id, what, rw, &crypto_what);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering r = unit_name_from_path(where, ".mount", &unit);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return log_error_errno(r, "Failed to generate unit name: %m");
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering "# Automatically generated by systemd-gpt-auto-generator\n\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Description=%s\n"
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering "Documentation=man:systemd-gpt-auto-generator(8)\n",
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers fprintf(f, "Options=%s,%s\n", options, rw ? "rw" : "ro");
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return log_error_errno(r, "Failed to write unit file %s: %m", p);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* already a mountpoint; generators run during reload */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return false;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* the directory might not exist on a stateless system */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return false;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return true;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* not a mountpoint but it contains files */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return true;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return false;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *post) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering log_debug("%s already populated, ignoring.", where);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* Let's check the partition type here, so that we know
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering * whether to do LUKS magic. */
e1427b138fbf7b7f13bb61187635b882be3ca2b2Michal Schmidt return log_error_errno(errno, "Failed to allocate prober: %m");
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (r == -2 || r == 1) /* no result or uncertain */
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek else if (r != 0)
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek /* add_mount is OK with fstype being NULL. */
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_error_errno(r, "Failed to generate unit name: %m");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "# Automatically generated by systemd-gpt-auto-generator\n\n"
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "Description=Swap Partition\n"
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "What=%s\n",
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return log_error_errno(r, "Failed to write unit file %s: %m", unit);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen const char *id,
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen _cleanup_free_ char *unit = NULL, *lnk = NULL;
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen r = unit_name_from_path(where, ".automount", &unit);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_error_errno(r, "Failed to generate unit name: %m");
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen "# Automatically generated by systemd-gpt-auto-generator\n\n"
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen "Description=%s\n"
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen "Documentation=man:systemd-gpt-auto-generator(8)\n"
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen "[Automount]\n"
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen "TimeoutIdleSec=%lld\n",
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_error_errno(r, "Failed to write unit file %s: %m", p);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit, NULL);
7a1494aa4e4a131d73e866cf1e7eb7b6e47dbab8Tom Gundersen return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers _cleanup_blkid_free_probe_ blkid_probe b = NULL;
0b6b6787e3f0ae8906ce0212bd629edbe931b73dKay Sievers /* We create an .automount which is not overridden by the .mount from the fstab generator. */
0b6b6787e3f0ae8906ce0212bd629edbe931b73dKay Sievers log_debug("/boot specified in fstab, ignoring.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("/boot already populated, ignoring.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_error_errno(r, "Failed to read ESP partition UUID: %m");
e1427b138fbf7b7f13bb61187635b882be3ca2b2Michal Schmidt return log_error_errno(errno, "Failed to allocate prober: %m");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r == -2 || r == 1) /* no result or uncertain */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers else if (r != 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid, NULL);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r != 0) {
59e73c5b102402ea18aec1f4d69b4daad574e82bLennart Poettering log_debug_errno(errno, "Partition for /boot does not have a UUID, ignoring.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("Partition for /boot does not have a valid UUID, ignoring.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers log_debug("Partition for /boot does not appear to be the partition we are booted from.");
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "umask=0077",
158df4b6a63c0d4e4f8de5210581619e7b693fb4Marius Thesing "EFI System Partition Automount",
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic int enumerate_partitions(dev_t devnum) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek _cleanup_udev_device_unref_ struct udev_device *d = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering _cleanup_blkid_free_probe_ blkid_probe b = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers _cleanup_free_ char *boot = NULL, *home = NULL, *srv = NULL;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek const char *name, *node, *pttype, *devtype;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering d = udev_device_new_from_devnum(udev, 'b', devnum);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek name = udev_device_get_devnode(d);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek name = udev_device_get_syspath(d);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("Device %u:%u does not have a name, ignoring.",
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s: not a partitioned device, ignoring.", name);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* Does it have a devtype? */
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering devtype = udev_device_get_devtype(parent);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s: parent doesn't have a device type, ignoring.", name);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* Is this a disk or a partition? We only care for disks... */
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s: parent isn't a raw disk, ignoring.", name);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* Does it have a device node? */
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s: parent device does not have device node, ignoring.", name);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s: root device %s.", name, node);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "%s: failed to allocate prober: %m", node);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
458a2f85e8ae08c534bf8d030fbeeb791893422bTom Gundersen return 0; /* no results */
458a2f85e8ae08c534bf8d030fbeeb791893422bTom Gundersen else if (r == -2) {
cb9712492f94153b7ce6fc03d6dd3fd95c87baa5Lennart Poettering log_warning("%s: probe gave ambiguous results, ignoring.", node);
458a2f85e8ae08c534bf8d030fbeeb791893422bTom Gundersen } else if (r != 0)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
cb9712492f94153b7ce6fc03d6dd3fd95c87baa5Lennart Poettering return 0; /* No partition table found. */
cb9712492f94153b7ce6fc03d6dd3fd95c87baa5Lennart Poettering return log_error_errno(errno, "%s: failed to determine partition table type: %m", node);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering /* We only do this all for GPT... */
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s: not a GPT partition table, ignoring.", node);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "%s: failed to list partitions: %m", node);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_add_match_parent(e, parent);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = udev_enumerate_add_match_subsystem(e, "block");
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek return log_error_errno(r, "%s: failed to enumerate partitions: %m", node);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering first = udev_enumerate_get_list_entry(e);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *q;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering pp = blkid_partlist_devno_to_partition(pl, qn);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering stype = blkid_partition_get_type_string(pp);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (sd_id128_from_string(stype, &type_id) < 0)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* We only care for the first /boot partition */
dd2c31bb04776ed8a9e9117028e987762f56c027Lennart Poettering /* Note that we do not honour the "no-auto"
dd2c31bb04776ed8a9e9117028e987762f56c027Lennart Poettering * flag for the ESP, as it is often unset, to
dd2c31bb04776ed8a9e9117028e987762f56c027Lennart Poettering * hide it from Windows. */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } else if (sd_id128_equal(type_id, GPT_HOME)) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering /* We only care for the first /home partition */
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering } else if (sd_id128_equal(type_id, GPT_SRV)) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering /* We only care for the first /srv partition */
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int get_block_device(const char *path, dev_t *dev) {
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering /* Get's the block device directly backing a file system. If
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering * the block device is encrypted, returns the device mapper
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering * block device. */
c51cf05646a11c65daf65c1123c77efb068f4f7bZbigniew Jędrzejewski-Szmek if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
f9ac15442e4132f00eca5495d53c17062aae13e0Lennart Poettering return btrfs_get_block_device(path, dev);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poetteringstatic int get_block_device_harder(const char *path, dev_t *dev) {
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering _cleanup_free_ char *p = NULL, *t = NULL;
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering const char *q;
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering /* Gets the backing block device for a file system, and
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering * handles LUKS encrypted file systems, looking for its
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering * immediate parent, if there is one. */
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering FOREACH_DIRENT_ALL(de, d, return -errno) {
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering if (found) /* Don't try to support multiple backing block devices */
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering q = strjoina(p, "/", found->d_name, "/dev");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int parse_proc_cmdline_item(const char *key, const char *value) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } else if (streq(key, "root") && value) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering /* Disable root disk logic if there's a root= value
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * specified (unless it happens to be "gpt-auto") */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering arg_root_enabled = streq(value, "gpt-auto");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("Not a EFI boot, not creating root mount.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = efi_loader_get_device_part_uuid(NULL);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_debug("EFI loader partition unknown, exiting.");
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt } else if (r < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to read ESP partition UUID: %m");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering /* OK, we have an ESP partition, this is fantastic, so let's
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * wait for a root device to show up. A udev rule will create
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering * the link for us under the right name. */
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "Root Partition",
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering r = get_block_device_harder("/", &devno);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to determine block device of root file system: %m");
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt else if (r == 0) {
c6ba0c184d297a454baf387663668db77f79c1b5Lennart Poettering r = get_block_device_harder("/usr", &devno);
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger return log_error_errno(r, "Failed to determine block device of /usr file system: %m");
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger else if (r == 0) {
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger log_debug("Neither root nor /usr file system are on a (single) block device.");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_error("This program takes three or no arguments.");
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering r = parse_proc_cmdline(parse_proc_cmdline_item);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");