summaryrefslogtreecommitdiffstats
path: root/src/shared/bootspec.h
blob: 0be254e1065e61106058ad6cc7770b5fe29b1f29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#pragma once

#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/types.h>

#include "sd-json.h"

#include "set.h"
#include "string-util.h"

typedef enum BootEntryType {
        BOOT_ENTRY_CONF,        /* Boot Loader Specification Type #1 entries: *.conf files */
        BOOT_ENTRY_UNIFIED,     /* Boot Loader Specification Type #2 entries: *.efi files */
        BOOT_ENTRY_LOADER,      /* Additional entries augmented from LoaderEntries EFI variable (regular entries) */
        BOOT_ENTRY_LOADER_AUTO, /* Additional entries augmented from LoaderEntries EFI variable (special "automatic" entries) */
        _BOOT_ENTRY_TYPE_MAX,
        _BOOT_ENTRY_TYPE_INVALID = -EINVAL,
} BootEntryType;

typedef struct BootEntryAddon {
        char *location;
        char *cmdline;
} BootEntryAddon;

typedef struct BootEntryAddons {
        BootEntryAddon *items;
        size_t n_items;
} BootEntryAddons;

BootEntryAddon* boot_entry_addon_free(BootEntryAddon *t);

typedef struct BootEntry {
        BootEntryType type;
        bool reported_by_loader;
        char *id;       /* This is the file basename (including extension!) */
        char *id_old;   /* Old-style ID, for deduplication purposes. */
        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 *sort_key;
        char *version;
        char *machine_id;
        char *architecture;
        char **options;
        BootEntryAddons local_addons;
        char *kernel;        /* linux is #defined to 1, yikes! */
        char *efi;
        char **initrd;
        char *device_tree;
        char **device_tree_overlay;
        unsigned tries_left;
        unsigned tries_done;
} BootEntry;

#define BOOT_ENTRY_INIT(t)                      \
        {                                       \
                .type = (t),                    \
                .tries_left = UINT_MAX,         \
                .tries_done = UINT_MAX,         \
        }

typedef struct BootConfig {
        char *default_pattern;

        char *entry_oneshot;
        char *entry_default;
        char *entry_selected;

        BootEntry *entries;
        size_t n_entries;

        BootEntryAddons global_addons;

        ssize_t default_entry;
        ssize_t selected_entry;

        Set *inodes_seen;
} BootConfig;

#define BOOT_CONFIG_NULL              \
        {                             \
                .default_entry = -1,  \
                .selected_entry = -1, \
        }

const char* boot_entry_type_to_string(BootEntryType);
const char* boot_entry_type_json_to_string(BootEntryType);

BootEntry* boot_config_find_entry(BootConfig *config, const char *id);

static inline const BootEntry* boot_config_default_entry(const BootConfig *config) {
        assert(config);

        if (config->default_entry < 0)
                return NULL;

        assert((size_t) config->default_entry < config->n_entries);
        return config->entries + config->default_entry;
}

void boot_config_free(BootConfig *config);

int boot_loader_read_conf(BootConfig *config, FILE *file, const char *path);

int boot_config_load_type1(
                BootConfig *config,
                FILE *f,
                const char *root,
                const char *dir,
                const char *id);

int boot_config_finalize(BootConfig *config);
int boot_config_load(BootConfig *config, const char *esp_path, const char *xbootldr_path);
int boot_config_load_auto(BootConfig *config, const char *override_esp_path, const char *override_xbootldr_path);
int boot_config_augment_from_loader(BootConfig *config, char **list, bool only_auto);

int boot_config_select_special_entries(BootConfig *config, bool skip_efivars);

static inline const char* boot_entry_title(const BootEntry *entry) {
        assert(entry);

        return ASSERT_PTR(entry->show_title ?: entry->title ?: entry->id);
}

int show_boot_entry(
                const BootEntry *e,
                const BootEntryAddons *global_addons,
                bool show_as_default,
                bool show_as_selected,
                bool show_reported);
int show_boot_entries(
                const BootConfig *config,
                sd_json_format_flags_t json_format);

int boot_filename_extract_tries(const char *fname, char **ret_stripped, unsigned *ret_tries_left, unsigned *ret_tries_done);

int boot_entry_to_json(const BootConfig *c, size_t i, sd_json_variant **ret);