sd_bus_error *error) {
_cleanup_free_ char *v = NULL;
+ Manager *m = userdata;
+ const char *x = NULL;
int r;
assert(bus);
assert(reply);
- assert(userdata);
+ assert(m);
r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY");
if (r == -ENXIO) {
/* EFI case: let's read the LoaderEntryOneShot variable */
- r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &v);
+ r = efi_loader_update_entry_one_shot_cache(&m->efi_loader_entry_one_shot, &m->efi_loader_entry_one_shot_stat);
if (r < 0) {
if (r != -ENOENT)
- log_warning_errno(r, "Failed to read LoaderEntryOneShot variable: %m");
- } else if (!efi_loader_entry_name_valid(v)) {
- log_warning("LoaderEntryOneShot contains invalid entry name '%s', ignoring.", v);
- v = mfree(v);
- }
+ log_warning_errno(r, "Failed to read LoaderEntryOneShot variable, ignoring: %m");
+ } else
+ x = m->efi_loader_entry_one_shot;
+
} else if (r < 0)
log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY: %m");
else if (r > 0) {
r = read_one_line_file("/run/systemd/reboot-to-boot-loader-entry", &v);
if (r < 0) {
if (r != -ENOENT)
- log_warning_errno(r, "Failed to read /run/systemd/reboot-to-boot-loader-entry: %m");
- } else if (!efi_loader_entry_name_valid(v)) {
+ log_warning_errno(r, "Failed to read /run/systemd/reboot-to-boot-loader-entry, ignoring: %m");
+ } else if (!efi_loader_entry_name_valid(v))
log_warning("/run/systemd/reboot-to-boot-loader-entry is not valid, ignoring.");
- v = mfree(v);
- }
+ else
+ x = v;
}
- return sd_bus_message_append(reply, "s", v);
+ return sd_bus_message_append(reply, "s", x);
}
static int boot_loader_entry_exists(Manager *m, const char *id) {
*ret = cache = sec * USEC_PER_SEC; /* return in µs */
return 0;
}
+
+int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat) {
+ _cleanup_free_ char *fn = NULL, *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)
+ return -errno;
+
+ if (stat_inode_unmodified(&new_stat, cache_stat))
+ return 0;
+
+ r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &v);
+ if (r < 0)
+ return r;
+
+ if (!efi_loader_entry_name_valid(v))
+ return -EINVAL;
+
+ *cache_stat = new_stat;
+ free_and_replace(*cache, v);
+
+ return 0;
+}
#include "efivars.h"
+#include <sys/stat.h>
+
#if ENABLE_EFI
int efi_reboot_to_firmware_supported(void);
int efi_loader_get_features(uint64_t *ret);
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);
#else
return -EOPNOTSUPP;
}
+static inline int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat) {
+ return -EOPNOTSUPP;
+}
+
#endif
bool efi_loader_entry_name_valid(const char *s);