diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 3a35c1b9aa..6eda26c7d6 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -529,6 +529,15 @@ disk images with `--image=` or similar: systems that may be mounted for automatically dissected disk images. If not specified defaults to something like: `ext4:btrfs:xfs:vfat:erofs:squashfs` +* `$SYSTEMD_DISSECT_FSTYPE_=` – overrides the file system time to + use when mounting the partition of the indicated designator. The + `` string shall be one of `ROOT`, `USR`, `HOME`, `SRV`, `ESP`, + `XBOOTLDR`, `TMP`, `VAR` as per the [Discoverable Partitions + Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification/). If + unspecified the image dissection logic will automatically probe the file + system type (subject to `$SYSTEMD_DISSECT_FILE_SYSTEMS`, see above), except + for ESP and XBOOTLDR where the file system type is set to VFAT. + * `$SYSTEMD_LOOP_DIRECT_IO` – takes a boolean, which controls whether to enable `LO_FLAGS_DIRECT_IO` (i.e. direct IO + asynchronous IO) on loopback block devices when opening them. Defaults to on, set this to "0" to disable this diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index e44c307bbf..4cb84116fa 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -117,6 +117,17 @@ int dissect_fstype_ok(const char *fstype) { return false; } +static const char *getenv_fstype(PartitionDesignator d) { + + if (d < 0 || + partition_designator_is_verity(d) || + d == PARTITION_SWAP) + return NULL; + + char *v = strjoina("SYSTEMD_DISSECT_FSTYPE_", partition_designator_to_string(d)); + return secure_getenv(ascii_strupper(v)); +} + int probe_sector_size(int fd, uint32_t *ret) { /* Disk images might be for 512B or for 4096 sector sizes, let's try to auto-detect that by searching @@ -1032,7 +1043,7 @@ static int dissect_image( } if (is_gpt) { - const char *fstype = NULL, *label; + const char *label; sd_id128_t type_id, id; GptPartitionType type; bool rw = true, growfs = false; @@ -1085,6 +1096,8 @@ static int dissect_image( continue; } + const char *fstype = getenv_fstype(type.designator); + if (IN_SET(type.designator, PARTITION_HOME, PARTITION_SRV, @@ -1097,6 +1110,11 @@ static int dissect_image( rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); + /* XBOOTLDR cannot be integrity protected (since firmware needs to access + * it), hence be restrictive with the fs choice when dissecting. */ + if (type.designator == PARTITION_XBOOTLDR && !fstype) + fstype = "vfat"; + } else if (type.designator == PARTITION_ESP) { if (FLAGS_SET(pflags, SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL)) { @@ -1104,7 +1122,9 @@ static int dissect_image( continue; } - fstype = "vfat"; + /* Effectively the ESP has to be VFAT, let's enforce this */ + if (!fstype) + fstype = "vfat"; } else if (type.designator == PARTITION_ROOT) { diff --git a/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh b/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh index c6b4ea0655..c8e3da09cf 100755 --- a/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh +++ b/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh @@ -158,6 +158,8 @@ EOF umount "${IMAGE_DIR}/root" + export SYSTEMD_DISSECT_FSTYPE_XBOOTLDR=ext4 + assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-esp-path)" "/run/systemd/mount-rootfs/efi" assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-esp-path --esp-path=/efi)" "/run/systemd/mount-rootfs/efi" assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-boot-path)" "/run/systemd/mount-rootfs/boot" @@ -167,6 +169,8 @@ EOF bootctl --image "${IMAGE_DIR}/image" --print-root-device || : basic_tests --image "${IMAGE_DIR}/image" + + unset SYSTEMD_DISSECT_FSTYPE_XBOOTLDR } cleanup_raid() (