1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/statfs.h>
25 #include <blkid/blkid.h>
30 #include "alloc-util.h"
31 #include "blkid-util.h"
32 #include "btrfs-util.h"
33 #include "dirent-util.h"
37 #include "fstab-util.h"
38 #include "generator.h"
42 #include "mount-util.h"
43 #include "parse-util.h"
44 #include "path-util.h"
45 #include "proc-cmdline.h"
47 #include "stat-util.h"
48 #include "string-util.h"
49 #include "udev-util.h"
50 #include "unit-name.h"
54 static const char *arg_dest
= "/tmp";
55 static bool arg_enabled
= true;
56 static bool arg_root_enabled
= true;
57 static bool arg_root_rw
= false;
59 static int add_cryptsetup(const char *id
, const char *what
, bool rw
, char **device
) {
60 _cleanup_free_
char *e
= NULL
, *n
= NULL
, *p
= NULL
, *d
= NULL
, *to
= NULL
;
61 _cleanup_fclose_
FILE *f
= NULL
;
69 r
= unit_name_from_path(what
, ".device", &d
);
71 return log_error_errno(r
, "Failed to generate unit name: %m");
73 e
= unit_name_escape(id
);
77 r
= unit_name_build("systemd-cryptsetup", e
, ".service", &n
);
79 return log_error_errno(r
, "Failed to generate unit name: %m");
81 p
= strjoin(arg_dest
, "/", n
, NULL
);
87 return log_error_errno(errno
, "Failed to create unit file %s: %m", p
);
90 "# Automatically generated by systemd-gpt-auto-generator\n\n"
92 "Description=Cryptography Setup for %%I\n"
93 "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
94 "DefaultDependencies=no\n"
95 "Conflicts=umount.target\n"
96 "BindsTo=dev-mapper-%%i.device %s\n"
97 "Before=umount.target cryptsetup.target\n"
99 "IgnoreOnIsolate=true\n"
102 "RemainAfterExit=yes\n"
103 "TimeoutSec=0\n" /* the binary handles timeouts anyway */
104 "ExecStart=" SYSTEMD_CRYPTSETUP_PATH
" attach '%s' '%s' '' '%s'\n"
105 "ExecStop=" SYSTEMD_CRYPTSETUP_PATH
" detach '%s'\n",
107 id
, what
, rw
? "" : "read-only",
110 r
= fflush_and_check(f
);
112 return log_error_errno(r
, "Failed to write file %s: %m", p
);
114 from
= strjoina("../", n
);
116 to
= strjoin(arg_dest
, "/", d
, ".wants/", n
, NULL
);
120 mkdir_parents_label(to
, 0755);
121 if (symlink(from
, to
) < 0)
122 return log_error_errno(errno
, "Failed to create symlink %s: %m", to
);
125 to
= strjoin(arg_dest
, "/cryptsetup.target.requires/", n
, NULL
);
129 mkdir_parents_label(to
, 0755);
130 if (symlink(from
, to
) < 0)
131 return log_error_errno(errno
, "Failed to create symlink %s: %m", to
);
134 to
= strjoin(arg_dest
, "/dev-mapper-", e
, ".device.requires/", n
, NULL
);
138 mkdir_parents_label(to
, 0755);
139 if (symlink(from
, to
) < 0)
140 return log_error_errno(errno
, "Failed to create symlink %s: %m", to
);
143 p
= strjoin(arg_dest
, "/dev-mapper-", e
, ".device.d/50-job-timeout-sec-0.conf", NULL
);
147 mkdir_parents_label(p
, 0755);
148 r
= write_string_file(p
,
149 "# Automatically generated by systemd-gpt-auto-generator\n\n"
152 WRITE_STRING_FILE_CREATE
); /* the binary handles timeouts anyway */
154 return log_error_errno(r
, "Failed to write device drop-in: %m");
156 ret
= strappend("/dev/mapper/", id
);
164 static int add_mount(
171 const char *description
,
174 _cleanup_free_
char *unit
= NULL
, *lnk
= NULL
, *crypto_what
= NULL
, *p
= NULL
;
175 _cleanup_fclose_
FILE *f
= NULL
;
183 log_debug("Adding %s: %s %s", where
, what
, strna(fstype
));
185 if (streq_ptr(fstype
, "crypto_LUKS")) {
187 r
= add_cryptsetup(id
, what
, rw
, &crypto_what
);
195 r
= unit_name_from_path(where
, ".mount", &unit
);
197 return log_error_errno(r
, "Failed to generate unit name: %m");
199 p
= strjoin(arg_dest
, "/", unit
, NULL
);
205 return log_error_errno(errno
, "Failed to create unit file %s: %m", unit
);
208 "# Automatically generated by systemd-gpt-auto-generator\n\n"
211 "Documentation=man:systemd-gpt-auto-generator(8)\n",
215 fprintf(f
, "Before=%s\n", post
);
217 r
= generator_write_fsck_deps(f
, arg_dest
, what
, where
, fstype
);
229 fprintf(f
, "Type=%s\n", fstype
);
232 fprintf(f
, "Options=%s,%s\n", options
, rw
? "rw" : "ro");
234 fprintf(f
, "Options=%s\n", rw
? "rw" : "ro");
236 r
= fflush_and_check(f
);
238 return log_error_errno(r
, "Failed to write unit file %s: %m", p
);
241 lnk
= strjoin(arg_dest
, "/", post
, ".requires/", unit
, NULL
);
245 mkdir_parents_label(lnk
, 0755);
246 if (symlink(p
, lnk
) < 0)
247 return log_error_errno(errno
, "Failed to create symlink %s: %m", lnk
);
253 static bool path_is_busy(const char *where
) {
256 /* already a mountpoint; generators run during reload */
257 r
= path_is_mount_point(where
, AT_SYMLINK_FOLLOW
);
261 /* the directory might not exist on a stateless system */
268 /* not a mountpoint but it contains files */
269 if (dir_is_empty(where
) <= 0)
275 static int probe_and_add_mount(
280 const char *description
,
283 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
284 const char *fstype
= NULL
;
292 if (path_is_busy(where
)) {
293 log_debug("%s already populated, ignoring.", where
);
297 /* Let's check the partition type here, so that we know
298 * whether to do LUKS magic. */
301 b
= blkid_new_probe_from_filename(what
);
305 log_error_errno(errno
, "Failed to allocate prober: %m");
309 blkid_probe_enable_superblocks(b
, 1);
310 blkid_probe_set_superblocks_flags(b
, BLKID_SUBLKS_TYPE
);
313 r
= blkid_do_safeprobe(b
);
314 if (r
== -2 || r
== 1) /* no result or uncertain */
317 return log_error_errno(errno
?: EIO
, "Failed to probe %s: %m", what
);
319 /* add_mount is OK with fstype being NULL. */
320 (void) blkid_probe_lookup_value(b
, "TYPE", &fstype
, NULL
);
333 static int add_swap(const char *path
) {
334 _cleanup_free_
char *name
= NULL
, *unit
= NULL
, *lnk
= NULL
;
335 _cleanup_fclose_
FILE *f
= NULL
;
340 log_debug("Adding swap: %s", path
);
342 r
= unit_name_from_path(path
, ".swap", &name
);
344 return log_error_errno(r
, "Failed to generate unit name: %m");
346 unit
= strjoin(arg_dest
, "/", name
, NULL
);
350 f
= fopen(unit
, "wxe");
352 return log_error_errno(errno
, "Failed to create unit file %s: %m", unit
);
355 "# Automatically generated by systemd-gpt-auto-generator\n\n"
357 "Description=Swap Partition\n"
358 "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
363 r
= fflush_and_check(f
);
365 return log_error_errno(r
, "Failed to write unit file %s: %m", unit
);
367 lnk
= strjoin(arg_dest
, "/" SPECIAL_SWAP_TARGET
".wants/", name
, NULL
);
371 mkdir_parents_label(lnk
, 0755);
372 if (symlink(unit
, lnk
) < 0)
373 return log_error_errno(errno
, "Failed to create symlink %s: %m", lnk
);
379 static int add_automount(
386 const char *description
,
389 _cleanup_free_
char *unit
= NULL
, *lnk
= NULL
;
390 _cleanup_free_
char *opt
, *p
= NULL
;
391 _cleanup_fclose_
FILE *f
= NULL
;
399 opt
= strjoin(options
, ",noauto", NULL
);
401 opt
= strdup("noauto");
416 r
= unit_name_from_path(where
, ".automount", &unit
);
418 return log_error_errno(r
, "Failed to generate unit name: %m");
420 p
= strjoin(arg_dest
, "/", unit
, NULL
);
426 return log_error_errno(errno
, "Failed to create unit file %s: %m", unit
);
429 "# Automatically generated by systemd-gpt-auto-generator\n\n"
432 "Documentation=man:systemd-gpt-auto-generator(8)\n"
435 "TimeoutIdleSec=%lld\n",
438 (unsigned long long)timeout
/ USEC_PER_SEC
);
440 r
= fflush_and_check(f
);
442 return log_error_errno(r
, "Failed to write unit file %s: %m", p
);
444 lnk
= strjoin(arg_dest
, "/" SPECIAL_LOCAL_FS_TARGET
".wants/", unit
, NULL
);
447 mkdir_parents_label(lnk
, 0755);
449 if (symlink(p
, lnk
) < 0)
450 return log_error_errno(errno
, "Failed to create symlink %s: %m", lnk
);
455 static int add_boot(const char *what
) {
456 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
457 const char *fstype
= NULL
, *uuid
= NULL
;
458 sd_id128_t id
, type_id
;
463 if (!is_efi_boot()) {
464 log_debug("Not an EFI boot, ignoring /boot.");
469 log_debug("In initrd, ignoring /boot.");
473 if (detect_container() > 0) {
474 log_debug("In a container, ignoring /boot.");
478 /* We create an .automount which is not overridden by the .mount from the fstab generator. */
479 if (fstab_is_mount_point("/boot")) {
480 log_debug("/boot specified in fstab, ignoring.");
484 if (path_is_busy("/boot")) {
485 log_debug("/boot already populated, ignoring.");
489 r
= efi_loader_get_device_part_uuid(&id
);
491 log_debug("EFI loader partition unknown.");
496 log_error_errno(r
, "Failed to read ESP partition UUID: %m");
501 b
= blkid_new_probe_from_filename(what
);
505 log_error_errno(errno
, "Failed to allocate prober: %m");
509 blkid_probe_enable_partitions(b
, 1);
510 blkid_probe_set_partitions_flags(b
, BLKID_PARTS_ENTRY_DETAILS
);
513 r
= blkid_do_safeprobe(b
);
514 if (r
== -2 || r
== 1) /* no result or uncertain */
517 return log_error_errno(errno
?: EIO
, "Failed to probe %s: %m", what
);
519 (void) blkid_probe_lookup_value(b
, "TYPE", &fstype
, NULL
);
520 if (!streq(fstype
, "vfat")) {
521 log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
525 r
= blkid_probe_lookup_value(b
, "PART_ENTRY_UUID", &uuid
, NULL
);
527 log_debug_errno(r
, "Partition for /boot does not have a UUID, ignoring. %m");
531 if (sd_id128_from_string(uuid
, &type_id
) < 0) {
532 log_debug("Partition for /boot does not have a valid UUID, ignoring.");
536 if (!sd_id128_equal(type_id
, id
)) {
537 log_debug("Partition for /boot does not appear to be the partition we are booted from.");
541 r
= add_automount("boot",
547 "EFI System Partition Automount",
553 static int add_boot(const char *what
) {
558 static int enumerate_partitions(dev_t devnum
) {
560 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
561 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
562 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
563 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
564 _cleanup_free_
char *boot
= NULL
, *home
= NULL
, *srv
= NULL
;
565 struct udev_list_entry
*first
, *item
;
566 struct udev_device
*parent
= NULL
;
567 const char *name
, *node
, *pttype
, *devtype
;
568 int boot_nr
= -1, home_nr
= -1, srv_nr
= -1;
569 bool home_rw
= true, srv_rw
= true;
578 d
= udev_device_new_from_devnum(udev
, 'b', devnum
);
582 name
= udev_device_get_devnode(d
);
584 name
= udev_device_get_syspath(d
);
586 log_debug("Device %u:%u does not have a name, ignoring.",
587 major(devnum
), minor(devnum
));
591 parent
= udev_device_get_parent(d
);
593 log_debug("%s: not a partitioned device, ignoring.", name
);
597 /* Does it have a devtype? */
598 devtype
= udev_device_get_devtype(parent
);
600 log_debug("%s: parent doesn't have a device type, ignoring.", name
);
604 /* Is this a disk or a partition? We only care for disks... */
605 if (!streq(devtype
, "disk")) {
606 log_debug("%s: parent isn't a raw disk, ignoring.", name
);
610 /* Does it have a device node? */
611 node
= udev_device_get_devnode(parent
);
613 log_debug("%s: parent device does not have device node, ignoring.", name
);
617 log_debug("%s: root device %s.", name
, node
);
619 pn
= udev_device_get_devnum(parent
);
624 b
= blkid_new_probe_from_filename(node
);
629 return log_error_errno(errno
, "%s: failed to allocate prober: %m", node
);
632 blkid_probe_enable_partitions(b
, 1);
633 blkid_probe_set_partitions_flags(b
, BLKID_PARTS_ENTRY_DETAILS
);
636 r
= blkid_do_safeprobe(b
);
638 return 0; /* no results */
640 log_warning("%s: probe gave ambiguous results, ignoring", node
);
643 return log_error_errno(errno
?: EIO
, "%s: failed to probe: %m", node
);
646 r
= blkid_probe_lookup_value(b
, "PTTYPE", &pttype
, NULL
);
648 return log_error_errno(errno
?: EIO
,
649 "%s: failed to determine partition table type: %m", node
);
651 /* We only do this all for GPT... */
652 if (!streq_ptr(pttype
, "gpt")) {
653 log_debug("%s: not a GPT partition table, ignoring.", node
);
658 pl
= blkid_probe_get_partitions(b
);
663 return log_error_errno(errno
, "%s: failed to list partitions: %m", node
);
666 e
= udev_enumerate_new(udev
);
670 r
= udev_enumerate_add_match_parent(e
, parent
);
674 r
= udev_enumerate_add_match_subsystem(e
, "block");
678 r
= udev_enumerate_scan_devices(e
);
680 return log_error_errno(r
, "%s: failed to enumerate partitions: %m", node
);
682 first
= udev_enumerate_get_list_entry(e
);
683 udev_list_entry_foreach(item
, first
) {
684 _cleanup_udev_device_unref_
struct udev_device
*q
;
685 unsigned long long flags
;
686 const char *stype
, *subnode
;
692 q
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
696 qn
= udev_device_get_devnum(q
);
706 subnode
= udev_device_get_devnode(q
);
710 pp
= blkid_partlist_devno_to_partition(pl
, qn
);
714 nr
= blkid_partition_get_partno(pp
);
718 stype
= blkid_partition_get_type_string(pp
);
722 if (sd_id128_from_string(stype
, &type_id
) < 0)
725 flags
= blkid_partition_get_flags(pp
);
727 if (sd_id128_equal(type_id
, GPT_SWAP
)) {
729 if (flags
& GPT_FLAG_NO_AUTO
)
732 if (flags
& GPT_FLAG_READ_ONLY
) {
733 log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode
);
737 k
= add_swap(subnode
);
741 } else if (sd_id128_equal(type_id
, GPT_ESP
)) {
743 /* We only care for the first /boot partition */
744 if (boot
&& nr
>= boot_nr
)
747 /* Note that we do not honour the "no-auto"
748 * flag for the ESP, as it is often unset, to
749 * hide it from Windows. */
753 r
= free_and_strdup(&boot
, subnode
);
757 } else if (sd_id128_equal(type_id
, GPT_HOME
)) {
759 if (flags
& GPT_FLAG_NO_AUTO
)
762 /* We only care for the first /home partition */
763 if (home
&& nr
>= home_nr
)
767 home_rw
= !(flags
& GPT_FLAG_READ_ONLY
),
769 r
= free_and_strdup(&home
, subnode
);
773 } else if (sd_id128_equal(type_id
, GPT_SRV
)) {
775 if (flags
& GPT_FLAG_NO_AUTO
)
778 /* We only care for the first /srv partition */
779 if (srv
&& nr
>= srv_nr
)
783 srv_rw
= !(flags
& GPT_FLAG_READ_ONLY
),
785 r
= free_and_strdup(&srv
, subnode
);
798 k
= probe_and_add_mount("home", home
, "/home", home_rw
, "Home Partition", SPECIAL_LOCAL_FS_TARGET
);
804 k
= probe_and_add_mount("srv", srv
, "/srv", srv_rw
, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET
);
812 static int get_block_device(const char *path
, dev_t
*dev
) {
819 /* Get's the block device directly backing a file system. If
820 * the block device is encrypted, returns the device mapper
823 if (lstat(path
, &st
))
826 if (major(st
.st_dev
) != 0) {
831 if (statfs(path
, &sfs
) < 0)
834 if (F_TYPE_EQUAL(sfs
.f_type
, BTRFS_SUPER_MAGIC
))
835 return btrfs_get_block_device(path
, dev
);
840 static int get_block_device_harder(const char *path
, dev_t
*dev
) {
841 _cleanup_closedir_
DIR *d
= NULL
;
842 _cleanup_free_
char *p
= NULL
, *t
= NULL
;
843 struct dirent
*de
, *found
= NULL
;
852 /* Gets the backing block device for a file system, and
853 * handles LUKS encrypted file systems, looking for its
854 * immediate parent, if there is one. */
856 r
= get_block_device(path
, &dt
);
860 if (asprintf(&p
, "/sys/dev/block/%u:%u/slaves", major(dt
), minor(dt
)) < 0)
871 FOREACH_DIRENT_ALL(de
, d
, return -errno
) {
873 if (STR_IN_SET(de
->d_name
, ".", ".."))
876 if (!IN_SET(de
->d_type
, DT_LNK
, DT_UNKNOWN
))
879 if (found
) /* Don't try to support multiple backing block devices */
888 q
= strjoina(p
, "/", found
->d_name
, "/dev");
890 r
= read_one_line_file(q
, &t
);
896 if (sscanf(t
, "%u:%u", &maj
, &min
) != 2)
902 *dev
= makedev(maj
, min
);
910 static int parse_proc_cmdline_item(const char *key
, const char *value
) {
915 if (STR_IN_SET(key
, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value
) {
917 r
= parse_boolean(value
);
919 log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value
);
923 } else if (streq(key
, "root") && value
) {
925 /* Disable root disk logic if there's a root= value
926 * specified (unless it happens to be "gpt-auto") */
928 arg_root_enabled
= streq(value
, "gpt-auto");
930 } else if (streq(key
, "rw") && !value
)
932 else if (streq(key
, "ro") && !value
)
938 static int add_root_mount(void) {
943 if (!is_efi_boot()) {
944 log_debug("Not a EFI boot, not creating root mount.");
948 r
= efi_loader_get_device_part_uuid(NULL
);
950 log_debug("EFI loader partition unknown, exiting.");
953 return log_error_errno(r
, "Failed to read ESP partition UUID: %m");
955 /* OK, we have an ESP partition, this is fantastic, so let's
956 * wait for a root device to show up. A udev rule will create
957 * the link for us under the right name. */
961 "/dev/gpt-auto-root",
962 in_initrd() ? "/sysroot" : "/",
967 in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET
: SPECIAL_LOCAL_FS_TARGET
);
973 static int add_mounts(void) {
977 r
= get_block_device_harder("/", &devno
);
979 return log_error_errno(r
, "Failed to determine block device of root file system: %m");
981 r
= get_block_device_harder("/usr", &devno
);
983 return log_error_errno(r
, "Failed to determine block device of /usr file system: %m");
985 log_debug("Neither root nor /usr file system are on a (single) block device.");
990 return enumerate_partitions(devno
);
993 int main(int argc
, char *argv
[]) {
996 if (argc
> 1 && argc
!= 4) {
997 log_error("This program takes three or no arguments.");
1004 log_set_target(LOG_TARGET_SAFE
);
1005 log_parse_environment();
1010 if (detect_container() > 0) {
1011 log_debug("In a container, exiting.");
1012 return EXIT_SUCCESS
;
1015 r
= parse_proc_cmdline(parse_proc_cmdline_item
);
1017 log_warning_errno(r
, "Failed to parse kernel command line, ignoring: %m");
1020 log_debug("Disabled, exiting.");
1021 return EXIT_SUCCESS
;
1024 if (arg_root_enabled
)
1025 r
= add_root_mount();
1035 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;