From e0a41aa4c6674f04723388c05b7cd81cc2ffd613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Apr 2021 15:09:22 +0200 Subject: [PATCH 1/5] man: dedent examples in sd-id128 to 2 columns In man pages, horizontal space it at premium, and everything should generally be indented with 2 spaces to make it more likely that the examples fit on a user's screen. C.f. 798d3a524ea57aaf40cb53858aaa45ec702f012d. --- man/sd-id128.xml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/man/sd-id128.xml b/man/sd-id128.xml index 40a3cc59ae..2005cd19db 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -65,8 +65,8 @@ union type: typedef union sd_id128 { - uint8_t bytes[16]; - uint64_t qwords[2]; + uint8_t bytes[16]; + uint64_t qwords[2]; } sd_id128_t; This union type allows accessing the 128-bit ID as 16 @@ -95,7 +95,7 @@ #define SD_MESSAGE_COREDUMP_STR SD_ID128_MAKE_STR(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) int main(int argc, char **argv) { - puts("Match for coredumps: MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR); + puts("Match for coredumps: MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR); } @@ -104,7 +104,7 @@ int main(int argc, char **argv) { following example code will output the string "fc2e22bc6ee647b6b90729ab34a250b1": int main(int argc, char *argv[]) { - puts("Match for coredumps: %s", SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP)); + puts("Match for coredumps: %s", SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP)); } SD_ID128_FORMAT_STR and SD_ID128_FORMAT_VAL() may @@ -113,10 +113,10 @@ int main(int argc, char **argv) { format string, as shown in the following example: int main(int argc, char *argv[]) { - sd_id128_t id; - id = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); - printf("The ID encoded in this C file is " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(id)); - return 0; + sd_id128_t id; + id = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); + printf("The ID encoded in this C file is " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(id)); + return 0; } SD_ID128_UUID_FORMAT_STR is similar to @@ -127,20 +127,20 @@ int main(int argc, char **argv) { Use sd_id128_equal() to compare two 128-bit IDs: int main(int argc, char *argv[]) { - sd_id128_t a, b, c; - a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); - b = SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e); - c = a; - assert(sd_id128_equal(a, c)); - assert(!sd_id128_equal(a, b)); - return 0; + sd_id128_t a, b, c; + a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); + b = SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e); + c = a; + assert(sd_id128_equal(a, c)); + assert(!sd_id128_equal(a, b)); + return 0; } Use sd_id128_is_null() to check if an 128bit ID consists of only NUL bytes: int main(int argc, char *argv[]) { - assert(sd_id128_is_null(SD_ID128_NULL)); + assert(sd_id128_is_null(SD_ID128_NULL)); } Note that new, randomized IDs may be generated with From 78aa5b6f59f1787bcd509f8070f82ae72add0fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Apr 2021 15:33:09 +0200 Subject: [PATCH 2/5] man: mention sd_id128_is_allf(), SD_ID128_ALLF It was added in 670814387ba8973245c08123e7240669f51a55a8, but not mentioned in the man pages. --- man/rules/meson.build | 4 +++- man/sd-id128.xml | 23 ++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/man/rules/meson.build b/man/rules/meson.build index 7ef26cb2c6..c21f1b6b4c 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -119,7 +119,8 @@ manpages = [ ['sd-hwdb', '3', [], ''], ['sd-id128', '3', - ['SD_ID128_CONST_STR', + ['SD_ID128_ALLF', + 'SD_ID128_CONST_STR', 'SD_ID128_FORMAT_STR', 'SD_ID128_FORMAT_VAL', 'SD_ID128_MAKE', @@ -127,6 +128,7 @@ manpages = [ 'SD_ID128_NULL', 'SD_ID128_UUID_FORMAT_STR', 'sd_id128_equal', + 'sd_id128_is_allf', 'sd_id128_is_null', 'sd_id128_t'], ''], diff --git a/man/sd-id128.xml b/man/sd-id128.xml index 2005cd19db..c448d60a94 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -18,16 +18,18 @@ sd-id128 - sd_id128_t + SD_ID128_ALLF + SD_ID128_CONST_STR + SD_ID128_FORMAT_STR + SD_ID128_FORMAT_VAL SD_ID128_MAKE SD_ID128_MAKE_STR SD_ID128_NULL - SD_ID128_CONST_STR - SD_ID128_FORMAT_STR SD_ID128_UUID_FORMAT_STR - SD_ID128_FORMAT_VAL sd_id128_equal + sd_id128_is_allf sd_id128_is_null + sd_id128_t APIs for processing 128-bit IDs @@ -85,7 +87,7 @@ #define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) - SD_ID128_NULL may be used to refer to the 128bit ID consisting of only + SD_ID128_NULL may be used to refer to the 128-bit ID consisting of only NUL bytes. SD_ID128_MAKE_STR() is similar to SD_ID128_MAKE(), but creates a @@ -136,12 +138,15 @@ int main(int argc, char **argv) { return 0; } - Use sd_id128_is_null() to check if an 128bit ID consists of only + Use sd_id128_is_null() to check if an 128-bit ID consists of only NUL bytes: - int main(int argc, char *argv[]) { - assert(sd_id128_is_null(SD_ID128_NULL)); -} + assert(sd_id128_is_null(SD_ID128_NULL)); + + Similarly, use sd_id128_is_allf() to check if an 128-bit ID consists of only + 0xFF bytes (all bits on): + + assert(sd_id128_is_allf(SD_ID128_ALLF)); Note that new, randomized IDs may be generated with systemd-id1281's From 64b21afc727deb5a0702563dcbe4baba9cf5bd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Apr 2021 15:36:10 +0200 Subject: [PATCH 3/5] sd-id128: add convenience functions to compare multiple sd_id128_t Similar to sd_bus_error_has_names() that was added in 2b07ec316a0e25a3e10c270c7f6baee9e0187bf8. It is made inline in the hope that the compiler will be able to optimize all the va_args boilerplate away, and do an efficient comparison when the arguments are all constants. --- man/rules/meson.build | 3 +++ man/sd-id128.xml | 29 +++++++++++++++++++++++++++++ src/systemd/sd-id128.h | 27 +++++++++++++++++++++++++++ src/test/test-id128.c | 7 +++++++ 4 files changed, 66 insertions(+) diff --git a/man/rules/meson.build b/man/rules/meson.build index c21f1b6b4c..05b087db3e 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -128,6 +128,9 @@ manpages = [ 'SD_ID128_NULL', 'SD_ID128_UUID_FORMAT_STR', 'sd_id128_equal', + 'sd_id128_in_set', + 'sd_id128_in_set_sentinel', + 'sd_id128_in_setv', 'sd_id128_is_allf', 'sd_id128_is_null', 'sd_id128_t'], diff --git a/man/sd-id128.xml b/man/sd-id128.xml index c448d60a94..1890f6d6a5 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -27,6 +27,9 @@ SD_ID128_NULL SD_ID128_UUID_FORMAT_STR sd_id128_equal + sd_id128_in_set + sd_id128_in_set_sentinel + sd_id128_in_setv sd_id128_is_allf sd_id128_is_null sd_id128_t @@ -148,6 +151,32 @@ int main(int argc, char **argv) { assert(sd_id128_is_allf(SD_ID128_ALLF)); + For convenience, sd_id128_in_set() takes a list of IDs and + returns true if any are equal to the first argument: + + int main(int argc, char *argv[]) { + sd_id12_t a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); + assert(sd_id128_in_set(a, a)); + assert(sd_id128_in_set(a, a, a)); + assert(!sd_id128_in_set(a)); + assert(!sd_id128_in_set(a, + SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e) + SD_ID128_MAKE(2f,88,28,5f,9c,44,09,9d,d7,15,77,04,bc,85,7e,e3) + SD_ID128_ALLF)); + return 0; +} + + + sd_id128_in_set() is defined as a macro over + sd_id128_in_set_sentinel(), adding the SD_ID128_NULL + sentinel. Since sd_id128_in_set_sentinel() uses SD_ID128_NULL + as the sentinel, SD_ID128_NULL cannot be otherwise placed in the argument list. + + + sd_id128_in_setv() is similar to + sd_id128_in_set_sentinel(), but takes a struct varargs + argument. + Note that new, randomized IDs may be generated with systemd-id1281's new command. diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h index 02aa318a06..ab209c8c7d 100644 --- a/src/systemd/sd-id128.h +++ b/src/systemd/sd-id128.h @@ -18,6 +18,7 @@ ***/ #include +#include #include #include "_sd-common.h" @@ -119,6 +120,32 @@ _sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) { #define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) #define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }}) +_sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) { + for (;;) { + sd_id128_t b = va_arg(ap, sd_id128_t); + + if (sd_id128_is_null(b)) + return 0; + + if (sd_id128_equal(a, b)) + return 1; + } +} + +_sd_pure_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) { + va_list ap; + int r; + + va_start(ap, a); + r = sd_id128_in_setv(a, ap); + va_end(ap); + + return r; +} + +#define sd_id128_in_set(a, ...) \ + sd_id128_in_set_sentinel(a, ##__VA_ARGS__, SD_ID128_NULL) + _SD_END_DECLARATIONS; #endif diff --git a/src/test/test-id128.c b/src/test/test-id128.c index a0649b9deb..a61b35b9a3 100644 --- a/src/test/test-id128.c +++ b/src/test/test-id128.c @@ -31,6 +31,13 @@ int main(int argc, char *argv[]) { assert_se(sd_id128_from_string(t, &id2) == 0); assert_se(sd_id128_equal(id, id2)); + assert_se(sd_id128_in_set(id, id)); + assert_se(sd_id128_in_set(id, id2)); + assert_se(sd_id128_in_set(id, id2, id)); + assert_se(sd_id128_in_set(id, ID128_WALDI, id)); + assert_se(!sd_id128_in_set(id)); + assert_se(!sd_id128_in_set(id, ID128_WALDI)); + assert_se(!sd_id128_in_set(id, ID128_WALDI, ID128_WALDI)); if (sd_booted() > 0) { assert_se(sd_id128_get_machine(&id) == 0); From 580f48cc024681f8e018278d6807e5481501fac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Apr 2021 15:42:05 +0200 Subject: [PATCH 4/5] partition,shared/gpt: use sd_id128_in_set() I was worried that the text size will grow, but apparently that's not the case: With --optimization=2: $ size build/src/shared/libsystemd-shared-248.a.p/gpt.c.o* text data bss dec hex filename 3674 1104 0 4778 12aa build/src/shared/libsystemd-shared-248.a.p/gpt.c.o.old 3085 1104 0 4189 105d build/src/shared/libsystemd-shared-248.a.p/gpt.c.o (I don't understand the generated assembly, even though it seems to work: Disassembly of section .text.gpt_partition_type_is_usr_verity: 0000000000000000 : bool gpt_partition_type_is_usr_verity(sd_id128_t id) { 0: 48 83 ec 08 sub $0x8,%rsp return sd_id128_in_set(id, 4: 4c 8b 05 00 00 00 00 mov 0x0(%rip),%r8 # b b: 31 c0 xor %eax,%eax d: 4c 8b 0d 00 00 00 00 mov 0x0(%rip),%r9 # 14 14: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 1b 1b: 48 8b 0d 00 00 00 00 mov 0x0(%rip),%rcx # 22 22: 6a 00 pushq $0x0 24: 6a 00 pushq $0x0 26: ff 35 00 00 00 00 pushq 0x0(%rip) # 2c 2c: ff 35 00 00 00 00 pushq 0x0(%rip) # 32 32: ff 35 00 00 00 00 pushq 0x0(%rip) # 38 38: ff 35 00 00 00 00 pushq 0x0(%rip) # 3e 3e: ff 35 00 00 00 00 pushq 0x0(%rip) # 44 44: ff 35 00 00 00 00 pushq 0x0(%rip) # 4a 4a: ff 35 00 00 00 00 pushq 0x0(%rip) # 50 50: ff 35 00 00 00 00 pushq 0x0(%rip) # 56 56: ff 35 00 00 00 00 pushq 0x0(%rip) # 5c 5c: ff 35 00 00 00 00 pushq 0x0(%rip) # 62 62: e8 00 00 00 00 callq 67 67: 85 c0 test %eax,%eax 69: 0f 95 c0 setne %al GPT_USR_ARM_VERITY, GPT_USR_ARM_64_VERITY, GPT_USR_IA64_VERITY, GPT_USR_RISCV32_VERITY, GPT_USR_RISCV64_VERITY); } 6c: 48 83 c4 68 add $0x68,%rsp 70: c3 retq ) --- src/partition/repart.c | 3 +- src/shared/gpt.c | 69 ++++++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/partition/repart.c b/src/partition/repart.c index 356fd9152c..38e65195ac 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -3115,8 +3115,7 @@ static int partition_acquire_uuid(Context *context, Partition *p, sd_id128_t *re if (p == q) continue; - if (sd_id128_equal(q->current_uuid, result.id) || - sd_id128_equal(q->new_uuid, result.id)) { + if (sd_id128_in_set(result.id, q->current_uuid, q->new_uuid)) { log_warning("Partition UUID calculated from seed for partition %" PRIu64 " exists already, reverting to randomized UUID.", p->partno); r = sd_id128_randomize(&result.id); diff --git a/src/shared/gpt.c b/src/shared/gpt.c index 846b2fe48f..6b1a576138 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -108,52 +108,57 @@ int gpt_partition_label_valid(const char *s) { } bool gpt_partition_type_is_root(sd_id128_t id) { - return sd_id128_equal(id, GPT_ROOT_X86) || - sd_id128_equal(id, GPT_ROOT_X86_64) || - sd_id128_equal(id, GPT_ROOT_ARM) || - sd_id128_equal(id, GPT_ROOT_ARM_64) || - sd_id128_equal(id, GPT_ROOT_IA64) || - sd_id128_equal(id, GPT_ROOT_RISCV32) || - sd_id128_equal(id, GPT_ROOT_RISCV64); + return sd_id128_in_set(id, + GPT_ROOT_X86, + GPT_ROOT_X86_64, + GPT_ROOT_ARM, + GPT_ROOT_ARM_64, + GPT_ROOT_IA64, + GPT_ROOT_RISCV32, + GPT_ROOT_RISCV64); } bool gpt_partition_type_is_root_verity(sd_id128_t id) { - return sd_id128_equal(id, GPT_ROOT_X86_VERITY) || - sd_id128_equal(id, GPT_ROOT_X86_64_VERITY) || - sd_id128_equal(id, GPT_ROOT_ARM_VERITY) || - sd_id128_equal(id, GPT_ROOT_ARM_64_VERITY) || - sd_id128_equal(id, GPT_ROOT_IA64_VERITY) || - sd_id128_equal(id, GPT_ROOT_RISCV32_VERITY) || - sd_id128_equal(id, GPT_ROOT_RISCV64_VERITY); + return sd_id128_in_set(id, + GPT_ROOT_X86_VERITY, + GPT_ROOT_X86_64_VERITY, + GPT_ROOT_ARM_VERITY, + GPT_ROOT_ARM_64_VERITY, + GPT_ROOT_IA64_VERITY, + GPT_ROOT_RISCV32_VERITY, + GPT_ROOT_RISCV64_VERITY); } bool gpt_partition_type_is_usr(sd_id128_t id) { - return sd_id128_equal(id, GPT_USR_X86) || - sd_id128_equal(id, GPT_USR_X86_64) || - sd_id128_equal(id, GPT_USR_ARM) || - sd_id128_equal(id, GPT_USR_ARM_64) || - sd_id128_equal(id, GPT_USR_IA64) || - sd_id128_equal(id, GPT_USR_RISCV32) || - sd_id128_equal(id, GPT_USR_RISCV64); + return sd_id128_in_set(id, + GPT_USR_X86, + GPT_USR_X86_64, + GPT_USR_ARM, + GPT_USR_ARM_64, + GPT_USR_IA64, + GPT_USR_RISCV32, + GPT_USR_RISCV64); } bool gpt_partition_type_is_usr_verity(sd_id128_t id) { - return sd_id128_equal(id, GPT_USR_X86_VERITY) || - sd_id128_equal(id, GPT_USR_X86_64_VERITY) || - sd_id128_equal(id, GPT_USR_ARM_VERITY) || - sd_id128_equal(id, GPT_USR_ARM_64_VERITY) || - sd_id128_equal(id, GPT_USR_IA64_VERITY) || - sd_id128_equal(id, GPT_USR_RISCV32_VERITY) || - sd_id128_equal(id, GPT_USR_RISCV64_VERITY); + return sd_id128_in_set(id, + GPT_USR_X86_VERITY, + GPT_USR_X86_64_VERITY, + GPT_USR_ARM_VERITY, + GPT_USR_ARM_64_VERITY, + GPT_USR_IA64_VERITY, + GPT_USR_RISCV32_VERITY, + GPT_USR_RISCV64_VERITY); } bool gpt_partition_type_knows_read_only(sd_id128_t id) { return gpt_partition_type_is_root(id) || gpt_partition_type_is_usr(id) || - sd_id128_equal(id, GPT_HOME) || - sd_id128_equal(id, GPT_SRV) || - sd_id128_equal(id, GPT_VAR) || - sd_id128_equal(id, GPT_TMP) || + sd_id128_in_set(id, + GPT_HOME, + GPT_SRV, + GPT_VAR, + GPT_TMP) || gpt_partition_type_is_root_verity(id) || /* pretty much implied, but let's set the bit to make things really clear */ gpt_partition_type_is_usr_verity(id); /* ditto */ } From da1af43dc1e11c723275aaf53588ec150dfc6c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Apr 2021 15:43:01 +0200 Subject: [PATCH 5/5] repart: reword log message The UUID does not exist, a partion with the UUID exists. So let's say that the UUID is "already used" for clarity. --- src/partition/repart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/partition/repart.c b/src/partition/repart.c index 38e65195ac..3e88d38205 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -3116,7 +3116,7 @@ static int partition_acquire_uuid(Context *context, Partition *p, sd_id128_t *re continue; if (sd_id128_in_set(result.id, q->current_uuid, q->new_uuid)) { - log_warning("Partition UUID calculated from seed for partition %" PRIu64 " exists already, reverting to randomized UUID.", p->partno); + log_warning("Partition UUID calculated from seed for partition %" PRIu64 " already used, reverting to randomized UUID.", p->partno); r = sd_id128_randomize(&result.id); if (r < 0)