<para><filename>systemd-gpt-auto-generator</filename> is a unit generator that automatically discovers
the root partition, <filename>/home/</filename>, <filename>/srv/</filename>, <filename>/var/</filename>,
- <filename>/var/tmp/</filename>, the EFI System Partition, the Extended Boot Loader Partition, and swap
- partitions and creates mount and swap units for them, based on the partition type GUIDs of GUID partition
- tables (GPT). See <ulink url="https://uefi.org/specifications">UEFI Specification</ulink>, chapter 5 for
- more details. It implements the <ulink
+ <filename>/var/tmp/</filename>, the EFI System Partition (ESP), the Extended Boot Loader Partition
+ (XBOOTLDR), and swap partitions and creates mount and swap units for them, based on the partition type
+ GUIDs of GUID partition tables (GPT). See <ulink url="https://uefi.org/specifications">UEFI
+ Specification</ulink>, chapter 5 for more details. It implements the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable
Partitions Specification</ulink>.</para>
<para>Note that this generator has no effect on non-GPT systems. It will also not create mount point
configuration for directories which already contain files or if the mount point is explicitly configured
in <citerefentry
- project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>. If
- the units this generator creates are overridden, for example by units in directories with higher
+ project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Additionally
+ no unit will be created for the ESP or the XBOOTLDR partition if mount entries are found in the
+ <filename>/boot/</filename> or <filename>/efi/</filename> hierarchies in <citerefentry
+ project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+ <para>If the units this generator creates are overridden, for example by units in directories with higher
precedence, drop-ins and additional dependencies created by this generator might still be used.</para>
<para>This generator will only look for the root partition on the same physical disk where the EFI System
return generator_add_symlink(arg_dest, SPECIAL_LOCAL_FS_TARGET, "wants", unit);
}
-static int slash_boot_in_fstab(void) {
- static int cache = -1;
-
- if (cache >= 0)
- return cache;
-
- cache = fstab_is_mount_point("/boot");
- if (cache < 0)
- return log_error_errno(cache, "Failed to parse fstab: %m");
- return cache;
-}
-
static int add_partition_xbootldr(DissectedPartition *p) {
_cleanup_free_ char *options = NULL;
int r;
return 0;
}
- r = slash_boot_in_fstab();
- if (r < 0)
- return r;
- if (r > 0) {
- log_debug("/boot/ specified in fstab, ignoring XBOOTLDR partition.");
- return 0;
- }
-
r = path_is_busy("/boot");
if (r < 0)
return r;
}
#if ENABLE_EFI
-static int slash_efi_in_fstab(void) {
- static int cache = -1;
-
- if (cache >= 0)
- return cache;
-
- cache = fstab_is_mount_point("/efi");
- if (cache < 0)
- return log_error_errno(cache, "Failed to parse fstab: %m");
- return cache;
-}
-
static bool slash_boot_exists(void) {
static int cache = -1;
* Otherwise, if /efi/ is unused and empty (or missing), we'll take that.
* Otherwise, we do nothing. */
if (!has_xbootldr && slash_boot_exists()) {
- r = slash_boot_in_fstab();
+ r = path_is_busy("/boot");
if (r < 0)
return r;
if (r == 0) {
- r = path_is_busy("/boot");
- if (r < 0)
- return r;
- if (r == 0) {
- esp_path = "/boot";
- id = "boot";
- }
+ esp_path = "/boot";
+ id = "boot";
}
}
if (!esp_path) {
- r = slash_efi_in_fstab();
- if (r < 0)
- return r;
- if (r > 0)
- return 0;
-
r = path_is_busy("/efi");
if (r < 0)
return r;
assert(esp);
assert(xbootldr);
+ /* If any paths in fstab look similar to our favorite paths for ESP or XBOOTLDR, we just exit
+ * early. We also don't bother with cases where one is configured explicitly and the other shall be
+ * mounted automatically. */
+
+ r = fstab_has_mount_point_prefix_strv(STRV_MAKE("/boot", "/efi"));
+ if (r > 0) {
+ log_debug("Found mount entries in the /boot/ or /efi/ hierarchies in fstab, not generating ESP or XBOOTLDR mounts.");
+ return 0;
+ }
+ if (r < 0)
+ log_debug_errno(r, "Failed to check fstab existing paths, ignoring: %m");
+
if (!is_efi_boot()) {
log_debug("Not an EFI boot, skipping loader partition UUID check.");
goto mount;
return false;
}
+int fstab_has_mount_point_prefix_strv(char **prefixes) {
+ _cleanup_endmntent_ FILE *f = NULL;
+
+ assert(prefixes);
+
+ /* This function returns true if at least one entry in fstab has a mount point that starts with one
+ * of the passed prefixes. */
+
+ if (!fstab_enabled())
+ return false;
+
+ f = setmntent(fstab_path(), "re");
+ if (!f)
+ return errno == ENOENT ? false : -errno;
+
+ for (;;) {
+ struct mntent *me;
+
+ errno = 0;
+ me = getmntent(f);
+ if (!me)
+ return errno != 0 ? -errno : false;
+
+ if (path_startswith_strv(me->mnt_dir, prefixes))
+ return true;
+ }
+}
+
int fstab_is_mount_point_full(const char *where, const char *path) {
_cleanup_endmntent_ FILE *f = NULL;
int r;
return fstab_is_mount_point_full(NULL, path);
}
+int fstab_has_mount_point_prefix_strv(char **prefixes);
+
int fstab_filter_options(
const char *opts,
const char *names,