]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootspec: store 'root' field in each bootspec entry we load
authorLennart Poettering <lennart@poettering.net>
Mon, 28 Jan 2019 16:57:41 +0000 (17:57 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 1 Mar 2019 11:41:32 +0000 (12:41 +0100)
This 'root' field contains the root path of the partition we found the
snippet in. The 'kernel', 'initrd', 'efi', … fields are relative to this
path.

This becomes particularly useful later when we add support for loading
snippets from both the ESP and XBOOTLDR, but already simplifies the code
for us a bit in systemctl.

src/shared/bootspec.c
src/shared/bootspec.h
src/systemctl/systemctl.c

index 5715c94d686cd8bd100c30f8979c51b0601c54ba..c662e890684cf9c4a9aeae0478dd0df844483984 100644 (file)
@@ -27,6 +27,7 @@ static void boot_entry_free(BootEntry *entry) {
 
         free(entry->id);
         free(entry->path);
+        free(entry->root);
         free(entry->title);
         free(entry->show_title);
         free(entry->version);
@@ -39,13 +40,18 @@ static void boot_entry_free(BootEntry *entry) {
         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);
 
@@ -62,6 +68,10 @@ static int boot_entry_load(const char *path, BootEntry *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);
@@ -215,13 +225,19 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
         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);
@@ -234,7 +250,7 @@ static int boot_entries_find(const char *dir, BootEntry **ret_entries, size_t *r
                 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;
 
@@ -369,7 +385,7 @@ int boot_entries_load_config(const char *esp_path, BootConfig *config) {
                 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;
 
@@ -799,7 +815,6 @@ found:
 
 int find_default_boot_entry(
                 const char *esp_path,
-                char **esp_where,
                 BootConfig *config,
                 const BootEntry **e) {
 
@@ -824,8 +839,5 @@ int find_default_boot_entry(
         *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;
 }
index 8a22fd5cdd40f5b2e5326050a6ba3bfd5c4d17cd..0fac051398a5f5b32a1832c1e0eb7a62e1716bbc 100644 (file)
@@ -10,7 +10,8 @@
 
 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;
@@ -49,4 +50,4 @@ static inline const char* boot_entry_title(const BootEntry *entry) {
 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);
index 63dae2c87285667bc833206bacb83989b4d22fe1..6900f61e9e563f8f0aa71b5f4008b71fd05771b1 100644 (file)
@@ -3519,7 +3519,7 @@ static int prepare_firmware_setup(void) {
 
 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;
@@ -3532,7 +3532,7 @@ static int load_kexec_kernel(void) {
         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)
@@ -3544,9 +3544,9 @@ static int load_kexec_kernel(void) {
                 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();