From: Luca Boccassi Date: Thu, 18 Dec 2025 12:47:51 +0000 (+0000) Subject: image-policy: add helper to determine fstype X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4be5c2870f1a665d107e18eb1a27dadfa511fadb;p=thirdparty%2Fsystemd.git image-policy: add helper to determine fstype --- diff --git a/src/shared/image-policy.c b/src/shared/image-policy.c index 44c807f6cbb..b5f9e699d6d 100644 --- a/src/shared/image-policy.c +++ b/src/shared/image-policy.c @@ -495,6 +495,43 @@ int partition_policy_flags_to_string(PartitionPolicyFlags flags, bool simplify, return (int) m; } +int partition_policy_determine_fstype( + const ImagePolicy *policy, + PartitionDesignator designator, + bool *ret_encrypted, + char **ret_fstype) { + + _cleanup_free_ char *fstype = NULL; + PartitionPolicyFlags policy_flags; + int r; + + assert(designator >= 0 && designator < _PARTITION_DESIGNATOR_MAX); + assert(ret_fstype); + + policy_flags = image_policy_get_exhaustively(policy, designator); + if (policy_flags < 0) + return policy_flags; + + /* The policy fstype flags translate to the literal fstype name of each filesystem. */ + r = partition_policy_flags_to_string(policy_flags & _PARTITION_POLICY_FSTYPE_MASK, /* simplify= */ true, &fstype); + if (r < 0) + return r; + /* Input must be a single filesystem type, if the policy specifies more than one, return NULL */ + if (r != 1) { + if (ret_encrypted) + *ret_encrypted = false; + *ret_fstype = NULL; + return 0; + } + + /* If the policy also allows unprotected or verity filesystems, don't set the 'encrypted' flag */ + if (ret_encrypted) + *ret_encrypted = (policy_flags & (PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY)) && + !(policy_flags & (PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_UNPROTECTED)); + *ret_fstype = TAKE_PTR(fstype); + return 1; +} + static bool partition_policy_flags_extended_equal(PartitionPolicyFlags a, PartitionPolicyFlags b) { return partition_policy_flags_extend(a) == partition_policy_flags_extend(b); } diff --git a/src/shared/image-policy.h b/src/shared/image-policy.h index 8023eb31aeb..218d2c5beb6 100644 --- a/src/shared/image-policy.h +++ b/src/shared/image-policy.h @@ -97,6 +97,8 @@ PartitionPolicyFlags partition_policy_flags_reduce(PartitionPolicyFlags flags); PartitionPolicyFlags partition_policy_flags_from_string(const char *s, bool graceful); int partition_policy_flags_to_string(PartitionPolicyFlags flags, bool simplify, char **ret); +int partition_policy_determine_fstype(const ImagePolicy *policy, PartitionDesignator designator, bool *ret_encrypted, char **ret_fstype); + int image_policy_from_string(const char *s, bool graceful, ImagePolicy **ret); int image_policy_to_string(const ImagePolicy *policy, bool simplify, char **ret); diff --git a/src/test/test-image-policy.c b/src/test/test-image-policy.c index 01c0417900f..f285d31d9e1 100644 --- a/src/test/test-image-policy.c +++ b/src/test/test-image-policy.c @@ -201,4 +201,68 @@ TEST(image_policy_ignore_designators) { test_policy_ignore_designators_one("~", ((const PartitionDesignator[]) { PARTITION_VAR, PARTITION_ESP, PARTITION_VAR }), 2, "var=ignore:esp=ignore:=absent"); } +TEST(partition_policy_determine_fstype) { + _cleanup_(image_policy_freep) ImagePolicy *p = NULL; + _cleanup_free_ char *fstype = NULL; + bool encrypted; + int r; + + ASSERT_OK(image_policy_from_string("root=ext4+encrypted", /* graceful= */ false, &p)); + r = partition_policy_determine_fstype(p, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_GT(r, 0); + ASSERT_STREQ(fstype, "ext4"); + ASSERT_TRUE(encrypted); + + fstype = mfree(fstype); + p = image_policy_free(p); + ASSERT_OK(image_policy_from_string("usr=verity+erofs", /* graceful= */ false, &p)); + r = partition_policy_determine_fstype(p, PARTITION_USR, &encrypted, &fstype); + ASSERT_GT(r, 0); + ASSERT_STREQ(fstype, "erofs"); + ASSERT_FALSE(encrypted); + fstype = mfree(fstype); + r = partition_policy_determine_fstype(p, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_EQ(r, 0); + ASSERT_FALSE(fstype); + ASSERT_FALSE(encrypted); + + fstype = mfree(fstype); + p = image_policy_free(p); + ASSERT_OK(image_policy_from_string("root=ext4+erofs", /* graceful= */ false, &p)); + r = partition_policy_determine_fstype(p, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_EQ(r, 0); + ASSERT_FALSE(fstype); + ASSERT_FALSE(encrypted); + + fstype = mfree(fstype); + p = image_policy_free(p); + ASSERT_OK(image_policy_from_string("root=encrypted", /* graceful= */ false, &p)); + r = partition_policy_determine_fstype(p, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_EQ(r, 0); + ASSERT_FALSE(fstype); + ASSERT_FALSE(encrypted); + + fstype = mfree(fstype); + p = image_policy_free(p); + ASSERT_OK(image_policy_from_string("", /* graceful= */ false, &p)); + r = partition_policy_determine_fstype(p, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_EQ(r, 0); + ASSERT_FALSE(fstype); + ASSERT_FALSE(encrypted); + + fstype = mfree(fstype); + r = partition_policy_determine_fstype(/* policy= */ NULL, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_EQ(r, 0); + ASSERT_FALSE(fstype); + ASSERT_FALSE(encrypted); + + fstype = mfree(fstype); + p = image_policy_free(p); + ASSERT_OK(image_policy_from_string("root=encrypted+signed+btrfs", /* graceful= */ false, &p)); + r = partition_policy_determine_fstype(p, PARTITION_ROOT, &encrypted, &fstype); + ASSERT_GT(r, 0); + ASSERT_STREQ(fstype, "btrfs"); + ASSERT_FALSE(encrypted); +} + DEFINE_TEST_MAIN(LOG_INFO);