systemd-id128: add new verb to print GPT partitions UUIDs

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-01-17 11:34:13 +01:00
parent 19ce38ce62
commit dc972b0740
7 changed files with 127 additions and 28 deletions

View File

@ -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

View File

@ -73,6 +73,10 @@
will be printed. This is available in systemd services. See
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
<para>With <command>show</command>, 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.</para>
</refsect1>
<refsect1>

View File

@ -4,9 +4,12 @@
#include <stdio.h>
#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 },
{}
};

View File

@ -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;

View File

@ -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[];

View File

@ -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;

View File

@ -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);