]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
image-policy: add helper to determine fstype
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 18 Dec 2025 12:47:51 +0000 (12:47 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 19 Dec 2025 09:17:41 +0000 (09:17 +0000)
src/shared/image-policy.c
src/shared/image-policy.h
src/test/test-image-policy.c

index 44c807f6cbb18a352b2a246bf406a4290e4fc08c..b5f9e699d6dddc504778e1647e7f16f64777c03c 100644 (file)
@@ -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);
 }
index 8023eb31aebc09f683bd41ad9997e5097fa88121..218d2c5beb63a864fdc79a6d8d26ad191fbd4a2a 100644 (file)
@@ -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);
 
index 01c0417900f28be9afde8f16ca762233643c388d..f285d31d9e1056f0a7a35aaf5a3ad93b1c84f7f4 100644 (file)
@@ -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);