efi: rework find_esp() error propagation/logging a bit

This renames find_esp() to find_esp_and_warn() and tries to normalize its
behaviour:

1. Change the error that is returned when we can't find the ESP to
   ENOKEY (from ENOENT). This way the error code can only mean one
   thing: that our search loop didn't find a good candidate.
2. Really log about all errors, except for ENOKEY and EACCES, and
   document the letter cases.
3. Normalize parameters to the call: separate out the path parameter in
   two: an input path and an output path. That way the memory management
   is clear: we will access the input parameter only for reading, and
   only write out the output parameter, using malloc() memory.
   Before the calling convention were quire surprising for internal API
   code, as the path parameter had to be malloc() memory and might and
   might not have changed.
4. Rename bootctl's find_esp_warn() to acquire_esp(), and make it a
   simple wrapper around find_esp_warn(), that basically just adds the
   friendly logging for the ENOKEY case. This rework removes double
   logging in a number of error cases, as we no longer log here in
   anything but ENOKEY, and leave that entirely to find_esp_warn().
5. find_esp_and_warn() now takes a bool flag parameter
   "unprivileged_mode", which disables logging in the EACCES case, and
   skips privileged validation of the path. This makes the function less
   magic, and doesn't hide this internal silencing automatism from the
   caller anymore.

With all that in place "bootctl list" and "bootctl status" work properly
(or as good as they can) when I invoke the tools whithout privileges on
my system where /boot is not world-readable
This commit is contained in:
Lennart Poettering
2017-12-11 23:18:56 +01:00
parent 4a0e9289bf
commit 5caa3167ff
4 changed files with 99 additions and 51 deletions
+10 -9
View File
@@ -3497,7 +3497,7 @@ static int prepare_firmware_setup(void) {
static int load_kexec_kernel(void) {
_cleanup_(boot_config_free) BootConfig config = {};
_cleanup_free_ char *kernel = NULL, *initrd = NULL, *options = NULL;
_cleanup_free_ char *where = NULL, *kernel = NULL, *initrd = NULL, *options = NULL;
const BootEntry *e;
pid_t pid;
int r;
@@ -3507,14 +3507,15 @@ static int load_kexec_kernel(void) {
return 0;
}
r = find_esp(&arg_esp_path, NULL, NULL, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Cannot find the ESP partition mount point: %m");
r = find_esp_and_warn(arg_esp_path, false, &where, NULL, NULL, NULL, NULL);
if (r == -ENOKEY) /* find_esp_and_warn() doesn't warn about this case */
return log_error_errno(r, "Cannot find the ESP partition mount point.");
if (r < 0) /* But it logs about all these cases, hence don't log here again */
return r;
r = boot_entries_load_config(arg_esp_path, &config);
r = boot_entries_load_config(where, &config);
if (r < 0)
return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m",
arg_esp_path);
return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m", where);
if (config.default_entry < 0) {
log_error("No entry suitable as default, refusing to guess.");
@@ -3527,9 +3528,9 @@ static int load_kexec_kernel(void) {
return -EINVAL;
}
kernel = path_join(NULL, arg_esp_path, e->kernel);
kernel = path_join(NULL, where, e->kernel);
if (!strv_isempty(e->initrd))
initrd = path_join(NULL, arg_esp_path, *e->initrd);
initrd = path_join(NULL, where, *e->initrd);
options = strv_join(e->options, " ");
if (!options)
return log_oom();