From 19ce38ce620f54e71bebad1c47e186289da48afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Jan 2020 22:55:48 +0100 Subject: [PATCH 1/2] shared/gpt: export gpt_partition_type_uuid_{to,from}_string functions --- src/partition/repart.c | 70 --------------------------------------- src/shared/gpt.c | 74 ++++++++++++++++++++++++++++++++++++++++++ src/shared/gpt.h | 8 +++++ src/shared/meson.build | 1 + 4 files changed, 83 insertions(+), 70 deletions(-) create mode 100644 src/shared/gpt.c diff --git a/src/partition/repart.c b/src/partition/repart.c index 9844de59610..58fb9c7c5d3 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -818,76 +818,6 @@ static void context_place_partitions(Context *context) { } } -typedef struct GptPartitionType { - sd_id128_t uuid; - const char *name; -} GptPartitionType; - -static const GptPartitionType gpt_partition_type_table[] = { - { GPT_ROOT_X86, "root-x86" }, - { GPT_ROOT_X86_VERITY, "root-x86-verity" }, - { GPT_ROOT_X86_64, "root-x86-64" }, - { GPT_ROOT_X86_64_VERITY, "root-x86-64-verity" }, - { GPT_ROOT_ARM, "root-arm" }, - { GPT_ROOT_ARM_VERITY, "root-arm-verity" }, - { GPT_ROOT_ARM_64, "root-arm64" }, - { GPT_ROOT_ARM_64_VERITY, "root-arm64-verity" }, - { GPT_ROOT_IA64, "root-ia64" }, - { GPT_ROOT_IA64_VERITY, "root-ia64-verity" }, -#ifdef GPT_ROOT_NATIVE - { GPT_ROOT_NATIVE, "root" }, - { GPT_ROOT_NATIVE_VERITY, "root-verity" }, -#endif -#ifdef GPT_ROOT_SECONDARY - { GPT_ROOT_SECONDARY, "root-secondary" }, - { GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity" }, -#endif - { GPT_ESP, "esp" }, - { GPT_XBOOTLDR, "xbootldr" }, - { GPT_SWAP, "swap" }, - { GPT_HOME, "home" }, - { GPT_SRV, "srv" }, - { GPT_VAR, "var" }, - { GPT_TMP, "tmp" }, - { GPT_LINUX_GENERIC, "linux-generic", }, -}; - -static const char *gpt_partition_type_uuid_to_string(sd_id128_t id) { - for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++) - if (sd_id128_equal(id, gpt_partition_type_table[i].uuid)) - return gpt_partition_type_table[i].name; - - return NULL; -} - -static const char *gpt_partition_type_uuid_to_string_harder( - sd_id128_t id, - char buffer[static ID128_UUID_STRING_MAX]) { - - const char *s; - - assert(buffer); - - s = gpt_partition_type_uuid_to_string(id); - if (s) - return s; - - return id128_to_uuid_string(id, buffer); -} - -static int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) { - assert(s); - assert(ret); - - for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++) - if (streq(s, gpt_partition_type_table[i].name)) { - *ret = gpt_partition_type_table[i].uuid; - return 0; - } - - return sd_id128_from_string(s, ret); -} - static int config_parse_type( const char *unit, const char *filename, diff --git a/src/shared/gpt.c b/src/shared/gpt.c new file mode 100644 index 00000000000..024f4db515b --- /dev/null +++ b/src/shared/gpt.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "gpt.h" +#include "string-util.h" + +typedef struct GptPartitionType { + sd_id128_t uuid; + const char *name; +} GptPartitionType; + +static const GptPartitionType gpt_partition_type_table[] = { + { GPT_ROOT_X86, "root-x86" }, + { GPT_ROOT_X86_VERITY, "root-x86-verity" }, + { GPT_ROOT_X86_64, "root-x86-64" }, + { GPT_ROOT_X86_64_VERITY, "root-x86-64-verity" }, + { GPT_ROOT_ARM, "root-arm" }, + { GPT_ROOT_ARM_VERITY, "root-arm-verity" }, + { GPT_ROOT_ARM_64, "root-arm64" }, + { GPT_ROOT_ARM_64_VERITY, "root-arm64-verity" }, + { GPT_ROOT_IA64, "root-ia64" }, + { GPT_ROOT_IA64_VERITY, "root-ia64-verity" }, +#ifdef GPT_ROOT_NATIVE + { GPT_ROOT_NATIVE, "root" }, + { GPT_ROOT_NATIVE_VERITY, "root-verity" }, +#endif +#ifdef GPT_ROOT_SECONDARY + { GPT_ROOT_SECONDARY, "root-secondary" }, + { GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity" }, +#endif + { GPT_ESP, "esp" }, + { GPT_XBOOTLDR, "xbootldr" }, + { GPT_SWAP, "swap" }, + { GPT_HOME, "home" }, + { GPT_SRV, "srv" }, + { GPT_VAR, "var" }, + { GPT_TMP, "tmp" }, + { GPT_LINUX_GENERIC, "linux-generic", }, +}; + +const char *gpt_partition_type_uuid_to_string(sd_id128_t id) { + for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++) + if (sd_id128_equal(id, gpt_partition_type_table[i].uuid)) + return gpt_partition_type_table[i].name; + + return NULL; +} + +const char *gpt_partition_type_uuid_to_string_harder( + sd_id128_t id, + char buffer[static ID128_UUID_STRING_MAX]) { + + const char *s; + + assert(buffer); + + s = gpt_partition_type_uuid_to_string(id); + if (s) + return s; + + return id128_to_uuid_string(id, buffer); +} + +int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) { + assert(s); + assert(ret); + + for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++) + if (streq(s, gpt_partition_type_table[i].name)) { + *ret = gpt_partition_type_table[i].uuid; + return 0; + } + + return sd_id128_from_string(s, ret); +} diff --git a/src/shared/gpt.h b/src/shared/gpt.h index 8e9b111857c..a07bd630172 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -5,6 +5,8 @@ #include "sd-id128.h" +#include "id128-util.h" + /* We only support root disk discovery for x86, x86-64, Itanium and ARM for * now, since EFI for anything else doesn't really exist, and we only * care for root partitions on the same disk as the EFI ESP. */ @@ -65,3 +67,9 @@ #define GPT_FLAG_NO_AUTO (1ULL << 63) #define GPT_LINUX_GENERIC SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4) + +const char *gpt_partition_type_uuid_to_string(sd_id128_t id); +const char *gpt_partition_type_uuid_to_string_harder( + sd_id128_t id, + char buffer[static ID128_UUID_STRING_MAX]); +int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret); diff --git a/src/shared/meson.build b/src/shared/meson.build index a7320fc4ed6..f51f4ee1f46 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -85,6 +85,7 @@ shared_sources = files(''' fstab-util.h generator.c generator.h + gpt.c gpt.h group-record-nss.c group-record-nss.h From dc972b0740714a9798fed0e20bc78efa0c5ad9a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 17 Jan 2020 11:34:13 +0100 Subject: [PATCH 2/2] systemd-id128: add new verb to print GPT partitions UUIDs --- docs/DISCOVERABLE_PARTITIONS.md | 3 ++ man/systemd-id128.xml | 4 ++ src/id128/id128.c | 86 ++++++++++++++++++++++++++++++++- src/shared/gpt.c | 12 ++--- src/shared/gpt.h | 7 +++ src/shared/id128-print.c | 42 ++++++++-------- src/shared/id128-print.h | 1 + 7 files changed, 127 insertions(+), 28 deletions(-) diff --git a/docs/DISCOVERABLE_PARTITIONS.md b/docs/DISCOVERABLE_PARTITIONS.md index 8b1a7b46e3e..f1537b89399 100644 --- a/docs/DISCOVERABLE_PARTITIONS.md +++ b/docs/DISCOVERABLE_PARTITIONS.md @@ -64,6 +64,9 @@ Other GPT type IDs might be used on Linux, for example to mark software RAID or LVM partitions. The definitions of those GPT types is outside of the scope of this specification. +[systemd-id128(1)](http://www.freedesktop.org/software/systemd/man/systemd-i128.html) +may be used to list those UUIDs. + ## Partition Names For partitions of the types listed above it is recommended to use diff --git a/man/systemd-id128.xml b/man/systemd-id128.xml index a5ab31ad6df..747b7036532 100644 --- a/man/systemd-id128.xml +++ b/man/systemd-id128.xml @@ -73,6 +73,10 @@ will be printed. This is available in systemd services. See systemd.exec5. + + With show, well-known UUIDs are printed. When no arguments are specified, all + known UUIDs are shown. When arguments are specified, they must be the names or values of one or more + known UUIDs, which are then printed. diff --git a/src/id128/id128.c b/src/id128/id128.c index cd4d5414503..de74bac2c07 100644 --- a/src/id128/id128.c +++ b/src/id128/id128.c @@ -4,9 +4,12 @@ #include #include "alloc-util.h" +#include "gpt.h" #include "id128-print.h" #include "main-func.h" #include "pretty-print.h" +#include "strv.h" +#include "format-table.h" #include "terminal-util.h" #include "util.h" #include "verbs.h" @@ -63,6 +66,85 @@ static int verb_invocation_id(int argc, char **argv, void *userdata) { return id128_pretty_print(id, arg_mode); } +static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first) { + int r; + + if (arg_mode == ID128_PRINT_PRETTY) { + _cleanup_free_ char *id = NULL; + + id = strreplace(name, "-", "_"); + if (!id) + return log_oom(); + + ascii_strupper(id); + + r = id128_pretty_print_sample(id, uuid); + if (r < 0) + return r; + if (!first) + puts(""); + return 0; + + } else { + if (!*table) { + *table = table_new("name", "uuid"); + if (!*table) + return log_oom(); + table_set_width(*table, 0); + } + + return table_add_many(*table, + TABLE_STRING, name, + arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID, + uuid); + } +} + +static int verb_show(int argc, char **argv, void *userdata) { + _cleanup_(table_unrefp) Table *table = NULL; + char **p; + int r; + + argv = strv_skip(argv, 1); + if (strv_isempty(argv)) + for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) { + r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table); + if (r < 0) + return r; + } + else + STRV_FOREACH(p, argv) { + sd_id128_t uuid; + bool have_uuid; + const char *id; + + /* Check if the argument is an actual UUID first */ + have_uuid = sd_id128_from_string(*p, &uuid) >= 0; + + if (have_uuid) + id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ"; + else { + r = gpt_partition_type_uuid_from_string(*p, &uuid); + if (r < 0) + return log_error_errno(r, "Unknown identifier \"%s\".", *p); + + id = *p; + } + + r = show_one(&table, id, uuid, p == argv); + if (r < 0) + return r; + } + + if (table) { + r = table_print(table, NULL); + if (r < 0) + return log_error_errno(r, "Failed to print table: %m"); + } + + return 0; +} + static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -74,10 +156,11 @@ static int help(void) { printf("%s [OPTIONS...] COMMAND\n\n" "%sGenerate and print 128bit identifiers.%s\n" "\nCommands:\n" - " new Generate a new id128 string\n" + " new Generate a new ID\n" " machine-id Print the ID of current machine\n" " boot-id Print the ID of current boot\n" " invocation-id Print the ID of current invocation\n" + " show [NAME] Print one or more well-known IDs\n" " help Show this help\n" "\nOptions:\n" " -h --help Show this help\n" @@ -155,6 +238,7 @@ static int id128_main(int argc, char *argv[]) { { "machine-id", VERB_ANY, 1, 0, verb_machine_id }, { "boot-id", VERB_ANY, 1, 0, verb_boot_id }, { "invocation-id", VERB_ANY, 1, 0, verb_invocation_id }, + { "show", VERB_ANY, VERB_ANY, 0, verb_show }, { "help", VERB_ANY, VERB_ANY, 0, verb_help }, {} }; diff --git a/src/shared/gpt.c b/src/shared/gpt.c index 024f4db515b..e62f21e889c 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -3,12 +3,7 @@ #include "gpt.h" #include "string-util.h" -typedef struct GptPartitionType { - sd_id128_t uuid; - const char *name; -} GptPartitionType; - -static const GptPartitionType gpt_partition_type_table[] = { +const GptPartitionType gpt_partition_type_table[] = { { GPT_ROOT_X86, "root-x86" }, { GPT_ROOT_X86_VERITY, "root-x86-verity" }, { GPT_ROOT_X86_64, "root-x86-64" }, @@ -35,10 +30,11 @@ static const GptPartitionType gpt_partition_type_table[] = { { GPT_VAR, "var" }, { GPT_TMP, "tmp" }, { GPT_LINUX_GENERIC, "linux-generic", }, + {} }; const char *gpt_partition_type_uuid_to_string(sd_id128_t id) { - for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++) + for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++) if (sd_id128_equal(id, gpt_partition_type_table[i].uuid)) return gpt_partition_type_table[i].name; @@ -64,7 +60,7 @@ int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) { assert(s); assert(ret); - for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++) + for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++) if (streq(s, gpt_partition_type_table[i].name)) { *ret = gpt_partition_type_table[i].uuid; return 0; diff --git a/src/shared/gpt.h b/src/shared/gpt.h index a07bd630172..dcceb076d6e 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -73,3 +73,10 @@ const char *gpt_partition_type_uuid_to_string_harder( sd_id128_t id, char buffer[static ID128_UUID_STRING_MAX]); int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret); + +typedef struct GptPartitionType { + sd_id128_t uuid; + const char *name; +} GptPartitionType; + +extern const GptPartitionType gpt_partition_type_table[]; diff --git a/src/shared/id128-print.c b/src/shared/id128-print.c index 356f4105078..6237424e824 100644 --- a/src/shared/id128-print.c +++ b/src/shared/id128-print.c @@ -10,24 +10,11 @@ #include "pretty-print.h" #include "terminal-util.h" -int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) { - _cleanup_free_ char *man_link = NULL, *mod_link = NULL; +int id128_pretty_print_sample(const char *name, sd_id128_t id) { + _cleanup_free_ char *man_link = NULL, *mod_link = NULL; const char *on, *off; unsigned i; - assert(mode >= 0); - assert(mode < _ID128_PRETTY_PRINT_MODE_MAX); - - if (mode == ID128_PRINT_ID128) { - printf(SD_ID128_FORMAT_STR "\n", - SD_ID128_FORMAT_VAL(id)); - return 0; - } else if (mode == ID128_PRINT_UUID) { - printf(SD_ID128_UUID_FORMAT_STR "\n", - SD_ID128_FORMAT_VAL(id)); - return 0; - } - on = ansi_highlight(); off = ansi_normal(); @@ -42,24 +29,41 @@ int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) { "As UUID:\n" "%s" SD_ID128_UUID_FORMAT_STR "%s\n\n" "As %s macro:\n" - "%s#define XYZ SD_ID128_MAKE(", + "%s#define %s SD_ID128_MAKE(", on, SD_ID128_FORMAT_VAL(id), off, on, SD_ID128_FORMAT_VAL(id), off, man_link, - on); + on, name); for (i = 0; i < 16; i++) printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); printf(")%s\n\n", off); printf("As Python constant:\n" ">>> import %s\n" - ">>> %sXYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n", + ">>> %s%s = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n", mod_link, - on, SD_ID128_FORMAT_VAL(id), off); + on, name, SD_ID128_FORMAT_VAL(id), off); return 0; } + +int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) { + assert(mode >= 0); + assert(mode < _ID128_PRETTY_PRINT_MODE_MAX); + + if (mode == ID128_PRINT_ID128) { + printf(SD_ID128_FORMAT_STR "\n", + SD_ID128_FORMAT_VAL(id)); + return 0; + } else if (mode == ID128_PRINT_UUID) { + printf(SD_ID128_UUID_FORMAT_STR "\n", + SD_ID128_FORMAT_VAL(id)); + return 0; + } else + return id128_pretty_print_sample("XYZ", id); +} + int id128_print_new(Id128PrettyPrintMode mode) { sd_id128_t id; int r; diff --git a/src/shared/id128-print.h b/src/shared/id128-print.h index 1dc5b6aae57..247558231c9 100644 --- a/src/shared/id128-print.h +++ b/src/shared/id128-print.h @@ -14,5 +14,6 @@ typedef enum Id128PrettyPrintMode { _ID128_PRETTY_PRINT_MODE_INVALID = -1 } Id128PrettyPrintMode; +int id128_pretty_print_sample(const char *name, sd_id128_t id); int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode); int id128_print_new(Id128PrettyPrintMode mode);