mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
image-policy: add image_policy_ignore_designators() helper
This new helper patches a provide image policy, setting the policy for specified designators to "ignore". This is useful for contexts where we only want to mount some subset of the available partitions, and hence don't care about the parts of the policy that cover the others. Specifically this is useful in systemd-gpt-auto-generator, which runs at a moment the root file system is already established, and hence the policy for the root file system can be ignored, the facts are already established.
This commit is contained in:
@@ -774,6 +774,56 @@ int image_policy_intersect(const ImagePolicy *a, const ImagePolicy *b, ImagePoli
|
||||
return 0;
|
||||
}
|
||||
|
||||
int image_policy_ignore_designators(const ImagePolicy *p, const PartitionDesignator table[], size_t n_table, ImagePolicy **ret) {
|
||||
assert(p);
|
||||
assert(table || n_table == 0);
|
||||
assert(ret);
|
||||
|
||||
/* Patches the specified image policy, replacing the policy for the specified designators by an
|
||||
* "ignore" policy. Returns a patched copy. This is useful in context where only some of the
|
||||
* available partitions shall be mounted, and hence the policy for the others really doesn't
|
||||
* matter. */
|
||||
|
||||
_cleanup_(image_policy_freep) ImagePolicy *np = image_policy_new(_PARTITION_DESIGNATOR_MAX);
|
||||
if (!np)
|
||||
return -ENOMEM;
|
||||
|
||||
FOREACH_ARRAY(t, table, n_table) {
|
||||
assert(*t >= 0);
|
||||
assert(*t < _PARTITION_DESIGNATOR_MAX);
|
||||
|
||||
if (image_policy_bsearch(np, *t))
|
||||
continue;
|
||||
|
||||
/* Insert an ignore policy for this entry, and sort it to the right place, so that image_policy_bsearch() can work */
|
||||
np->policies[np->n_policies++] = (PartitionPolicy) {
|
||||
.designator = *t,
|
||||
.flags = PARTITION_POLICY_IGNORE,
|
||||
};
|
||||
typesafe_qsort(np->policies, np->n_policies, partition_policy_compare);
|
||||
}
|
||||
|
||||
FOREACH_ARRAY(i, p->policies, p->n_policies) {
|
||||
|
||||
if (image_policy_bsearch(np, i->designator))
|
||||
continue;
|
||||
|
||||
/* Copy the policy entry from the old image policy, and sort it to the right place, so that image_policy_bsearch() can work */
|
||||
np->policies[np->n_policies++] = *i;
|
||||
typesafe_qsort(np->policies, np->n_policies, partition_policy_compare);
|
||||
}
|
||||
|
||||
np->default_flags = p->default_flags;
|
||||
|
||||
/* Return unused space to libc */
|
||||
ImagePolicy *t = realloc(np, offsetof(ImagePolicy, policies) + sizeof(PartitionPolicy) * np->n_policies);
|
||||
if (t)
|
||||
np = t;
|
||||
|
||||
*ret = TAKE_PTR(np);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const ImagePolicy image_policy_allow = {
|
||||
/* Allow policy */
|
||||
.n_policies = 0,
|
||||
|
||||
@@ -106,3 +106,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(ImagePolicy*, image_policy_free);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_image_policy);
|
||||
int parse_image_policy_argument(const char *s, ImagePolicy **policy);
|
||||
|
||||
int image_policy_ignore_designators(const ImagePolicy *p, const PartitionDesignator table[], size_t n_table, ImagePolicy **ret);
|
||||
|
||||
@@ -162,4 +162,31 @@ TEST(image_policy_intersect) {
|
||||
test_policy_intersect_one("root=open", "=verity+ignore", "root=verity+ignore:=ignore");
|
||||
}
|
||||
|
||||
static void test_policy_ignore_designators_one(const char *a, const PartitionDesignator array[], size_t n, const char *b) {
|
||||
_cleanup_(image_policy_freep) ImagePolicy *x = NULL, *y = NULL, *t = NULL;
|
||||
|
||||
ASSERT_OK(image_policy_from_string(a, &x));
|
||||
ASSERT_OK(image_policy_from_string(b, &y));
|
||||
|
||||
_cleanup_free_ char *s1 = NULL, *s2 = NULL, *s3 = NULL;
|
||||
ASSERT_OK(image_policy_to_string(x, true, &s1));
|
||||
ASSERT_OK(image_policy_to_string(y, true, &s2));
|
||||
|
||||
ASSERT_OK(image_policy_ignore_designators(x, array, n, &t));
|
||||
|
||||
ASSERT_OK(image_policy_to_string(t, true, &s3));
|
||||
|
||||
log_info("%s → %s vs. %s", s1, s2, s3);
|
||||
|
||||
ASSERT_TRUE(image_policy_equivalent(t, y));
|
||||
}
|
||||
|
||||
TEST(image_policy_ignore_designators) {
|
||||
test_policy_ignore_designators_one("-", NULL, 0, "-");
|
||||
test_policy_ignore_designators_one("-", ((const PartitionDesignator[]) { PARTITION_ROOT }), 1, "-");
|
||||
test_policy_ignore_designators_one("*", ((const PartitionDesignator[]) { PARTITION_ROOT }), 1, "root=ignore:=open");
|
||||
test_policy_ignore_designators_one("*", ((const PartitionDesignator[]) { PARTITION_ROOT, PARTITION_USR }), 2, "root=ignore:usr=ignore:=open");
|
||||
test_policy_ignore_designators_one("~", ((const PartitionDesignator[]) { PARTITION_VAR, PARTITION_ESP, PARTITION_VAR }), 2, "var=ignore:esp=ignore:=absent");
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
|
||||
Reference in New Issue
Block a user