free(entry->id);
free(entry->path);
+ free(entry->root);
free(entry->title);
free(entry->show_title);
free(entry->version);
free(entry->device_tree);
}
-static int boot_entry_load(const char *path, BootEntry *entry) {
+static int boot_entry_load(
+ const char *root,
+ const char *path,
+ BootEntry *entry) {
+
_cleanup_(boot_entry_free) BootEntry tmp = {};
_cleanup_fclose_ FILE *f = NULL;
unsigned line = 1;
char *b, *c;
int r;
+ assert(root);
assert(path);
assert(entry);
if (!tmp.path)
return log_oom();
+ tmp.root = strdup(root);
+ if (!tmp.root)
+ return log_oom();
+
f = fopen(path, "re");
if (!f)
return log_error_errno(errno, "Failed to open \"%s\": %m", path);
return str_verscmp(a->id, b->id);
}
-static int boot_entries_find(const char *dir, BootEntry **ret_entries, size_t *ret_n_entries) {
+static int boot_entries_find(
+ const char *root,
+ const char *dir,
+ BootEntry **ret_entries,
+ size_t *ret_n_entries) {
+
_cleanup_strv_free_ char **files = NULL;
char **f;
int r;
BootEntry *array = NULL;
size_t n_allocated = 0, n = 0;
+ assert(root);
assert(dir);
assert(ret_entries);
assert(ret_n_entries);
if (!GREEDY_REALLOC0(array, n_allocated, n + 1))
return log_oom();
- r = boot_entry_load(*f, array + n);
+ r = boot_entry_load(root, *f, array + n);
if (r < 0)
continue;
return r;
p = strjoina(esp_path, "/loader/entries");
- r = boot_entries_find(p, &config->entries, &config->n_entries);
+ r = boot_entries_find(esp_path, p, &config->entries, &config->n_entries);
if (r < 0)
return r;
int find_default_boot_entry(
const char *esp_path,
- char **esp_where,
BootConfig *config,
const BootEntry **e) {
*e = &config->entries[config->default_entry];
log_debug("Found default boot entry in file \"%s\"", (*e)->path);
- if (esp_where)
- *esp_where = TAKE_PTR(where);
-
return 0;
}
typedef struct BootEntry {
char *id; /* This is the file basename without extension */
- char *path; /* This is the full path to the file */
+ char *path; /* This is the full path to the drop-in file */
+ char *root; /* The root path in which the drop-in was found, i.e. to which 'kernel', 'efi' and 'initrd' are relative */
char *title;
char *show_title;
char *version;
int find_esp_and_warn(const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid);
int find_xbootldr_and_warn(const char *path, bool unprivileged_mode, char **ret_path,sd_id128_t *ret_uuid);
-int find_default_boot_entry(const char *esp_path, char **esp_where, BootConfig *config, const BootEntry **e);
+int find_default_boot_entry(const char *esp_path, BootConfig *config, const BootEntry **e);
static int load_kexec_kernel(void) {
_cleanup_(boot_config_free) BootConfig config = {};
- _cleanup_free_ char *where = NULL, *kernel = NULL, *initrd = NULL, *options = NULL;
+ _cleanup_free_ char *kernel = NULL, *initrd = NULL, *options = NULL;
const BootEntry *e;
pid_t pid;
int r;
if (access(KEXEC, X_OK) < 0)
return log_error_errno(errno, KEXEC" is not available: %m");
- r = find_default_boot_entry(arg_esp_path, &where, &config, &e);
+ r = find_default_boot_entry(arg_esp_path, &config, &e);
if (r == -ENOKEY) /* find_default_boot_entry() doesn't warn about this case */
return log_error_errno(r, "Cannot find the ESP partition mount point.");
if (r < 0)
return -EINVAL;
}
- kernel = path_join(where, e->kernel);
+ kernel = path_join(e->root, e->kernel);
if (!strv_isempty(e->initrd))
- initrd = path_join(where, *e->initrd);
+ initrd = path_join(e->root, *e->initrd);
options = strv_join(e->options, " ");
if (!options)
return log_oom();