basic/efivars: replace dynanamic creation of efivar names with static strings

Creating those string dynamically at runtime is slow and unnecessary.
Let's use static strings with a bit of macro magic and the let the compiler
coalesce as much as possible.

$ size build/src/shared/libsystemd-shared-248.so{.old,}
   text	   data	    bss	    dec	    hex	filename
2813453	  94572	   4584	2912609	 2c7161	build/src/shared/libsystemd-shared-248.so.old
2812309	  94564	   4584	2911457	 2c6ce1	build/src/shared/libsystemd-shared-248.so

A nice side-effect is that the same form is used everywhere, so it's easier to
figure out all variables that are used, and where each specific variable is
used.

C.f. 2b0445262a.

Note: 'const char *foo = alloca(…);' seems OK. Our coding style document and
alloca(3) only warn against using alloca() in function invocations. Declaring
both stack variable and alloca at the same time should be fine: no matter in
which order they happen, i.e. if the pointer variable is above the contents,
or the contents are above the pointer, or even if the pointer is elided by the
compiler, everything should be fine.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2021-06-15 22:01:42 +02:00
parent 7c7683f36c
commit e6f055cbc4
10 changed files with 141 additions and 183 deletions
+3 -3
View File
@@ -677,14 +677,14 @@ int boot_entries_load_config(
return log_error_errno(r, "Failed to uniquify boot entries: %m");
if (is_efi_boot()) {
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &config->entry_oneshot);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryOneShot), &config->entry_oneshot);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntryOneShot\": %m");
if (r == -ENOMEM)
return r;
}
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryDefault", &config->entry_default);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryDefault), &config->entry_default);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntryDefault\": %m");
if (r == -ENOMEM)
@@ -776,7 +776,7 @@ int boot_entries_augment_from_loader(
break;
}
p = efi_variable_path(EFI_VENDOR_LOADER, "LoaderEntries");
p = strdup(EFIVAR_PATH(EFI_LOADER_VARIABLE(LoaderEntries)));
if (!p)
return log_oom();
+33 -46
View File
@@ -82,7 +82,7 @@ int efi_reboot_to_firmware_supported(void) {
if (!is_efi_boot())
goto not_supported;
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
r = efi_get_variable(EFI_GLOBAL_VARIABLE(OsIndicationsSupported), NULL, &v, &s);
if (r == -ENOENT)
goto not_supported; /* variable doesn't exist? it's not supported then */
if (r < 0)
@@ -105,7 +105,6 @@ not_supported:
static int get_os_indications(uint64_t *ret) {
static struct stat cache_stat = {};
_cleanup_free_ void *v = NULL;
_cleanup_free_ char *fn = NULL;
static uint64_t cache;
struct stat new_stat;
size_t s;
@@ -118,12 +117,8 @@ static int get_os_indications(uint64_t *ret) {
if (r < 0)
return r;
fn = efi_variable_path(EFI_VENDOR_GLOBAL, "OsIndications");
if (!fn)
return -ENOMEM;
/* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
if (stat(fn, &new_stat) < 0) {
if (stat(EFIVAR_PATH(EFI_GLOBAL_VARIABLE(OsIndications)), &new_stat) < 0) {
if (errno != ENOENT)
return -errno;
@@ -137,7 +132,7 @@ static int get_os_indications(uint64_t *ret) {
return 0;
}
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndications", NULL, &v, &s);
r = efi_get_variable(EFI_GLOBAL_VARIABLE(OsIndications), NULL, &v, &s);
if (r == -ENOENT) {
/* Some firmware implementations that do support OsIndications and report that with
* OsIndicationsSupported will remove the OsIndications variable when it is unset. Let's
@@ -180,7 +175,7 @@ int efi_set_reboot_to_firmware(bool value) {
/* Avoid writing to efi vars store if we can due to firmware bugs. */
if (b != b_new)
return efi_set_variable(EFI_VENDOR_GLOBAL, "OsIndications", &b_new, sizeof(uint64_t));
return efi_set_variable(EFI_GLOBAL_VARIABLE(OsIndications), &b_new, sizeof(uint64_t));
return 0;
}
@@ -235,7 +230,7 @@ int efi_get_boot_option(
char **path,
bool *active) {
char boot_id[9];
char variable[STRLEN(EFI_GLOBAL_VARIABLE_STR("Boot")) + 4 + 1];
_cleanup_free_ uint8_t *buf = NULL;
size_t l;
struct boot_option *header;
@@ -247,8 +242,8 @@ int efi_get_boot_option(
if (!is_efi_boot())
return -EOPNOTSUPP;
xsprintf(boot_id, "Boot%04X", id);
r = efi_get_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, (void **)&buf, &l);
xsprintf(variable, EFI_GLOBAL_VARIABLE_STR("Boot%04X"), id);
r = efi_get_variable(variable, NULL, (void **)&buf, &l);
if (r < 0)
return r;
if (l < offsetof(struct boot_option, title))
@@ -372,7 +367,7 @@ int efi_add_boot_option(
_cleanup_free_ char *buf = NULL;
struct boot_option *option;
struct device_path *devicep;
char boot_id[9];
char variable[STRLEN(EFI_GLOBAL_VARIABLE_STR("Boot")) + 4 + 1];
if (!is_efi_boot())
return -EOPNOTSUPP;
@@ -424,18 +419,18 @@ int efi_add_boot_option(
devicep->length = offsetof(struct device_path, path);
size += devicep->length;
xsprintf(boot_id, "Boot%04X", id);
return efi_set_variable(EFI_VENDOR_GLOBAL, boot_id, buf, size);
xsprintf(variable, EFI_GLOBAL_VARIABLE_STR("Boot%04X"), id);
return efi_set_variable(variable, buf, size);
}
int efi_remove_boot_option(uint16_t id) {
char boot_id[9];
char variable[STRLEN(EFI_GLOBAL_VARIABLE_STR("Boot")) + 4 + 1];
if (!is_efi_boot())
return -EOPNOTSUPP;
xsprintf(boot_id, "Boot%04X", id);
return efi_set_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, 0);
xsprintf(variable, EFI_GLOBAL_VARIABLE_STR("Boot%04X"), id);
return efi_set_variable(variable, NULL, 0);
}
int efi_get_boot_order(uint16_t **order) {
@@ -446,7 +441,7 @@ int efi_get_boot_order(uint16_t **order) {
if (!is_efi_boot())
return -EOPNOTSUPP;
r = efi_get_variable(EFI_VENDOR_GLOBAL, "BootOrder", NULL, &buf, &l);
r = efi_get_variable(EFI_GLOBAL_VARIABLE(BootOrder), NULL, &buf, &l);
if (r < 0)
return r;
@@ -466,7 +461,7 @@ int efi_set_boot_order(uint16_t *order, size_t n) {
if (!is_efi_boot())
return -EOPNOTSUPP;
return efi_set_variable(EFI_VENDOR_GLOBAL, "BootOrder", order, n * sizeof(uint16_t));
return efi_set_variable(EFI_GLOBAL_VARIABLE(BootOrder), order, n * sizeof(uint16_t));
}
static int boot_id_hex(const char s[static 4]) {
@@ -500,7 +495,7 @@ int efi_get_boot_options(uint16_t **options) {
if (!is_efi_boot())
return -EOPNOTSUPP;
dir = opendir("/sys/firmware/efi/efivars/");
dir = opendir(EFIVAR_PATH("."));
if (!dir)
return -errno;
@@ -513,7 +508,7 @@ int efi_get_boot_options(uint16_t **options) {
if (strlen(de->d_name) != 45)
continue;
if (strcmp(de->d_name + 8, "-8be4df61-93ca-11d2-aa0d-00e098032b8c") != 0)
if (strcmp(de->d_name + 8, EFI_GLOBAL_VARIABLE_STR("")) != 0) /* generate variable suffix using macro */
continue;
id = boot_id_hex(de->d_name + 4);
@@ -533,15 +528,15 @@ int efi_get_boot_options(uint16_t **options) {
return count;
}
static int read_usec(sd_id128_t vendor, const char *name, usec_t *u) {
static int read_usec(const char *variable, usec_t *u) {
_cleanup_free_ char *j = NULL;
int r;
uint64_t x = 0;
assert(name);
assert(variable);
assert(u);
r = efi_get_variable_string(EFI_VENDOR_LOADER, name, &j);
r = efi_get_variable_string(variable, &j);
if (r < 0)
return r;
@@ -563,11 +558,11 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
if (!is_efi_boot())
return -EOPNOTSUPP;
r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeInitUSec", &x);
r = read_usec(EFI_LOADER_VARIABLE(LoaderTimeInitUSec), &x);
if (r < 0)
return log_debug_errno(r, "Failed to read LoaderTimeInitUSec: %m");
r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeExecUSec", &y);
r = read_usec(EFI_LOADER_VARIABLE(LoaderTimeExecUSec), &y);
if (r < 0)
return log_debug_errno(r, "Failed to read LoaderTimeExecUSec: %m");
@@ -589,7 +584,7 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) {
if (!is_efi_boot())
return -EOPNOTSUPP;
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderDevicePartUUID", &p);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderDevicePartUUID), &p);
if (r < 0)
return r;
@@ -621,7 +616,7 @@ int efi_loader_get_entries(char ***ret) {
if (!is_efi_boot())
return -EOPNOTSUPP;
r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderEntries", NULL, (void**) &entries, &size);
r = efi_get_variable(EFI_LOADER_VARIABLE(LoaderEntries), NULL, (void**) &entries, &size);
if (r < 0)
return r;
@@ -673,12 +668,12 @@ int efi_loader_get_features(uint64_t *ret) {
return 0;
}
r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderFeatures", NULL, &v, &s);
r = efi_get_variable(EFI_LOADER_VARIABLE(LoaderFeatures), NULL, &v, &s);
if (r == -ENOENT) {
_cleanup_free_ char *info = NULL;
/* The new (v240+) LoaderFeatures variable is not supported, let's see if it's systemd-boot at all */
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderInfo), &info);
if (r < 0) {
if (r != -ENOENT)
return r;
@@ -713,7 +708,7 @@ int efi_loader_get_features(uint64_t *ret) {
}
int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
_cleanup_free_ char *v = NULL, *fn = NULL;
_cleanup_free_ char *v = NULL;
static struct stat cache_stat = {};
struct stat new_stat;
static usec_t cache;
@@ -722,12 +717,8 @@ int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
assert(ret);
fn = efi_variable_path(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot");
if (!fn)
return -ENOMEM;
/* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
if (stat(fn, &new_stat) < 0)
/* stat() the EFI variable, to see if the mtime changed. If it did, we need to cache again. */
if (stat(EFIVAR_PATH(EFI_LOADER_VARIABLE(LoaderConfigTimeoutOneShot)), &new_stat) < 0)
return -errno;
if (stat_inode_unmodified(&new_stat, &cache_stat)) {
@@ -735,7 +726,7 @@ int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
return 0;
}
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot", &v);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderConfigTimeoutOneShot), &v);
if (r < 0)
return r;
@@ -751,25 +742,21 @@ int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
}
int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat) {
_cleanup_free_ char *fn = NULL, *v = NULL;
_cleanup_free_ char *v = NULL;
struct stat new_stat;
int r;
assert(cache);
assert(cache_stat);
fn = efi_variable_path(EFI_VENDOR_LOADER, "LoaderEntryOneShot");
if (!fn)
return -ENOMEM;
/* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
if (stat(fn, &new_stat) < 0)
if (stat(EFIVAR_PATH(EFI_LOADER_VARIABLE(LoaderEntryOneShot)), &new_stat) < 0)
return -errno;
if (stat_inode_unmodified(&new_stat, cache_stat))
return 0;
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &v);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryOneShot), &v);
if (r < 0)
return r;