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 "blkid-util.h"
31 #include "btrfs-util.h"
35 #include "fstab-util.h"
36 #include "generator.h"
40 #include "parse-util.h"
41 #include "path-util.h"
43 #include "string-util.h"
44 #include "udev-util.h"
45 #include "unit-name.h"
49 static const char *arg_dest
= "/tmp";
50 static bool arg_enabled
= true;
51 static bool arg_root_enabled
= true;
52 static bool arg_root_rw
= false;
54 static int add_cryptsetup(const char *id
, const char *what
, bool rw
, char **device
) {
55 _cleanup_free_
char *e
= NULL
, *n
= NULL
, *p
= NULL
, *d
= NULL
, *to
= NULL
;
56 _cleanup_fclose_
FILE *f
= NULL
;
64 r
= unit_name_from_path(what
, ".device", &d
);
66 return log_error_errno(r
, "Failed to generate unit name: %m");
68 e
= unit_name_escape(id
);
72 r
= unit_name_build("systemd-cryptsetup", e
, ".service", &n
);
74 return log_error_errno(r
, "Failed to generate unit name: %m");
76 p
= strjoin(arg_dest
, "/", n
, NULL
);
82 return log_error_errno(errno
, "Failed to create unit file %s: %m", p
);
85 "# Automatically generated by systemd-gpt-auto-generator\n\n"
87 "Description=Cryptography Setup for %%I\n"
88 "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
89 "DefaultDependencies=no\n"
90 "Conflicts=umount.target\n"
91 "BindsTo=dev-mapper-%%i.device %s\n"
92 "Before=umount.target cryptsetup.target\n"
94 "IgnoreOnIsolate=true\n"
97 "RemainAfterExit=yes\n"
98 "TimeoutSec=0\n" /* the binary handles timeouts anyway */
99 "ExecStart=" SYSTEMD_CRYPTSETUP_PATH
" attach '%s' '%s' '' '%s'\n"
100 "ExecStop=" SYSTEMD_CRYPTSETUP_PATH
" detach '%s'\n",
102 id
, what
, rw
? "" : "read-only",
105 r
= fflush_and_check(f
);
107 return log_error_errno(r
, "Failed to write file %s: %m", p
);
109 from
= strjoina("../", n
);
111 to
= strjoin(arg_dest
, "/", d
, ".wants/", n
, NULL
);
115 mkdir_parents_label(to
, 0755);
116 if (symlink(from
, to
) < 0)
117 return log_error_errno(errno
, "Failed to create symlink %s: %m", to
);
120 to
= strjoin(arg_dest
, "/cryptsetup.target.requires/", n
, NULL
);
124 mkdir_parents_label(to
, 0755);
125 if (symlink(from
, to
) < 0)
126 return log_error_errno(errno
, "Failed to create symlink %s: %m", to
);
129 to
= strjoin(arg_dest
, "/dev-mapper-", e
, ".device.requires/", n
, NULL
);
133 mkdir_parents_label(to
, 0755);
134 if (symlink(from
, to
) < 0)
135 return log_error_errno(errno
, "Failed to create symlink %s: %m", to
);
138 p
= strjoin(arg_dest
, "/dev-mapper-", e
, ".device.d/50-job-timeout-sec-0.conf", NULL
);
142 mkdir_parents_label(p
, 0755);
143 r
= write_string_file(p
,
144 "# Automatically generated by systemd-gpt-auto-generator\n\n"
147 WRITE_STRING_FILE_CREATE
); /* the binary handles timeouts anyway */
149 return log_error_errno(r
, "Failed to write device drop-in: %m");
151 ret
= strappend("/dev/mapper/", id
);
159 static int add_mount(
166 const char *description
,
169 _cleanup_free_
char *unit
= NULL
, *lnk
= NULL
, *crypto_what
= NULL
, *p
= NULL
;
170 _cleanup_fclose_
FILE *f
= NULL
;
178 log_debug("Adding %s: %s %s", where
, what
, strna(fstype
));
180 if (streq_ptr(fstype
, "crypto_LUKS")) {
182 r
= add_cryptsetup(id
, what
, rw
, &crypto_what
);
190 r
= unit_name_from_path(where
, ".mount", &unit
);
192 return log_error_errno(r
, "Failed to generate unit name: %m");
194 p
= strjoin(arg_dest
, "/", unit
, NULL
);
200 return log_error_errno(errno
, "Failed to create unit file %s: %m", unit
);
203 "# Automatically generated by systemd-gpt-auto-generator\n\n"
206 "Documentation=man:systemd-gpt-auto-generator(8)\n",
210 fprintf(f
, "Before=%s\n", post
);
212 r
= generator_write_fsck_deps(f
, arg_dest
, what
, where
, fstype
);
224 fprintf(f
, "Type=%s\n", fstype
);
227 fprintf(f
, "Options=%s,%s\n", options
, rw
? "rw" : "ro");
229 fprintf(f
, "Options=%s\n", rw
? "rw" : "ro");
231 r
= fflush_and_check(f
);
233 return log_error_errno(r
, "Failed to write unit file %s: %m", p
);
236 lnk
= strjoin(arg_dest
, "/", post
, ".requires/", unit
, NULL
);
240 mkdir_parents_label(lnk
, 0755);
241 if (symlink(p
, lnk
) < 0)
242 return log_error_errno(errno
, "Failed to create symlink %s: %m", lnk
);
248 static bool path_is_busy(const char *where
) {
251 /* already a mountpoint; generators run during reload */
252 r
= path_is_mount_point(where
, AT_SYMLINK_FOLLOW
);
256 /* the directory might not exist on a stateless system */
263 /* not a mountpoint but it contains files */
264 if (dir_is_empty(where
) <= 0)
270 static int probe_and_add_mount(
275 const char *description
,
278 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
279 const char *fstype
= NULL
;
287 if (path_is_busy(where
)) {
288 log_debug("%s already populated, ignoring.", where
);
292 /* Let's check the partition type here, so that we know
293 * whether to do LUKS magic. */
296 b
= blkid_new_probe_from_filename(what
);
300 log_error_errno(errno
, "Failed to allocate prober: %m");
304 blkid_probe_enable_superblocks(b
, 1);
305 blkid_probe_set_superblocks_flags(b
, BLKID_SUBLKS_TYPE
);
308 r
= blkid_do_safeprobe(b
);
309 if (r
== -2 || r
== 1) /* no result or uncertain */
312 return log_error_errno(errno
?: EIO
, "Failed to probe %s: %m", what
);
314 /* add_mount is OK with fstype being NULL. */
315 (void) blkid_probe_lookup_value(b
, "TYPE", &fstype
, NULL
);
328 static int add_swap(const char *path
) {
329 _cleanup_free_
char *name
= NULL
, *unit
= NULL
, *lnk
= NULL
;
330 _cleanup_fclose_
FILE *f
= NULL
;
335 log_debug("Adding swap: %s", path
);
337 r
= unit_name_from_path(path
, ".swap", &name
);
339 return log_error_errno(r
, "Failed to generate unit name: %m");
341 unit
= strjoin(arg_dest
, "/", name
, NULL
);
345 f
= fopen(unit
, "wxe");
347 return log_error_errno(errno
, "Failed to create unit file %s: %m", unit
);
350 "# Automatically generated by systemd-gpt-auto-generator\n\n"
352 "Description=Swap Partition\n"
353 "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
358 r
= fflush_and_check(f
);
360 return log_error_errno(r
, "Failed to write unit file %s: %m", unit
);
362 lnk
= strjoin(arg_dest
, "/" SPECIAL_SWAP_TARGET
".wants/", name
, NULL
);
366 mkdir_parents_label(lnk
, 0755);
367 if (symlink(unit
, lnk
) < 0)
368 return log_error_errno(errno
, "Failed to create symlink %s: %m", lnk
);
374 static int add_automount(
381 const char *description
,
384 _cleanup_free_
char *unit
= NULL
, *lnk
= NULL
;
385 _cleanup_free_
char *opt
, *p
= NULL
;
386 _cleanup_fclose_
FILE *f
= NULL
;
394 opt
= strjoin(options
, ",noauto", NULL
);
396 opt
= strdup("noauto");
411 r
= unit_name_from_path(where
, ".automount", &unit
);
413 return log_error_errno(r
, "Failed to generate unit name: %m");
415 p
= strjoin(arg_dest
, "/", unit
, NULL
);
421 return log_error_errno(errno
, "Failed to create unit file %s: %m", unit
);
424 "# Automatically generated by systemd-gpt-auto-generator\n\n"
427 "Documentation=man:systemd-gpt-auto-generator(8)\n"
430 "TimeoutIdleSec=%lld\n",
433 (unsigned long long)timeout
/ USEC_PER_SEC
);
435 r
= fflush_and_check(f
);
437 return log_error_errno(r
, "Failed to write unit file %s: %m", p
);
439 lnk
= strjoin(arg_dest
, "/" SPECIAL_LOCAL_FS_TARGET
".wants/", unit
, NULL
);
442 mkdir_parents_label(lnk
, 0755);
444 if (symlink(p
, lnk
) < 0)
445 return log_error_errno(errno
, "Failed to create symlink %s: %m", lnk
);
450 static int add_boot(const char *what
) {
451 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
452 const char *fstype
= NULL
, *uuid
= NULL
;
453 sd_id128_t id
, type_id
;
458 if (!is_efi_boot()) {
459 log_debug("Not an EFI boot, ignoring /boot.");
464 log_debug("In initrd, ignoring /boot.");
468 if (detect_container() > 0) {
469 log_debug("In a container, ignoring /boot.");
473 /* We create an .automount which is not overridden by the .mount from the fstab generator. */
474 if (fstab_is_mount_point("/boot")) {
475 log_debug("/boot specified in fstab, ignoring.");
479 if (path_is_busy("/boot")) {
480 log_debug("/boot already populated, ignoring.");
484 r
= efi_loader_get_device_part_uuid(&id
);
486 log_debug("EFI loader partition unknown.");
491 log_error_errno(r
, "Failed to read ESP partition UUID: %m");
496 b
= blkid_new_probe_from_filename(what
);
500 log_error_errno(errno
, "Failed to allocate prober: %m");
504 blkid_probe_enable_partitions(b
, 1);
505 blkid_probe_set_partitions_flags(b
, BLKID_PARTS_ENTRY_DETAILS
);
508 r
= blkid_do_safeprobe(b
);
509 if (r
== -2 || r
== 1) /* no result or uncertain */
512 return log_error_errno(errno
?: EIO
, "Failed to probe %s: %m", what
);
514 (void) blkid_probe_lookup_value(b
, "TYPE", &fstype
, NULL
);
515 if (!streq(fstype
, "vfat")) {
516 log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
520 r
= blkid_probe_lookup_value(b
, "PART_ENTRY_UUID", &uuid
, NULL
);
522 log_debug_errno(r
, "Partition for /boot does not have a UUID, ignoring. %m");
526 if (sd_id128_from_string(uuid
, &type_id
) < 0) {
527 log_debug("Partition for /boot does not have a valid UUID, ignoring.");
531 if (!sd_id128_equal(type_id
, id
)) {
532 log_debug("Partition for /boot does not appear to be the partition we are booted from.");
536 r
= add_automount("boot",
542 "EFI System Partition Automount",
548 static int add_boot(const char *what
) {
553 static int enumerate_partitions(dev_t devnum
) {
555 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
556 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
557 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
558 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
559 _cleanup_free_
char *boot
= NULL
, *home
= NULL
, *srv
= NULL
;
560 struct udev_list_entry
*first
, *item
;
561 struct udev_device
*parent
= NULL
;
562 const char *name
, *node
, *pttype
, *devtype
;
563 int boot_nr
= -1, home_nr
= -1, srv_nr
= -1;
564 bool home_rw
= true, srv_rw
= true;
573 d
= udev_device_new_from_devnum(udev
, 'b', devnum
);
577 name
= udev_device_get_devnode(d
);
579 name
= udev_device_get_syspath(d
);
581 log_debug("Device %u:%u does not have a name, ignoring.",
582 major(devnum
), minor(devnum
));
586 parent
= udev_device_get_parent(d
);
588 log_debug("%s: not a partitioned device, ignoring.", name
);
592 /* Does it have a devtype? */
593 devtype
= udev_device_get_devtype(parent
);
595 log_debug("%s: parent doesn't have a device type, ignoring.", name
);
599 /* Is this a disk or a partition? We only care for disks... */
600 if (!streq(devtype
, "disk")) {
601 log_debug("%s: parent isn't a raw disk, ignoring.", name
);
605 /* Does it have a device node? */
606 node
= udev_device_get_devnode(parent
);
608 log_debug("%s: parent device does not have device node, ignoring.", name
);
612 log_debug("%s: root device %s.", name
, node
);
614 pn
= udev_device_get_devnum(parent
);
619 b
= blkid_new_probe_from_filename(node
);
624 return log_error_errno(errno
, "%s: failed to allocate prober: %m", node
);
627 blkid_probe_enable_partitions(b
, 1);
628 blkid_probe_set_partitions_flags(b
, BLKID_PARTS_ENTRY_DETAILS
);
631 r
= blkid_do_safeprobe(b
);
633 return 0; /* no results */
635 log_warning("%s: probe gave ambiguous results, ignoring", node
);
638 return log_error_errno(errno
?: EIO
, "%s: failed to probe: %m", node
);
641 r
= blkid_probe_lookup_value(b
, "PTTYPE", &pttype
, NULL
);
643 return log_error_errno(errno
?: EIO
,
644 "%s: failed to determine partition table type: %m", node
);
646 /* We only do this all for GPT... */
647 if (!streq_ptr(pttype
, "gpt")) {
648 log_debug("%s: not a GPT partition table, ignoring.", node
);
653 pl
= blkid_probe_get_partitions(b
);
658 return log_error_errno(errno
, "%s: failed to list partitions: %m", node
);
661 e
= udev_enumerate_new(udev
);
665 r
= udev_enumerate_add_match_parent(e
, parent
);
669 r
= udev_enumerate_add_match_subsystem(e
, "block");
673 r
= udev_enumerate_scan_devices(e
);
675 return log_error_errno(r
, "%s: failed to enumerate partitions: %m", node
);
677 first
= udev_enumerate_get_list_entry(e
);
678 udev_list_entry_foreach(item
, first
) {
679 _cleanup_udev_device_unref_
struct udev_device
*q
;
680 unsigned long long flags
;
681 const char *stype
, *subnode
;
687 q
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
691 qn
= udev_device_get_devnum(q
);
701 subnode
= udev_device_get_devnode(q
);
705 pp
= blkid_partlist_devno_to_partition(pl
, qn
);
709 nr
= blkid_partition_get_partno(pp
);
713 stype
= blkid_partition_get_type_string(pp
);
717 if (sd_id128_from_string(stype
, &type_id
) < 0)
720 flags
= blkid_partition_get_flags(pp
);
722 if (sd_id128_equal(type_id
, GPT_SWAP
)) {
724 if (flags
& GPT_FLAG_NO_AUTO
)
727 if (flags
& GPT_FLAG_READ_ONLY
) {
728 log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode
);
732 k
= add_swap(subnode
);
736 } else if (sd_id128_equal(type_id
, GPT_ESP
)) {
738 /* We only care for the first /boot partition */
739 if (boot
&& nr
>= boot_nr
)
742 /* Note that we do not honour the "no-auto"
743 * flag for the ESP, as it is often unset, to
744 * hide it from Windows. */
748 r
= free_and_strdup(&boot
, subnode
);
752 } else if (sd_id128_equal(type_id
, GPT_HOME
)) {
754 if (flags
& GPT_FLAG_NO_AUTO
)
757 /* We only care for the first /home partition */
758 if (home
&& nr
>= home_nr
)
762 home_rw
= !(flags
& GPT_FLAG_READ_ONLY
),
764 r
= free_and_strdup(&home
, subnode
);
768 } else if (sd_id128_equal(type_id
, GPT_SRV
)) {
770 if (flags
& GPT_FLAG_NO_AUTO
)
773 /* We only care for the first /srv partition */
774 if (srv
&& nr
>= srv_nr
)
778 srv_rw
= !(flags
& GPT_FLAG_READ_ONLY
),
780 r
= free_and_strdup(&srv
, subnode
);
793 k
= probe_and_add_mount("home", home
, "/home", home_rw
, "Home Partition", SPECIAL_LOCAL_FS_TARGET
);
799 k
= probe_and_add_mount("srv", srv
, "/srv", srv_rw
, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET
);
807 static int get_block_device(const char *path
, dev_t
*dev
) {
814 /* Get's the block device directly backing a file system. If
815 * the block device is encrypted, returns the device mapper
818 if (lstat(path
, &st
))
821 if (major(st
.st_dev
) != 0) {
826 if (statfs(path
, &sfs
) < 0)
829 if (F_TYPE_EQUAL(sfs
.f_type
, BTRFS_SUPER_MAGIC
))
830 return btrfs_get_block_device(path
, dev
);
835 static int get_block_device_harder(const char *path
, dev_t
*dev
) {
836 _cleanup_closedir_
DIR *d
= NULL
;
837 _cleanup_free_
char *p
= NULL
, *t
= NULL
;
838 struct dirent
*de
, *found
= NULL
;
847 /* Gets the backing block device for a file system, and
848 * handles LUKS encrypted file systems, looking for its
849 * immediate parent, if there is one. */
851 r
= get_block_device(path
, &dt
);
855 if (asprintf(&p
, "/sys/dev/block/%u:%u/slaves", major(dt
), minor(dt
)) < 0)
866 FOREACH_DIRENT_ALL(de
, d
, return -errno
) {
868 if (STR_IN_SET(de
->d_name
, ".", ".."))
871 if (!IN_SET(de
->d_type
, DT_LNK
, DT_UNKNOWN
))
874 if (found
) /* Don't try to support multiple backing block devices */
883 q
= strjoina(p
, "/", found
->d_name
, "/dev");
885 r
= read_one_line_file(q
, &t
);
891 if (sscanf(t
, "%u:%u", &maj
, &min
) != 2)
897 *dev
= makedev(maj
, min
);
905 static int parse_proc_cmdline_item(const char *key
, const char *value
) {
910 if (STR_IN_SET(key
, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value
) {
912 r
= parse_boolean(value
);
914 log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value
);
918 } else if (streq(key
, "root") && value
) {
920 /* Disable root disk logic if there's a root= value
921 * specified (unless it happens to be "gpt-auto") */
923 arg_root_enabled
= streq(value
, "gpt-auto");
925 } else if (streq(key
, "rw") && !value
)
927 else if (streq(key
, "ro") && !value
)
933 static int add_root_mount(void) {
938 if (!is_efi_boot()) {
939 log_debug("Not a EFI boot, not creating root mount.");
943 r
= efi_loader_get_device_part_uuid(NULL
);
945 log_debug("EFI loader partition unknown, exiting.");
948 return log_error_errno(r
, "Failed to read ESP partition UUID: %m");
950 /* OK, we have an ESP partition, this is fantastic, so let's
951 * wait for a root device to show up. A udev rule will create
952 * the link for us under the right name. */
956 "/dev/gpt-auto-root",
957 in_initrd() ? "/sysroot" : "/",
962 in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET
: SPECIAL_LOCAL_FS_TARGET
);
968 static int add_mounts(void) {
972 r
= get_block_device_harder("/", &devno
);
974 return log_error_errno(r
, "Failed to determine block device of root file system: %m");
976 r
= get_block_device_harder("/usr", &devno
);
978 return log_error_errno(r
, "Failed to determine block device of /usr file system: %m");
980 log_debug("Neither root nor /usr file system are on a (single) block device.");
985 return enumerate_partitions(devno
);
988 int main(int argc
, char *argv
[]) {
991 if (argc
> 1 && argc
!= 4) {
992 log_error("This program takes three or no arguments.");
999 log_set_target(LOG_TARGET_SAFE
);
1000 log_parse_environment();
1005 if (detect_container() > 0) {
1006 log_debug("In a container, exiting.");
1007 return EXIT_SUCCESS
;
1010 r
= parse_proc_cmdline(parse_proc_cmdline_item
);
1012 log_warning_errno(r
, "Failed to parse kernel command line, ignoring: %m");
1015 log_debug("Disabled, exiting.");
1016 return EXIT_SUCCESS
;
1019 if (arg_root_enabled
)
1020 r
= add_root_mount();
1030 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;