mirror of
https://github.com/systemd/systemd
synced 2026-03-25 16:25:04 +01:00
Compare commits
No commits in common. "8908ceb7a855eabf5739dc15932ee1d41a0bc93c" and "ced10d48380369c5a3b43037bc00e54ac7fe27b5" have entirely different histories.
8908ceb7a8
...
ced10d4838
@ -41,8 +41,8 @@
|
||||
a comment line. Empty and comment lines are ignored.</para>
|
||||
|
||||
<para>Boolean arguments may be written as
|
||||
<literal>yes</literal>/<literal>y</literal>/<literal>true</literal>/<literal>t</literal>/<literal>on</literal>/<literal>1</literal> or
|
||||
<literal>no</literal>/<literal>n</literal>/<literal>false</literal>/<literal>f</literal>/<literal>off</literal>/<literal>0</literal>.
|
||||
<literal>yes</literal>/<literal>y</literal>/<literal>true</literal>/<literal>1</literal> or
|
||||
<literal>no</literal>/<literal>n</literal>/<literal>false</literal>/<literal>0</literal>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@ -744,18 +744,6 @@ Service b@0.service not loaded, b.socket cannot be started.
|
||||
generators enabled will generally result in some warnings.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--recursive-errors=<replaceable>MODE</replaceable></option></term>
|
||||
|
||||
<listitem><para>Control verification of units and their dependencies and whether
|
||||
<command>systemd-analyze verify</command> exits with a non-zero process exit status or not. With
|
||||
<command>yes</command>, return a non-zero process exit status when warnings arise during verification
|
||||
of either the specified unit or any of its associated dependencies. This is the default. With
|
||||
<command>no</command>, return a non-zero process exit status when warnings arise during verification
|
||||
of only the specified unit. With <command>one</command>, return a non-zero process exit status when
|
||||
warnings arise during verification of either the specified unit or its immediate dependencies. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--root=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
|
||||
@ -345,7 +345,6 @@ possible_common_cc_flags = [
|
||||
'-Werror=shift-count-overflow',
|
||||
'-Werror=shift-overflow=2',
|
||||
'-Werror=undef',
|
||||
'-Werror=unused-function',
|
||||
'-Wfloat-equal',
|
||||
'-Wimplicit-fallthrough=5',
|
||||
'-Winit-self',
|
||||
|
||||
@ -125,7 +125,7 @@ _systemd_analyze() {
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[VERIFY]}; then
|
||||
if [[ $cur = -* ]]; then
|
||||
comps='--help --version --system --user --global --man=no --generators=yes --root --image --recursive-errors=no --recursive-errors=yes --recursive-errors=one'
|
||||
comps='--help --version --system --user --global --man=no --generators=yes --root --image'
|
||||
else
|
||||
comps=$( compgen -A file -- "$cur" )
|
||||
compopt -o filenames
|
||||
|
||||
@ -89,7 +89,6 @@ _arguments \
|
||||
'--global[Show global user instance config]' \
|
||||
'--root=[Add support for root argument]:PATH' \
|
||||
'--image=[Add support for discrete images]:PATH' \
|
||||
'--recursive-errors=[When verifying a unit, control dependency verification]:MODE' \
|
||||
'--no-pager[Do not pipe output into a pager]' \
|
||||
'--man=[Do (not) check for existence of man pages]:boolean:(1 0)' \
|
||||
'--order[When generating graph for dot, show only order]' \
|
||||
|
||||
@ -11,28 +11,10 @@
|
||||
#include "manager.h"
|
||||
#include "pager.h"
|
||||
#include "path-util.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "unit-serialize.h"
|
||||
|
||||
static void log_syntax_callback(const char *unit, int level, void *userdata) {
|
||||
Set **s = userdata;
|
||||
int r;
|
||||
|
||||
assert(userdata);
|
||||
assert(unit);
|
||||
|
||||
if (level > LOG_WARNING)
|
||||
return;
|
||||
|
||||
r = set_put_strdup(s, unit);
|
||||
if (r < 0) {
|
||||
set_free_free(*s);
|
||||
*s = POINTER_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static int prepare_filename(const char *filename, char **ret) {
|
||||
int r;
|
||||
const char *name;
|
||||
@ -236,22 +218,13 @@ static int verify_unit(Unit *u, bool check_man, const char *root) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static void set_destroy_ignore_pointer_max(Set** s) {
|
||||
if (*s == POINTER_MAX)
|
||||
return;
|
||||
set_free_free(*s);
|
||||
}
|
||||
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root) {
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root) {
|
||||
const ManagerTestRunFlags flags =
|
||||
MANAGER_TEST_RUN_MINIMAL |
|
||||
MANAGER_TEST_RUN_ENV_GENERATORS |
|
||||
(recursive_errors == RECURSIVE_ERRORS_NO) * MANAGER_TEST_RUN_IGNORE_DEPENDENCIES |
|
||||
run_generators * MANAGER_TEST_RUN_GENERATORS;
|
||||
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
_cleanup_(set_destroy_ignore_pointer_max) Set *s = NULL;
|
||||
_unused_ _cleanup_(clear_log_syntax_callback) dummy_t dummy;
|
||||
Unit *units[strv_length(filenames)];
|
||||
_cleanup_free_ char *var = NULL;
|
||||
int r, k, i, count = 0;
|
||||
@ -260,11 +233,6 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
|
||||
if (strv_isempty(filenames))
|
||||
return 0;
|
||||
|
||||
/* Allow systemd-analyze to hook in a callback function so that it can get
|
||||
* all the required log data from the function itself without having to rely
|
||||
* on a global set variable for the same */
|
||||
set_log_syntax_callback(log_syntax_callback, &s);
|
||||
|
||||
/* set the path */
|
||||
r = generate_path(&var, filenames);
|
||||
if (r < 0)
|
||||
@ -315,34 +283,5 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
|
||||
r = k;
|
||||
}
|
||||
|
||||
if (s == POINTER_MAX)
|
||||
return log_oom();
|
||||
|
||||
if (set_isempty(s) || r != 0)
|
||||
return r;
|
||||
|
||||
/* If all previous verifications succeeded, then either the recursive parsing of all the
|
||||
* associated dependencies with RECURSIVE_ERRORS_YES or the parsing of the specified unit file
|
||||
* with RECURSIVE_ERRORS_NO must have yielded a syntax warning and hence, a non-empty set. */
|
||||
if (IN_SET(recursive_errors, RECURSIVE_ERRORS_YES, RECURSIVE_ERRORS_NO))
|
||||
return -ENOTRECOVERABLE;
|
||||
|
||||
/* If all previous verifications succeeded, then the non-empty set could have resulted from
|
||||
* a syntax warning encountered during the recursive parsing of the specified unit file and
|
||||
* its direct dependencies. Hence, search for any of the filenames in the set and if found,
|
||||
* return a non-zero process exit status. */
|
||||
if (recursive_errors == RECURSIVE_ERRORS_ONE)
|
||||
STRV_FOREACH(filename, filenames)
|
||||
if (set_contains(s, basename(*filename)))
|
||||
return -ENOTRECOVERABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* const recursive_errors_table[_RECURSIVE_ERRORS_MAX] = {
|
||||
[RECURSIVE_ERRORS_NO] = "no",
|
||||
[RECURSIVE_ERRORS_YES] = "yes",
|
||||
[RECURSIVE_ERRORS_ONE] = "one",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(recursive_errors, RecursiveErrors);
|
||||
|
||||
@ -6,16 +6,5 @@
|
||||
#include "execute.h"
|
||||
#include "path-lookup.h"
|
||||
|
||||
typedef enum RecursiveErrors {
|
||||
RECURSIVE_ERRORS_YES, /* Look for errors in all associated units */
|
||||
RECURSIVE_ERRORS_NO, /* Don't look for errors in any but the selected unit */
|
||||
RECURSIVE_ERRORS_ONE, /* Look for errors in the selected unit and its direct dependencies */
|
||||
_RECURSIVE_ERRORS_MAX,
|
||||
_RECURSIVE_ERRORS_INVALID = -EINVAL,
|
||||
} RecursiveErrors;
|
||||
|
||||
int verify_executable(Unit *u, const ExecCommand *exec, const char *root);
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root);
|
||||
|
||||
const char* recursive_errors_to_string(RecursiveErrors i) _const_;
|
||||
RecursiveErrors recursive_errors_from_string(const char *s) _pure_;
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root);
|
||||
|
||||
@ -46,7 +46,6 @@
|
||||
#endif
|
||||
#include "sort-util.h"
|
||||
#include "special.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
#include "strxcpyx.h"
|
||||
#include "terminal-util.h"
|
||||
@ -86,7 +85,6 @@ static PagerFlags arg_pager_flags = 0;
|
||||
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
|
||||
static const char *arg_host = NULL;
|
||||
static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
|
||||
static RecursiveErrors arg_recursive_errors = RECURSIVE_ERRORS_YES;
|
||||
static bool arg_man = true;
|
||||
static bool arg_generators = false;
|
||||
static char *arg_root = NULL;
|
||||
@ -2147,7 +2145,7 @@ static int do_condition(int argc, char *argv[], void *userdata) {
|
||||
}
|
||||
|
||||
static int do_verify(int argc, char *argv[], void *userdata) {
|
||||
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root);
|
||||
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_root);
|
||||
}
|
||||
|
||||
static int do_security(int argc, char *argv[], void *userdata) {
|
||||
@ -2182,32 +2180,25 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
"%sProfile systemd, show unit dependencies, check unit files.%s\n"
|
||||
"\nCommands:\n"
|
||||
" [time] Print time required to boot the machine\n"
|
||||
" blame Print list of running units ordered by\n"
|
||||
" time to init\n"
|
||||
" critical-chain [UNIT...] Print a tree of the time critical chain\n"
|
||||
" of units\n"
|
||||
" plot Output SVG graphic showing service\n"
|
||||
" initialization\n"
|
||||
" blame Print list of running units ordered by time to init\n"
|
||||
" critical-chain [UNIT...] Print a tree of the time critical chain of units\n"
|
||||
" plot Output SVG graphic showing service initialization\n"
|
||||
" dot [UNIT...] Output dependency graph in %s format\n"
|
||||
" dump Output state serialization of service\n"
|
||||
" manager\n"
|
||||
" dump Output state serialization of service manager\n"
|
||||
" cat-config Show configuration file and drop-ins\n"
|
||||
" unit-files List files and symlinks for units\n"
|
||||
" unit-paths List load directories for units\n"
|
||||
" exit-status [STATUS...] List exit status definitions\n"
|
||||
" capability [CAP...] List capability definitions\n"
|
||||
" syscall-filter [NAME...] Print list of syscalls in seccomp\n"
|
||||
" filter\n"
|
||||
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
|
||||
" condition CONDITION... Evaluate conditions and asserts\n"
|
||||
" verify FILE... Check unit files for correctness\n"
|
||||
" calendar SPEC... Validate repetitive calendar time\n"
|
||||
" events\n"
|
||||
" calendar SPEC... Validate repetitive calendar time events\n"
|
||||
" timestamp TIMESTAMP... Validate a timestamp\n"
|
||||
" timespan SPAN... Validate a time span\n"
|
||||
" security [UNIT...] Analyze security of unit\n"
|
||||
"\nOptions:\n"
|
||||
" -h --help Show this help\n"
|
||||
" --recursive-errors=MODE Control which units are verified\n"
|
||||
" --version Show package version\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --system Operate on system systemd instance\n"
|
||||
@ -2219,14 +2210,12 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" --require Show only requirement in the graph\n"
|
||||
" --from-pattern=GLOB Show only origins in the graph\n"
|
||||
" --to-pattern=GLOB Show only destinations in the graph\n"
|
||||
" --fuzz=SECONDS Also print services which finished SECONDS\n"
|
||||
" earlier than the latest in the branch\n"
|
||||
" --fuzz=SECONDS Also print services which finished SECONDS earlier\n"
|
||||
" than the latest in the branch\n"
|
||||
" --man[=BOOL] Do [not] check for existence of man pages\n"
|
||||
" --generators[=BOOL] Do [not] run unit generators\n"
|
||||
" (requires privileges)\n"
|
||||
" --generators[=BOOL] Do [not] run unit generators (requires privileges)\n"
|
||||
" --iterations=N Show the specified number of iterations\n"
|
||||
" --base-time=TIMESTAMP Calculate calendar times relative to\n"
|
||||
" specified time\n"
|
||||
" --base-time=TIMESTAMP Calculate calendar times relative to specified time\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
@ -2258,7 +2247,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_GENERATORS,
|
||||
ARG_ITERATIONS,
|
||||
ARG_BASE_TIME,
|
||||
ARG_RECURSIVE_ERRORS,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -2268,7 +2256,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "require", no_argument, NULL, ARG_REQUIRE },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
||||
{ "recursive-errors", required_argument, NULL, ARG_RECURSIVE_ERRORS },
|
||||
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "global", no_argument, NULL, ARG_GLOBAL },
|
||||
@ -2296,18 +2283,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case 'h':
|
||||
return help(0, NULL, NULL);
|
||||
|
||||
case ARG_RECURSIVE_ERRORS:
|
||||
if (streq(optarg, "help")) {
|
||||
DUMP_STRING_TABLE(recursive_errors, RecursiveErrors, _RECURSIVE_ERRORS_MAX);
|
||||
return 0;
|
||||
}
|
||||
r = recursive_errors_from_string(optarg);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Unknown mode passed to --recursive-errors='%s'.", optarg);
|
||||
|
||||
arg_recursive_errors = r;
|
||||
break;
|
||||
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
|
||||
@ -39,9 +39,6 @@
|
||||
|
||||
#define SNDBUF_SIZE (8*1024*1024)
|
||||
|
||||
static log_syntax_callback_t log_syntax_callback = NULL;
|
||||
static void *log_syntax_callback_userdata = NULL;
|
||||
|
||||
static LogTarget log_target = LOG_TARGET_CONSOLE;
|
||||
static int log_max_level = LOG_INFO;
|
||||
static int log_facility = LOG_DAEMON;
|
||||
@ -1344,14 +1341,6 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) {
|
||||
signal_to_string(si->ssi_signo));
|
||||
}
|
||||
|
||||
void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata) {
|
||||
assert(!log_syntax_callback || !cb);
|
||||
assert(!log_syntax_callback_userdata || !userdata);
|
||||
|
||||
log_syntax_callback = cb;
|
||||
log_syntax_callback_userdata = userdata;
|
||||
}
|
||||
|
||||
int log_syntax_internal(
|
||||
const char *unit,
|
||||
int level,
|
||||
@ -1363,9 +1352,6 @@ int log_syntax_internal(
|
||||
const char *func,
|
||||
const char *format, ...) {
|
||||
|
||||
if (log_syntax_callback)
|
||||
log_syntax_callback(unit, level, log_syntax_callback_userdata);
|
||||
|
||||
PROTECT_ERRNO;
|
||||
char buffer[LINE_MAX];
|
||||
va_list ap;
|
||||
|
||||
@ -32,15 +32,6 @@ typedef enum LogTarget{
|
||||
#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1)
|
||||
#define ERRNO_VALUE(val) (abs(val) & 255)
|
||||
|
||||
/* The callback function to be invoked when syntax warnings are seen
|
||||
* in the unit files. */
|
||||
typedef void (*log_syntax_callback_t)(const char *unit, int level, void *userdata);
|
||||
void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata);
|
||||
|
||||
static inline void clear_log_syntax_callback(dummy_t *dummy) {
|
||||
set_log_syntax_callback(/* cb= */ NULL, /* userdata= */ NULL);
|
||||
}
|
||||
|
||||
const char *log_target_to_string(LogTarget target) _const_;
|
||||
LogTarget log_target_from_string(const char *s) _pure_;
|
||||
void log_set_target(LogTarget target);
|
||||
|
||||
@ -23,12 +23,28 @@
|
||||
#define _packed_ __attribute__((__packed__))
|
||||
#define _malloc_ __attribute__((__malloc__))
|
||||
#define _weak_ __attribute__((__weak__))
|
||||
#define _likely_(x) (__builtin_expect(!!(x), 1))
|
||||
#define _unlikely_(x) (__builtin_expect(!!(x), 0))
|
||||
#define _public_ __attribute__((__visibility__("default")))
|
||||
#define _hidden_ __attribute__((__visibility__("hidden")))
|
||||
#define _weakref_(x) __attribute__((__weakref__(#x)))
|
||||
#define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
|
||||
#define _alignptr_ __attribute__((__aligned__(sizeof(void*))))
|
||||
#define _warn_unused_result_ __attribute__((__warn_unused_result__))
|
||||
#if __GNUC__ >= 7
|
||||
#define _fallthrough_ __attribute__((__fallthrough__))
|
||||
#else
|
||||
#define _fallthrough_
|
||||
#endif
|
||||
/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
|
||||
* compiler versions */
|
||||
#ifndef _noreturn_
|
||||
#if __STDC_VERSION__ >= 201112L
|
||||
#define _noreturn_ _Noreturn
|
||||
#else
|
||||
#define _noreturn_ __attribute__((__noreturn__))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_FEATURE_MEMORY_SANITIZER)
|
||||
# if defined(__has_feature)
|
||||
@ -193,6 +209,13 @@ static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) {
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
* STRLEN - return the length of a string literal, minus the trailing NUL byte.
|
||||
* Contrary to strlen(), this is a constant expression.
|
||||
* @x: a string literal.
|
||||
*/
|
||||
#define STRLEN(x) (sizeof(""x"") - 1U)
|
||||
|
||||
/*
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
* @ptr: the pointer to the member.
|
||||
@ -460,10 +483,4 @@ static inline size_t size_add(size_t x, size_t y) {
|
||||
return y >= SIZE_MAX - x ? SIZE_MAX : x + y;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int _empty[0];
|
||||
} dummy_t;
|
||||
|
||||
assert_cc(sizeof(dummy_t) == 0);
|
||||
|
||||
#include "log.h"
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "util.h"
|
||||
|
||||
void efi_assert(const char *expr, const char *file, unsigned line, const char *function) {
|
||||
log_error_stall(L"systemd-boot assertion '%a' failed at %a:%u, function %a(). Halting.", expr, file, line, function);
|
||||
for (;;)
|
||||
uefi_call_wrapper(BS->Stall, 1, 60 * 1000 * 1000);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -72,9 +72,6 @@ typedef struct {
|
||||
} Config;
|
||||
|
||||
static VOID cursor_left(UINTN *cursor, UINTN *first) {
|
||||
assert(cursor);
|
||||
assert(first);
|
||||
|
||||
if ((*cursor) > 0)
|
||||
(*cursor)--;
|
||||
else if ((*first) > 0)
|
||||
@ -87,9 +84,6 @@ static VOID cursor_right(
|
||||
UINTN x_max,
|
||||
UINTN len) {
|
||||
|
||||
assert(cursor);
|
||||
assert(first);
|
||||
|
||||
if ((*cursor)+1 < x_max)
|
||||
(*cursor)++;
|
||||
else if ((*first) + (*cursor) < len)
|
||||
@ -106,8 +100,6 @@ static BOOLEAN line_edit(
|
||||
UINTN size, len, first, cursor, clear;
|
||||
BOOLEAN exit, enter;
|
||||
|
||||
assert(line_out);
|
||||
|
||||
if (!line_in)
|
||||
line_in = L"";
|
||||
size = StrLen(line_in) + 1024;
|
||||
@ -142,7 +134,7 @@ static BOOLEAN line_edit(
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print);
|
||||
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos);
|
||||
|
||||
err = console_key_read(&key, 0);
|
||||
err = console_key_read(&key, TRUE);
|
||||
if (EFI_ERROR(err))
|
||||
continue;
|
||||
|
||||
@ -340,8 +332,6 @@ static BOOLEAN line_edit(
|
||||
}
|
||||
|
||||
static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
|
||||
assert(config);
|
||||
|
||||
if (key == 0)
|
||||
return -1;
|
||||
|
||||
@ -372,9 +362,6 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
_cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL;
|
||||
UINTN x, y;
|
||||
|
||||
assert(config);
|
||||
assert(loaded_image_path);
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK);
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
|
||||
@ -400,7 +387,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
Print(L"OsIndicationsSupported: %d\n", indvar);
|
||||
|
||||
Print(L"\n--- press key ---\n\n");
|
||||
console_key_read(&key, 0);
|
||||
console_key_read(&key, TRUE);
|
||||
|
||||
Print(L"timeout: %u\n", config->timeout_sec);
|
||||
if (config->timeout_sec_efivar >= 0)
|
||||
@ -445,7 +432,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
Print(L"LoaderEntryDefault: %s\n", defaultstr);
|
||||
|
||||
Print(L"\n--- press key ---\n\n");
|
||||
console_key_read(&key, 0);
|
||||
console_key_read(&key, TRUE);
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++) {
|
||||
ConfigEntry *entry;
|
||||
@ -495,7 +482,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
entry->path, entry->next_name);
|
||||
|
||||
Print(L"\n--- press key ---\n\n");
|
||||
console_key_read(&key, 0);
|
||||
console_key_read(&key, TRUE);
|
||||
}
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
@ -506,10 +493,6 @@ static BOOLEAN menu_run(
|
||||
ConfigEntry **chosen_entry,
|
||||
CHAR16 *loaded_image_path) {
|
||||
|
||||
assert(config);
|
||||
assert(chosen_entry);
|
||||
assert(loaded_image_path);
|
||||
|
||||
EFI_STATUS err;
|
||||
UINTN visible_max;
|
||||
UINTN idx_highlight;
|
||||
@ -526,10 +509,11 @@ static BOOLEAN menu_run(
|
||||
UINTN y_max;
|
||||
CHAR16 *status;
|
||||
CHAR16 *clearline;
|
||||
UINTN timeout_remain = config->timeout_sec;
|
||||
INTN timeout_remain;
|
||||
INT16 idx;
|
||||
BOOLEAN exit = FALSE;
|
||||
BOOLEAN run = TRUE;
|
||||
BOOLEAN wait = FALSE;
|
||||
|
||||
graphics_mode(FALSE);
|
||||
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
|
||||
@ -543,7 +527,7 @@ static BOOLEAN menu_run(
|
||||
err = console_set_mode(&config->console_mode, config->console_mode_change);
|
||||
if (EFI_ERROR(err)) {
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
log_error_stall(L"Error switching console mode to %lu: %r", (UINT64)config->console_mode, err);
|
||||
Print(L"Error switching console mode to %ld: %r.\r", (UINT64)config->console_mode, err);
|
||||
}
|
||||
} else
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
@ -554,6 +538,12 @@ static BOOLEAN menu_run(
|
||||
y_max = 25;
|
||||
}
|
||||
|
||||
/* we check 10 times per second for a keystroke */
|
||||
if (config->timeout_sec > 0)
|
||||
timeout_remain = config->timeout_sec * 10;
|
||||
else
|
||||
timeout_remain = -1;
|
||||
|
||||
idx_highlight = config->idx_default;
|
||||
idx_highlight_prev = 0;
|
||||
|
||||
@ -653,7 +643,7 @@ static BOOLEAN menu_run(
|
||||
|
||||
if (timeout_remain > 0) {
|
||||
FreePool(status);
|
||||
status = PoolPrint(L"Boot in %d s.", timeout_remain);
|
||||
status = PoolPrint(L"Boot in %d sec.", (timeout_remain + 5) / 10);
|
||||
}
|
||||
|
||||
/* print status at last line of screen */
|
||||
@ -674,18 +664,27 @@ static BOOLEAN menu_run(
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len);
|
||||
}
|
||||
|
||||
err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : 0);
|
||||
if (err == EFI_TIMEOUT) {
|
||||
timeout_remain--;
|
||||
err = console_key_read(&key, wait);
|
||||
if (EFI_ERROR(err)) {
|
||||
/* timeout reached */
|
||||
if (timeout_remain == 0) {
|
||||
exit = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* update status */
|
||||
/* sleep and update status */
|
||||
if (timeout_remain > 0) {
|
||||
uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
|
||||
timeout_remain--;
|
||||
continue;
|
||||
} else
|
||||
timeout_remain = 0;
|
||||
}
|
||||
|
||||
/* timeout disabled, wait for next key */
|
||||
wait = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
timeout_remain = -1;
|
||||
|
||||
/* clear status after keystroke */
|
||||
if (status) {
|
||||
@ -788,7 +787,7 @@ static BOOLEAN menu_run(
|
||||
config->timeout_sec_efivar,
|
||||
EFI_VARIABLE_NON_VOLATILE);
|
||||
if (config->timeout_sec_efivar > 0)
|
||||
status = PoolPrint(L"Menu timeout set to %d s.", config->timeout_sec_efivar);
|
||||
status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar);
|
||||
else
|
||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
} else if (config->timeout_sec_efivar <= 0){
|
||||
@ -796,7 +795,7 @@ static BOOLEAN menu_run(
|
||||
efivar_set(
|
||||
LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||
if (config->timeout_sec_config > 0)
|
||||
status = PoolPrint(L"Menu timeout of %d s is defined by configuration file.",
|
||||
status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.",
|
||||
config->timeout_sec_config);
|
||||
else
|
||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
@ -814,7 +813,7 @@ static BOOLEAN menu_run(
|
||||
config->timeout_sec_efivar,
|
||||
EFI_VARIABLE_NON_VOLATILE);
|
||||
if (config->timeout_sec_efivar > 0)
|
||||
status = PoolPrint(L"Menu timeout set to %d s.",
|
||||
status = PoolPrint(L"Menu timeout set to %d sec.",
|
||||
config->timeout_sec_efivar);
|
||||
else
|
||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
@ -885,9 +884,6 @@ static BOOLEAN menu_run(
|
||||
}
|
||||
|
||||
static VOID config_add_entry(Config *config, ConfigEntry *entry) {
|
||||
assert(config);
|
||||
assert(entry);
|
||||
|
||||
if ((config->entry_count & 15) == 0) {
|
||||
UINTN i;
|
||||
|
||||
@ -928,12 +924,6 @@ static CHAR8 *line_get_key_value(
|
||||
CHAR8 *line, *value;
|
||||
UINTN linelen;
|
||||
|
||||
assert(content);
|
||||
assert(sep);
|
||||
assert(pos);
|
||||
assert(key_ret);
|
||||
assert(value_ret);
|
||||
|
||||
skip:
|
||||
line = content + *pos;
|
||||
if (*line == '\0')
|
||||
@ -995,10 +985,6 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
CHAR8 *line;
|
||||
UINTN pos = 0;
|
||||
CHAR8 *key, *value;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(config);
|
||||
assert(content);
|
||||
|
||||
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
|
||||
if (strcmpa((CHAR8 *)"timeout", key) == 0) {
|
||||
@ -1018,23 +1004,32 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"editor", key) == 0) {
|
||||
err = parse_boolean(value, &config->editor);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'editor' config option: %a", value);
|
||||
BOOLEAN on;
|
||||
|
||||
if (EFI_ERROR(parse_boolean(value, &on)))
|
||||
continue;
|
||||
|
||||
config->editor = on;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"auto-entries", key) == 0) {
|
||||
err = parse_boolean(value, &config->auto_entries);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'auto-entries' config option: %a", value);
|
||||
BOOLEAN on;
|
||||
|
||||
if (EFI_ERROR(parse_boolean(value, &on)))
|
||||
continue;
|
||||
|
||||
config->auto_entries = on;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"auto-firmware", key) == 0) {
|
||||
err = parse_boolean(value, &config->auto_firmware);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'auto-firmware' config option: %a", value);
|
||||
BOOLEAN on;
|
||||
|
||||
if (EFI_ERROR(parse_boolean(value, &on)))
|
||||
continue;
|
||||
|
||||
config->auto_firmware = on;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1066,11 +1061,8 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
else {
|
||||
BOOLEAN on;
|
||||
|
||||
err = parse_boolean(value, &on);
|
||||
if (EFI_ERROR(err)) {
|
||||
log_error_stall(L"Error parsing 'random-seed-mode' config option: %a", value);
|
||||
if (EFI_ERROR(parse_boolean(value, &on)))
|
||||
continue;
|
||||
}
|
||||
|
||||
config->random_seed_mode = on ? RANDOM_SEED_ALWAYS : RANDOM_SEED_OFF;
|
||||
}
|
||||
@ -1087,10 +1079,6 @@ static VOID config_entry_parse_tries(
|
||||
UINTN left = UINTN_MAX, done = UINTN_MAX, factor = 1, i, next_left, next_done;
|
||||
_cleanup_freepool_ CHAR16 *prefix = NULL;
|
||||
|
||||
assert(entry);
|
||||
assert(path);
|
||||
assert(file);
|
||||
|
||||
/*
|
||||
* Parses a suffix of two counters (one going down, one going up) in the form "+LEFT-DONE" from the end of the
|
||||
* filename (but before the .efi/.conf suffix), where the "-DONE" part is optional and may be left out (in
|
||||
@ -1208,9 +1196,6 @@ static VOID config_entry_bump_counters(
|
||||
UINTN file_info_size, a, b;
|
||||
EFI_STATUS r;
|
||||
|
||||
assert(entry);
|
||||
assert(root_dir);
|
||||
|
||||
if (entry->tries_left == UINTN_MAX)
|
||||
return;
|
||||
|
||||
@ -1236,7 +1221,8 @@ static VOID config_entry_bump_counters(
|
||||
break;
|
||||
|
||||
if (r != EFI_BUFFER_TOO_SMALL || file_info_size * 2 < file_info_size) {
|
||||
log_error_stall(L"Failed to get file info for '%s': %r", old_path, r);
|
||||
Print(L"\nFailed to get file info for '%s': %r\n", old_path, r);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1248,7 +1234,8 @@ static VOID config_entry_bump_counters(
|
||||
StrCpy(file_info->FileName, entry->next_name);
|
||||
r = uefi_call_wrapper(handle->SetInfo, 4, handle, &EfiFileInfoGuid, file_info_size, file_info);
|
||||
if (EFI_ERROR(r)) {
|
||||
log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, r);
|
||||
Print(L"\nFailed to rename '%s' to '%s', ignoring: %r\n", old_path, entry->next_name, r);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1284,14 +1271,6 @@ static VOID config_entry_add_from_file(
|
||||
EFI_FILE_HANDLE handle;
|
||||
_cleanup_freepool_ CHAR16 *initrd = NULL;
|
||||
|
||||
assert(config);
|
||||
assert(device);
|
||||
assert(root_dir);
|
||||
assert(path);
|
||||
assert(file);
|
||||
assert(content);
|
||||
assert(loaded_image_path);
|
||||
|
||||
entry = AllocatePool(sizeof(ConfigEntry));
|
||||
|
||||
*entry = (ConfigEntry) {
|
||||
@ -1420,8 +1399,6 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
UINTN sec;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(root_dir);
|
||||
|
||||
*config = (Config) {
|
||||
.editor = TRUE,
|
||||
.auto_entries = TRUE,
|
||||
@ -1459,11 +1436,6 @@ static VOID config_load_entries(
|
||||
EFI_FILE_HANDLE entries_dir;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(config);
|
||||
assert(device);
|
||||
assert(root_dir);
|
||||
assert(loaded_image_path);
|
||||
|
||||
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &entries_dir, (CHAR16*) L"\\loader\\entries", EFI_FILE_MODE_READ, 0ULL);
|
||||
if (!EFI_ERROR(err)) {
|
||||
for (;;) {
|
||||
@ -1499,9 +1471,6 @@ static VOID config_load_entries(
|
||||
static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
|
||||
INTN r;
|
||||
|
||||
assert(a);
|
||||
assert(b);
|
||||
|
||||
/* Order entries that have no tries left to the beginning of the list */
|
||||
if (a->tries_left != 0 && b->tries_left == 0)
|
||||
return 1;
|
||||
@ -1532,8 +1501,6 @@ static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
|
||||
}
|
||||
|
||||
static VOID config_sort_entries(Config *config) {
|
||||
assert(config);
|
||||
|
||||
for (UINTN i = 1; i < config->entry_count; i++) {
|
||||
BOOLEAN more;
|
||||
|
||||
@ -1555,9 +1522,6 @@ static VOID config_sort_entries(Config *config) {
|
||||
}
|
||||
|
||||
static INTN config_entry_find(Config *config, CHAR16 *id) {
|
||||
assert(config);
|
||||
assert(id);
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++)
|
||||
if (StrCmp(config->entries[i]->id, id) == 0)
|
||||
return (INTN) i;
|
||||
@ -1570,8 +1534,6 @@ static VOID config_default_entry_select(Config *config) {
|
||||
EFI_STATUS err;
|
||||
INTN i;
|
||||
|
||||
assert(config);
|
||||
|
||||
/*
|
||||
* The EFI variable to specify a boot entry for the next, and only the
|
||||
* next reboot. The variable is always cleared directly after it is read.
|
||||
@ -1642,8 +1604,6 @@ static VOID config_default_entry_select(Config *config) {
|
||||
static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) {
|
||||
BOOLEAN non_unique = FALSE;
|
||||
|
||||
assert(entries);
|
||||
|
||||
for (UINTN i = 0; i < entry_count; i++)
|
||||
entries[i]->non_unique = FALSE;
|
||||
|
||||
@ -1662,8 +1622,6 @@ static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) {
|
||||
|
||||
/* generate a unique title, avoiding non-distinguishable menu entries */
|
||||
static VOID config_title_generate(Config *config) {
|
||||
assert(config);
|
||||
|
||||
/* set title */
|
||||
for (UINTN i = 0; i < config->entry_count; i++) {
|
||||
CHAR16 *title;
|
||||
@ -1736,11 +1694,6 @@ static BOOLEAN config_entry_add_call(
|
||||
|
||||
ConfigEntry *entry;
|
||||
|
||||
assert(config);
|
||||
assert(id);
|
||||
assert(title);
|
||||
assert(call);
|
||||
|
||||
entry = AllocatePool(sizeof(ConfigEntry));
|
||||
*entry = (ConfigEntry) {
|
||||
.id = StrDuplicate(id),
|
||||
@ -1767,17 +1720,11 @@ static ConfigEntry *config_entry_add_loader(
|
||||
|
||||
ConfigEntry *entry;
|
||||
|
||||
assert(config);
|
||||
assert(device);
|
||||
assert(id);
|
||||
assert(title);
|
||||
assert(loader);
|
||||
|
||||
entry = AllocatePool(sizeof(ConfigEntry));
|
||||
*entry = (ConfigEntry) {
|
||||
.type = type,
|
||||
.title = StrDuplicate(title),
|
||||
.version = version ? StrDuplicate(version) : NULL,
|
||||
.version = StrDuplicate(version),
|
||||
.device = device,
|
||||
.loader = StrDuplicate(loader),
|
||||
.id = StrDuplicate(id),
|
||||
@ -1806,13 +1753,6 @@ static BOOLEAN config_entry_add_loader_auto(
|
||||
ConfigEntry *entry;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(config);
|
||||
assert(device);
|
||||
assert(root_dir);
|
||||
assert(id);
|
||||
assert(title);
|
||||
assert(loader);
|
||||
|
||||
if (!config->auto_entries)
|
||||
return FALSE;
|
||||
|
||||
@ -1853,8 +1793,6 @@ static VOID config_entry_add_osx(Config *config) {
|
||||
UINTN handle_count = 0;
|
||||
_cleanup_freepool_ EFI_HANDLE *handles = NULL;
|
||||
|
||||
assert(config);
|
||||
|
||||
if (!config->auto_entries)
|
||||
return;
|
||||
|
||||
@ -1885,10 +1823,6 @@ static VOID config_entry_add_linux(
|
||||
EFI_STATUS err;
|
||||
ConfigEntry *entry;
|
||||
|
||||
assert(config);
|
||||
assert(device);
|
||||
assert(root_dir);
|
||||
|
||||
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &linux_dir, (CHAR16*) L"\\EFI\\Linux", EFI_FILE_MODE_READ, 0ULL);
|
||||
if (EFI_ERROR(err))
|
||||
return;
|
||||
@ -2023,9 +1957,6 @@ static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node
|
||||
EFI_DEVICE_PATH *parent;
|
||||
UINTN len;
|
||||
|
||||
assert(path);
|
||||
assert(node);
|
||||
|
||||
len = (UINT8*) NextDevicePathNode(node) - (UINT8*) path;
|
||||
parent = (EFI_DEVICE_PATH*) AllocatePool(len + sizeof(EFI_DEVICE_PATH));
|
||||
CopyMem(parent, path, len);
|
||||
@ -2047,9 +1978,6 @@ static VOID config_load_xbootldr(
|
||||
EFI_FILE *root_dir;
|
||||
EFI_STATUS r;
|
||||
|
||||
assert(config);
|
||||
assert(device);
|
||||
|
||||
partition_path = DevicePathFromHandle(device);
|
||||
if (!partition_path)
|
||||
return;
|
||||
@ -2236,16 +2164,19 @@ static EFI_STATUS image_start(
|
||||
CHAR16 *options;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(config);
|
||||
assert(entry);
|
||||
|
||||
path = FileDevicePath(entry->device, entry->loader);
|
||||
if (!path)
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path.");
|
||||
if (!path) {
|
||||
Print(L"Error getting device path.");
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
err = uefi_call_wrapper(BS->LoadImage, 6, FALSE, parent_image, path, NULL, 0, &image);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error loading %s: %r", entry->loader, err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error loading %s: %r", entry->loader, err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (config->options_edit)
|
||||
options = config->options_edit;
|
||||
@ -2259,19 +2190,22 @@ static EFI_STATUS image_start(
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err)) {
|
||||
log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err);
|
||||
Print(L"Error getting LoadedImageProtocol handle: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
goto out_unload;
|
||||
}
|
||||
loaded_image->LoadOptions = options;
|
||||
loaded_image->LoadOptionsSize = StrSize(loaded_image->LoadOptions);
|
||||
loaded_image->LoadOptionsSize = (StrLen(loaded_image->LoadOptions)+1) * sizeof(CHAR16);
|
||||
|
||||
#if ENABLE_TPM
|
||||
/* Try to log any options to the TPM, especially to catch manually edited options */
|
||||
err = tpm_log_event(SD_TPM_PCR,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Unable to add image options measurement: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Unable to add image options measurement: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2297,11 +2231,12 @@ static EFI_STATUS reboot_into_firmware(VOID) {
|
||||
return err;
|
||||
|
||||
err = uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
return log_error_status_stall(err, L"Error calling ResetSystem: %r", err);
|
||||
Print(L"Error calling ResetSystem: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
|
||||
static VOID config_free(Config *config) {
|
||||
assert(config);
|
||||
for (UINTN i = 0; i < config->entry_count; i++)
|
||||
config_entry_free(config->entries[i]);
|
||||
FreePool(config->entries);
|
||||
@ -2311,30 +2246,26 @@ static VOID config_free(Config *config) {
|
||||
}
|
||||
|
||||
static VOID config_write_entries_to_variable(Config *config) {
|
||||
_cleanup_freepool_ CHAR8 *buffer = NULL;
|
||||
_cleanup_freepool_ CHAR16 *buffer = NULL;
|
||||
UINTN sz = 0;
|
||||
CHAR8 *p;
|
||||
|
||||
assert(config);
|
||||
CHAR16 *p;
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++)
|
||||
sz += StrSize(config->entries[i]->id);
|
||||
sz += StrLen(config->entries[i]->id) + 1;
|
||||
|
||||
p = buffer = AllocatePool(sz);
|
||||
p = buffer = AllocatePool(sz * sizeof(CHAR16));
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++) {
|
||||
UINTN l;
|
||||
|
||||
l = StrSize(config->entries[i]->id);
|
||||
CopyMem(p, config->entries[i]->id, l);
|
||||
l = StrLen(config->entries[i]->id) + 1;
|
||||
CopyMem(p, config->entries[i]->id, l * sizeof(CHAR16));
|
||||
|
||||
p += l;
|
||||
}
|
||||
|
||||
assert(p == buffer + sz);
|
||||
|
||||
/* Store the full list of discovered entries. */
|
||||
(void) efivar_set_raw(LOADER_GUID, L"LoaderEntries", buffer, sz, 0);
|
||||
(void) efivar_set_raw(LOADER_GUID, L"LoaderEntries", buffer, (UINT8 *) p - (UINT8 *) buffer, 0);
|
||||
}
|
||||
|
||||
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
@ -2374,21 +2305,30 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* export the device path this image is started from */
|
||||
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
|
||||
efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, 0);
|
||||
|
||||
root_dir = LibOpenRoot(loaded_image->DeviceHandle);
|
||||
if (!root_dir)
|
||||
return log_error_status_stall(EFI_LOAD_ERROR, L"Unable to open root directory.", EFI_LOAD_ERROR);
|
||||
if (!root_dir) {
|
||||
Print(L"Unable to open root directory.");
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
|
||||
if (secure_boot_enabled() && shim_loaded()) {
|
||||
err = security_policy_install();
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error installing security policy: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error installing security policy: %r ", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* the filesystem path to this image, to prevent adding ourselves to the menu */
|
||||
@ -2427,7 +2367,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
}
|
||||
|
||||
if (config.entry_count == 0) {
|
||||
log_error_stall(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
|
||||
Print(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2451,8 +2392,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
else {
|
||||
UINT64 key;
|
||||
|
||||
/* Block up to 100ms to give firmware time to get input working. */
|
||||
err = console_key_read(&key, 100 * 1000);
|
||||
err = console_key_read(&key, FALSE);
|
||||
|
||||
if (err == EFI_NOT_READY) {
|
||||
uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
|
||||
err = console_key_read(&key, FALSE);
|
||||
}
|
||||
|
||||
if (!EFI_ERROR(err)) {
|
||||
INT16 idx;
|
||||
|
||||
@ -2494,7 +2440,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
err = image_start(image, &config, entry);
|
||||
if (EFI_ERROR(err)) {
|
||||
graphics_mode(FALSE);
|
||||
log_error_stall(L"Failed to execute %s (%s): %r", entry->title, entry->loader, err);
|
||||
Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@ -11,82 +11,32 @@
|
||||
|
||||
#define EFI_SIMPLE_TEXT_INPUT_EX_GUID &(EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
|
||||
|
||||
static inline void EventClosep(EFI_EVENT *event) {
|
||||
if (!*event)
|
||||
return;
|
||||
|
||||
uefi_call_wrapper(BS->CloseEvent, 1, *event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading input from the console sounds like an easy task to do, but thanks to broken
|
||||
* firmware it is actually a nightmare.
|
||||
*
|
||||
* There is a ConIn and TextInputEx API for this. Ideally we want to use TextInputEx,
|
||||
* because that gives us Ctrl/Alt/Shift key state information. Unfortunately, it is not
|
||||
* always available and sometimes just non-functional.
|
||||
*
|
||||
* On the other hand we have ConIn, where some firmware likes to just freeze on us
|
||||
* if we call ReadKeyStroke on it.
|
||||
*
|
||||
* Therefore, we use WaitForEvent on both ConIn and TextInputEx (if available) along
|
||||
* with a timer event. The timer ensures there is no need to call into functions
|
||||
* that might freeze on us, while still allowing us to show a timeout counter.
|
||||
*/
|
||||
EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) {
|
||||
static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx;
|
||||
static BOOLEAN checked;
|
||||
UINTN index;
|
||||
EFI_INPUT_KEY k;
|
||||
EFI_STATUS err;
|
||||
_cleanup_(EventClosep) EFI_EVENT timer = NULL;
|
||||
EFI_EVENT events[3] = { ST->ConIn->WaitForKey };
|
||||
UINTN n_events = 1;
|
||||
|
||||
assert(key);
|
||||
|
||||
if (!checked) {
|
||||
err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx);
|
||||
if (EFI_ERROR(err) ||
|
||||
uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
|
||||
/* If WaitForKeyEx fails here, the firmware pretends it talks this
|
||||
* protocol, but it really doesn't. */
|
||||
if (EFI_ERROR(err))
|
||||
TextInputEx = NULL;
|
||||
else
|
||||
events[n_events++] = TextInputEx->WaitForKeyEx;
|
||||
|
||||
checked = TRUE;
|
||||
}
|
||||
|
||||
if (timeout_usec > 0) {
|
||||
err = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &timer);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error creating timer event: %r", err);
|
||||
/* wait until key is pressed */
|
||||
if (wait)
|
||||
uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
|
||||
|
||||
/* SetTimer expects 100ns units for some reason. */
|
||||
err = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerRelative, timeout_usec * 10);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error arming timer event: %r", err);
|
||||
|
||||
events[n_events++] = timer;
|
||||
}
|
||||
|
||||
err = uefi_call_wrapper(BS->WaitForEvent, 3, n_events, events, &index);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error waiting for events: %r", err);
|
||||
|
||||
if (timeout_usec > 0 && timer == events[index])
|
||||
return EFI_TIMEOUT;
|
||||
|
||||
/* TextInputEx might be ready too even if ConIn got to signal first. */
|
||||
if (TextInputEx && !EFI_ERROR(uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx))) {
|
||||
if (TextInputEx) {
|
||||
EFI_KEY_DATA keydata;
|
||||
UINT64 keypress;
|
||||
UINT32 shift = 0;
|
||||
|
||||
err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
if (!EFI_ERROR(err)) {
|
||||
UINT32 shift = 0;
|
||||
|
||||
/* do not distinguish between left and right keys */
|
||||
if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) {
|
||||
@ -100,18 +50,22 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar);
|
||||
if (keypress > 0) {
|
||||
*key = keypress;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_NOT_READY;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fallback for firmware which does not support SimpleTextInputExProtocol
|
||||
*
|
||||
* This is also called in case ReadKeyStrokeEx did not return a key, because
|
||||
* some broken firmwares offer SimpleTextInputExProtocol, but never actually
|
||||
* handle any key. */
|
||||
err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
*key = KEYPRESS(0, k.ScanCode, k.UnicodeChar);
|
||||
return EFI_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EFI_STATUS change_mode(UINTN mode) {
|
||||
@ -154,8 +108,6 @@ static EFI_STATUS mode_auto(UINTN *mode) {
|
||||
EFI_STATUS err;
|
||||
BOOLEAN keep = FALSE;
|
||||
|
||||
assert(mode);
|
||||
|
||||
err = LibLocateProtocol(&GraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
|
||||
if (!EFI_ERROR(err) && GraphicsOutput->Mode && GraphicsOutput->Mode->Info) {
|
||||
Info = GraphicsOutput->Mode->Info;
|
||||
@ -204,8 +156,6 @@ static EFI_STATUS mode_auto(UINTN *mode) {
|
||||
}
|
||||
|
||||
EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how) {
|
||||
assert(mode);
|
||||
|
||||
if (how == CONSOLE_MODE_AUTO)
|
||||
return mode_auto(mode);
|
||||
|
||||
|
||||
@ -16,5 +16,5 @@ enum console_mode_change_type {
|
||||
CONSOLE_MODE_MAX,
|
||||
};
|
||||
|
||||
EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec);
|
||||
EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait);
|
||||
EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how);
|
||||
|
||||
@ -42,7 +42,6 @@
|
||||
*/
|
||||
|
||||
#include "crc32.h"
|
||||
#include "macro-fundamental.h"
|
||||
|
||||
static const UINT32 crc32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
@ -112,8 +111,6 @@ UINT32 crc32(UINT32 seed, const VOID *buf, UINTN len) {
|
||||
const UINT8 *p = buf;
|
||||
UINT32 crc = seed;
|
||||
|
||||
assert(buf);
|
||||
|
||||
while (len > 0) {
|
||||
crc = crc32_add_char(crc, *p++);
|
||||
len--;
|
||||
@ -132,8 +129,6 @@ UINT32 crc32_exclude_offset(
|
||||
const UINT8 *p = buf;
|
||||
UINT32 crc = seed;
|
||||
|
||||
assert(buf);
|
||||
|
||||
for (UINTN i = 0; i < len; i++) {
|
||||
UINT8 x = *p++;
|
||||
|
||||
|
||||
@ -9,8 +9,6 @@
|
||||
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]) {
|
||||
EFI_DEVICE_PATH *device_path;
|
||||
|
||||
assert(handle);
|
||||
|
||||
/* export the device path this image is started from */
|
||||
device_path = DevicePathFromHandle(handle);
|
||||
if (device_path) {
|
||||
|
||||
@ -17,8 +17,6 @@ static VOID linux_efi_handover(EFI_HANDLE image, struct boot_params *params) {
|
||||
handover_f handover;
|
||||
UINTN start = (UINTN)params->hdr.code32_start;
|
||||
|
||||
assert(params);
|
||||
|
||||
#ifdef __x86_64__
|
||||
asm volatile ("cli");
|
||||
start += 512;
|
||||
@ -37,9 +35,6 @@ EFI_STATUS linux_exec(EFI_HANDLE *image,
|
||||
EFI_PHYSICAL_ADDRESS addr;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(image);
|
||||
assert(cmdline);
|
||||
|
||||
image_params = (struct boot_params *) linux_addr;
|
||||
|
||||
if (image_params->hdr.boot_flag != 0xAA55 ||
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
#include "measure.h"
|
||||
|
||||
#define EFI_TCG_GUID \
|
||||
@ -185,10 +184,8 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p
|
||||
EFI_PHYSICAL_ADDRESS event_log_last;
|
||||
UINTN desc_len;
|
||||
|
||||
assert(tcg);
|
||||
assert(description);
|
||||
desc_len = (StrLen(description) + 1) * sizeof(CHAR16);
|
||||
|
||||
desc_len = StrSize(description);
|
||||
tcg_event = AllocateZeroPool(desc_len + sizeof(TCG_PCR_EVENT));
|
||||
|
||||
if (!tcg_event)
|
||||
@ -218,16 +215,14 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32
|
||||
EFI_TCG2_EVENT *tcg_event;
|
||||
UINTN desc_len;
|
||||
|
||||
assert(tcg);
|
||||
assert(description);
|
||||
desc_len = StrLen(description) * sizeof(CHAR16);
|
||||
|
||||
desc_len = StrSize(description);
|
||||
tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len);
|
||||
tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1);
|
||||
|
||||
if (!tcg_event)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len;
|
||||
tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1;
|
||||
tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
|
||||
tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
|
||||
tcg_event->Header.PCRIndex = pcrindex;
|
||||
@ -307,8 +302,6 @@ EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UIN
|
||||
EFI_TCG *tpm1;
|
||||
EFI_TCG2 *tpm2;
|
||||
|
||||
assert(description);
|
||||
|
||||
tpm2 = tcg2_interface_check();
|
||||
if (tpm2)
|
||||
return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description);
|
||||
|
||||
@ -17,7 +17,6 @@ efi_headers = files('''
|
||||
'''.split())
|
||||
|
||||
common_sources = '''
|
||||
assert.c
|
||||
disk.c
|
||||
graphics.c
|
||||
measure.c
|
||||
@ -220,16 +219,12 @@ if have_gnu_efi
|
||||
compile_args += ['-Werror']
|
||||
endif
|
||||
if get_option('buildtype') == 'debug'
|
||||
compile_args += ['-ggdb', '-O0', '-DEFI_DEBUG']
|
||||
compile_args += ['-ggdb', '-O0']
|
||||
elif get_option('buildtype') == 'debugoptimized'
|
||||
compile_args += ['-ggdb', '-Og', '-DEFI_DEBUG']
|
||||
compile_args += ['-ggdb', '-Og']
|
||||
else
|
||||
compile_args += ['-O2']
|
||||
endif
|
||||
if get_option('b_ndebug') == 'true' or (
|
||||
get_option('b_ndebug') == 'if-release' and ['plain', 'release'].contains(get_option('buildtype')))
|
||||
compile_args += ['-DNDEBUG']
|
||||
endif
|
||||
|
||||
efi_ldflags = ['-T', efi_lds,
|
||||
'-shared',
|
||||
|
||||
@ -66,9 +66,6 @@ EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs
|
||||
struct PeHeader *pe;
|
||||
UINTN offset;
|
||||
|
||||
assert(base);
|
||||
assert(sections);
|
||||
|
||||
dos = (struct DosFileHeader *)base;
|
||||
|
||||
if (CompareMem(dos->Magic, "MZ", 2) != 0)
|
||||
@ -121,9 +118,6 @@ EFI_STATUS pe_file_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections
|
||||
EFI_STATUS err;
|
||||
_cleanup_freepool_ CHAR8 *header = NULL;
|
||||
|
||||
assert(dir);
|
||||
assert(path);
|
||||
|
||||
err = uefi_call_wrapper(dir->Open, 5, dir, &handle, path, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
@ -22,8 +22,6 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) {
|
||||
EFI_RNG_PROTOCOL *rng;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* Try to acquire the specified number of bytes from the UEFI RNG */
|
||||
|
||||
err = LibLocateProtocol(EFI_RNG_GUID, (VOID**) &rng);
|
||||
@ -37,8 +35,10 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) {
|
||||
return log_oom();
|
||||
|
||||
err = uefi_call_wrapper(rng->GetRNG, 3, rng, NULL, size, data);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to acquire RNG data: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
return EFI_SUCCESS;
|
||||
@ -65,10 +65,6 @@ static VOID hash_once(
|
||||
|
||||
struct sha256_ctx hash;
|
||||
|
||||
assert(old_seed);
|
||||
assert(rng);
|
||||
assert(system_token);
|
||||
|
||||
sha256_init_ctx(&hash);
|
||||
sha256_process_bytes(old_seed, size, &hash);
|
||||
if (rng)
|
||||
@ -91,11 +87,6 @@ static EFI_STATUS hash_many(
|
||||
|
||||
_cleanup_freepool_ VOID *output = NULL;
|
||||
|
||||
assert(old_seed);
|
||||
assert(rng);
|
||||
assert(system_token);
|
||||
assert(ret);
|
||||
|
||||
/* Hashes the specified parameters in counter mode, generating n hash values, with the counter in the
|
||||
* range counter_start…counter_start+n-1. */
|
||||
|
||||
@ -126,12 +117,6 @@ static EFI_STATUS mangle_random_seed(
|
||||
EFI_STATUS err;
|
||||
UINTN n;
|
||||
|
||||
assert(old_seed);
|
||||
assert(rng);
|
||||
assert(system_token);
|
||||
assert(ret_new_seed);
|
||||
assert(ret_for_kernel);
|
||||
|
||||
/* This takes the old seed file contents, an (optional) random number acquired from the UEFI RNG, an
|
||||
* (optional) system 'token' installed once by the OS installer in an EFI variable, and hashes them
|
||||
* together in counter mode, generating a new seed (to replace the file on disk) and the seed for the
|
||||
@ -161,18 +146,17 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) {
|
||||
EFI_STATUS err;
|
||||
UINTN size;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
|
||||
err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_NOT_FOUND)
|
||||
log_error_stall(L"Failed to read LoaderSystemToken EFI variable: %r", err);
|
||||
Print(L"Failed to read LoaderSystemToken EFI variable: %r", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (size <= 0)
|
||||
return log_error_status_stall(EFI_NOT_FOUND, L"System token too short, ignoring.");
|
||||
if (size <= 0) {
|
||||
Print(L"System token too short, ignoring.");
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
*ret_size = size;
|
||||
@ -182,7 +166,7 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) {
|
||||
|
||||
static VOID validate_sha256(void) {
|
||||
|
||||
#ifdef EFI_DEBUG
|
||||
#ifndef __OPTIMIZE__
|
||||
/* Let's validate our SHA256 implementation. We stole it from glibc, and converted it to UEFI
|
||||
* style. We better check whether it does the right stuff. We use the simpler test vectors from the
|
||||
* SHA spec. Note that we strip this out in optimization builds. */
|
||||
@ -224,9 +208,14 @@ static VOID validate_sha256(void) {
|
||||
sha256_process_bytes(array[i].string, strlena((const CHAR8*) array[i].string), &hash);
|
||||
sha256_finish_ctx(&hash, result);
|
||||
|
||||
assert(CompareMem(result, array[i].hash, HASH_VALUE_SIZE) == 0);
|
||||
if (CompareMem(result, array[i].hash, HASH_VALUE_SIZE) != 0) {
|
||||
Print(L"SHA256 failed validation.\n");
|
||||
uefi_call_wrapper(BS->Stall, 1, 120 * 1000 * 1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Print(L"SHA256 validated\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -237,8 +226,6 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(root_dir);
|
||||
|
||||
validate_sha256();
|
||||
|
||||
if (mode == RANDOM_SEED_OFF)
|
||||
@ -259,7 +246,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
|
||||
log_error_stall(L"Failed to open random seed file: %r", err);
|
||||
Print(L"Failed to open random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -268,11 +255,15 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
return log_oom();
|
||||
|
||||
size = info->FileSize;
|
||||
if (size < RANDOM_MAX_SIZE_MIN)
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too short.");
|
||||
if (size < RANDOM_MAX_SIZE_MIN) {
|
||||
Print(L"Random seed file is too short?\n");
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (size > RANDOM_MAX_SIZE_MAX)
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too large.");
|
||||
if (size > RANDOM_MAX_SIZE_MAX) {
|
||||
Print(L"Random seed file is too large?\n");
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
seed = AllocatePool(size);
|
||||
if (!seed)
|
||||
@ -280,14 +271,20 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
|
||||
rsize = size;
|
||||
err = uefi_call_wrapper(handle->Read, 3, handle, &rsize, seed);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to read random seed file: %r", err);
|
||||
if (rsize != size)
|
||||
return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file.");
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to read random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (rsize != size) {
|
||||
Print(L"Short read on random seed file\n");
|
||||
return EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to seek to beginning of random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good
|
||||
* idea to use it because it helps us for cases where users mistakenly include a random seed in
|
||||
@ -302,19 +299,27 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
/* Update the random seed on disk before we use it */
|
||||
wsize = size;
|
||||
err = uefi_call_wrapper(handle->Write, 3, handle, &wsize, new_seed);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to write random seed file: %r", err);
|
||||
if (wsize != size)
|
||||
return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file.");
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to write random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (wsize != size) {
|
||||
Print(L"Short write on random seed file\n");
|
||||
return EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
err = uefi_call_wrapper(handle->Flush, 1, handle);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to flush random seed file: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to flush random seed file: %r\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* We are good to go */
|
||||
err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, 0);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to write random seed to EFI variable: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to write random seed to EFI variable: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
|
||||
/* Written by Ulrich Drepper <drepper@redhat.com>, 2007. */
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
@ -74,8 +73,6 @@ static void sha256_process_block(const void *, UINTN, struct sha256_ctx *);
|
||||
/* Initialize structure containing state of computation.
|
||||
(FIPS 180-2:5.3.2) */
|
||||
void sha256_init_ctx(struct sha256_ctx *ctx) {
|
||||
assert(ctx);
|
||||
|
||||
ctx->H[0] = 0x6a09e667;
|
||||
ctx->H[1] = 0xbb67ae85;
|
||||
ctx->H[2] = 0x3c6ef372;
|
||||
@ -99,9 +96,6 @@ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) {
|
||||
UINT32 bytes = ctx->buflen;
|
||||
UINTN pad;
|
||||
|
||||
assert(ctx);
|
||||
assert(resbuf);
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total64 += bytes;
|
||||
|
||||
@ -124,9 +118,6 @@ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) {
|
||||
}
|
||||
|
||||
void sha256_process_bytes(const void *buffer, UINTN len, struct sha256_ctx *ctx) {
|
||||
assert(buffer);
|
||||
assert(ctx);
|
||||
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
|
||||
@ -200,10 +191,6 @@ void sha256_process_bytes(const void *buffer, UINTN len, struct sha256_ctx *ctx)
|
||||
static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ctx *ctx) {
|
||||
const UINT32 *words = buffer;
|
||||
UINTN nwords = len / sizeof (UINT32);
|
||||
|
||||
assert(buffer);
|
||||
assert(ctx);
|
||||
|
||||
UINT32 a = ctx->H[0];
|
||||
UINT32 b = ctx->H[1];
|
||||
UINT32 c = ctx->H[2];
|
||||
|
||||
@ -111,10 +111,6 @@ static EFIAPI EFI_STATUS security2_policy_authentication (const EFI_SECURITY2_PR
|
||||
VOID *file_buffer, UINTN file_size, BOOLEAN boot_policy) {
|
||||
EFI_STATUS status;
|
||||
|
||||
assert(this);
|
||||
assert(device_path);
|
||||
assert(file_buffer);
|
||||
|
||||
/* Chain original security policy */
|
||||
status = uefi_call_wrapper(es2fa, 5, this, device_path, file_buffer, file_size, boot_policy);
|
||||
|
||||
@ -147,9 +143,6 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT
|
||||
_cleanup_freepool_ CHAR8 *file_buffer = NULL;
|
||||
UINTN file_size;
|
||||
|
||||
assert(this);
|
||||
assert(device_path_const);
|
||||
|
||||
if (!device_path_const)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
|
||||
@ -44,11 +44,6 @@ static EFI_STATUS bmp_parse_header(UINT8 *bmp, UINTN size, struct bmp_dib **ret_
|
||||
struct bmp_map *map;
|
||||
UINTN row_size;
|
||||
|
||||
assert(bmp);
|
||||
assert(ret_dib);
|
||||
assert(ret_map);
|
||||
assert(pixmap);
|
||||
|
||||
if (size < sizeof(struct bmp_file) + sizeof(struct bmp_dib))
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
@ -133,8 +128,6 @@ static EFI_STATUS bmp_parse_header(UINT8 *bmp, UINTN size, struct bmp_dib **ret_
|
||||
static VOID pixel_blend(UINT32 *dst, const UINT32 source) {
|
||||
UINT32 alpha, src, src_rb, src_g, dst_rb, dst_g, rb, g;
|
||||
|
||||
assert(dst);
|
||||
|
||||
alpha = (source & 0xff);
|
||||
|
||||
/* convert src from RGBA to XRGB */
|
||||
@ -159,11 +152,6 @@ static EFI_STATUS bmp_to_blt(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf,
|
||||
UINT8 *pixmap) {
|
||||
UINT8 *in;
|
||||
|
||||
assert(buf);
|
||||
assert(dib);
|
||||
assert(map);
|
||||
assert(pixmap);
|
||||
|
||||
/* transform and copy pixels */
|
||||
in = pixmap;
|
||||
for (UINTN y = 0; y < dib->y; y++) {
|
||||
@ -259,8 +247,6 @@ EFI_STATUS graphics_splash(UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_
|
||||
UINTN y_pos = 0;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(content);
|
||||
|
||||
if (!background) {
|
||||
if (StriCmp(L"Apple", ST->FirmwareVendor) == 0) {
|
||||
pixel.Red = 0xc0;
|
||||
|
||||
@ -36,12 +36,18 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error getting a LoadedImageProtocol handle: %r ", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Unable to locate embedded .linux section: %r ", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (szs[0] > 0)
|
||||
cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
|
||||
@ -66,8 +72,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
err = tpm_log_event(SD_TPM_PCR,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Unable to add image options measurement: %r", err);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Unable to add image options measurement: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -118,5 +126,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
(UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
|
||||
|
||||
graphics_mode(FALSE);
|
||||
return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
|
||||
Print(L"Execution of embedded linux image failed: %r\n", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -67,17 +67,13 @@ UINT64 time_usec(VOID) {
|
||||
}
|
||||
|
||||
EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
|
||||
assert(b);
|
||||
|
||||
if (!v)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (strcmpa(v, (CHAR8 *)"1") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"yes") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"y") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"true") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"t") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"on") == 0) {
|
||||
strcmpa(v, (CHAR8 *)"true") == 0) {
|
||||
*b = TRUE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@ -85,9 +81,7 @@ EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
|
||||
if (strcmpa(v, (CHAR8 *)"0") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"no") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"n") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"false") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"f") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"off") == 0) {
|
||||
strcmpa(v, (CHAR8 *)"false") == 0) {
|
||||
*b = FALSE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@ -96,37 +90,24 @@ EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, UINT32 flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
assert(buf || size == 0);
|
||||
|
||||
flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
return uefi_call_wrapper(RT->SetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, flags, size, (VOID*) buf);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, UINT32 flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
return efivar_set_raw(vendor, name, value, value ? StrSize(value) : 0, flags);
|
||||
return efivar_set_raw(vendor, name, value, value ? (StrLen(value) + 1) * sizeof(CHAR16) : 0, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags) {
|
||||
CHAR16 str[32];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
SPrint(str, ELEMENTSOF(str), L"%u", i);
|
||||
SPrint(str, 32, L"%u", i);
|
||||
return efivar_set(vendor, name, str, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 value, UINT32 flags) {
|
||||
UINT8 buf[4];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (UINT8)(value >> 0U & 0xFF);
|
||||
buf[1] = (UINT8)(value >> 8U & 0xFF);
|
||||
buf[2] = (UINT8)(value >> 16U & 0xFF);
|
||||
@ -138,9 +119,6 @@ EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 value, UINT32 flags) {
|
||||
UINT8 buf[8];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (UINT8)(value >> 0U & 0xFF);
|
||||
buf[1] = (UINT8)(value >> 8U & 0xFF);
|
||||
buf[2] = (UINT8)(value >> 16U & 0xFF);
|
||||
@ -154,38 +132,35 @@ EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value) {
|
||||
_cleanup_freepool_ CHAR16 *buf = NULL;
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
EFI_STATUS err;
|
||||
CHAR16 *val;
|
||||
UINTN size;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (CHAR8**)&buf, &size);
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
/* Make sure there are no incomplete characters in the buffer */
|
||||
if ((size % sizeof(CHAR16)) != 0)
|
||||
if ((size % 2) != 0)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (!value)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Return buffer directly if it happens to be NUL terminated already */
|
||||
if (size >= sizeof(CHAR16) && buf[size/sizeof(CHAR16)] == 0) {
|
||||
*value = TAKE_PTR(buf);
|
||||
if (size >= 2 && buf[size-2] == 0 && buf[size-1] == 0) {
|
||||
*value = (CHAR16*) TAKE_PTR(buf);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure a terminating NUL is available at the end */
|
||||
val = AllocatePool(size + sizeof(CHAR16));
|
||||
val = AllocatePool(size + 2);
|
||||
if (!val)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
CopyMem(val, buf, size);
|
||||
val[size / sizeof(CHAR16)] = 0; /* NUL terminate */
|
||||
val[size/2] = 0; /* NUL terminate */
|
||||
|
||||
*value = val;
|
||||
return EFI_SUCCESS;
|
||||
@ -195,12 +170,8 @@ EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UI
|
||||
_cleanup_freepool_ CHAR16 *val = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
assert(i);
|
||||
|
||||
err = efivar_get(vendor, name, &val);
|
||||
if (!EFI_ERROR(err))
|
||||
if (!EFI_ERROR(err) && i)
|
||||
*i = Atoi(val);
|
||||
|
||||
return err;
|
||||
@ -211,9 +182,6 @@ EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
UINTN size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (!EFI_ERROR(err) && ret) {
|
||||
if (size != sizeof(UINT32))
|
||||
@ -231,9 +199,6 @@ EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
UINTN size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (!EFI_ERROR(err) && ret) {
|
||||
if (size != sizeof(UINT64))
|
||||
@ -252,9 +217,6 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu
|
||||
UINTN l;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
l = sizeof(CHAR16 *) * EFI_MAXIMUM_VARIABLE_SIZE;
|
||||
buf = AllocatePool(l);
|
||||
if (!buf)
|
||||
@ -278,10 +240,6 @@ EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOO
|
||||
UINTN size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &b, &size);
|
||||
if (!EFI_ERROR(err))
|
||||
*ret = *b > 0;
|
||||
@ -292,15 +250,12 @@ EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOO
|
||||
VOID efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec) {
|
||||
CHAR16 str[32];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
if (usec == 0)
|
||||
usec = time_usec();
|
||||
if (usec == 0)
|
||||
return;
|
||||
|
||||
SPrint(str, ELEMENTSOF(str), L"%ld", usec);
|
||||
SPrint(str, 32, L"%ld", usec);
|
||||
efivar_set(vendor, name, str, 0);
|
||||
}
|
||||
|
||||
@ -308,9 +263,6 @@ static INTN utf8_to_16(const CHAR8 *stra, CHAR16 *c) {
|
||||
CHAR16 unichar;
|
||||
UINTN len;
|
||||
|
||||
assert(stra);
|
||||
assert(c);
|
||||
|
||||
if (!(stra[0] & 0x80))
|
||||
len = 1;
|
||||
else if ((stra[0] & 0xe0) == 0xc0)
|
||||
@ -364,8 +316,6 @@ CHAR16 *stra_to_str(const CHAR8 *stra) {
|
||||
UINTN i;
|
||||
CHAR16 *str;
|
||||
|
||||
assert(stra);
|
||||
|
||||
len = strlena(stra);
|
||||
str = AllocatePool((len + 1) * sizeof(CHAR16));
|
||||
|
||||
@ -394,8 +344,6 @@ CHAR16 *stra_to_path(const CHAR8 *stra) {
|
||||
UINTN len;
|
||||
UINTN i;
|
||||
|
||||
assert(stra);
|
||||
|
||||
len = strlena(stra);
|
||||
str = AllocatePool((len + 2) * sizeof(CHAR16));
|
||||
|
||||
@ -428,7 +376,6 @@ CHAR16 *stra_to_path(const CHAR8 *stra) {
|
||||
}
|
||||
|
||||
CHAR8 *strchra(const CHAR8 *s, CHAR8 c) {
|
||||
assert(s);
|
||||
do {
|
||||
if (*s == c)
|
||||
return (CHAR8*) s;
|
||||
@ -441,9 +388,6 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
err = uefi_call_wrapper(dir->Open, 5, dir, &handle, (CHAR16*) name, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
@ -481,23 +425,8 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s
|
||||
return err;
|
||||
}
|
||||
|
||||
VOID log_error_stall(const CHAR16 *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
assert(fmt);
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK);
|
||||
|
||||
Print(L"\n");
|
||||
va_start(args, fmt);
|
||||
VPrint(fmt, args);
|
||||
va_end(args);
|
||||
Print(L"\n");
|
||||
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
}
|
||||
|
||||
EFI_STATUS log_oom(void) {
|
||||
log_error_stall(L"Out of memory.");
|
||||
Print(L"Out of memory.");
|
||||
(void) uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
@ -74,13 +74,4 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
|
||||
#define UINT64_MAX ((UINT64) -1)
|
||||
#endif
|
||||
|
||||
VOID log_error_stall(const CHAR16 *fmt, ...);
|
||||
EFI_STATUS log_oom(void);
|
||||
|
||||
/* This works just like log_error_errno() from userspace, but requires you
|
||||
* to provide err a second time if you want to use %r in the message! */
|
||||
#define log_error_status_stall(err, fmt, ...) \
|
||||
({ \
|
||||
log_error_stall(fmt, ##__VA_ARGS__); \
|
||||
err; \
|
||||
})
|
||||
|
||||
@ -1541,7 +1541,7 @@ Manager* manager_free(Manager *m) {
|
||||
static void manager_enumerate_perpetual(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
if (FLAGS_SET(m->test_run_flags, MANAGER_TEST_RUN_MINIMAL))
|
||||
if (m->test_run_flags == MANAGER_TEST_RUN_MINIMAL)
|
||||
return;
|
||||
|
||||
/* Let's ask every type to load all units from disk/kernel that it might know */
|
||||
@ -1559,7 +1559,7 @@ static void manager_enumerate_perpetual(Manager *m) {
|
||||
static void manager_enumerate(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
if (FLAGS_SET(m->test_run_flags, MANAGER_TEST_RUN_MINIMAL))
|
||||
if (m->test_run_flags == MANAGER_TEST_RUN_MINIMAL)
|
||||
return;
|
||||
|
||||
/* Let's ask every type to load all units from disk/kernel that it might know */
|
||||
|
||||
@ -133,7 +133,6 @@ typedef enum ManagerTestRunFlags {
|
||||
MANAGER_TEST_RUN_BASIC = 1 << 1, /* interact with the environment */
|
||||
MANAGER_TEST_RUN_ENV_GENERATORS = 1 << 2, /* also run env generators */
|
||||
MANAGER_TEST_RUN_GENERATORS = 1 << 3, /* also run unit generators */
|
||||
MANAGER_TEST_RUN_IGNORE_DEPENDENCIES = 1 << 4, /* run while ignoring dependencies */
|
||||
MANAGER_TEST_FULL = MANAGER_TEST_RUN_BASIC | MANAGER_TEST_RUN_ENV_GENERATORS | MANAGER_TEST_RUN_GENERATORS,
|
||||
} ManagerTestRunFlags;
|
||||
|
||||
|
||||
@ -3053,9 +3053,6 @@ int unit_add_dependency(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
|
||||
return 0;
|
||||
|
||||
/* Note that ordering a device unit after a unit is permitted since it allows to start its job
|
||||
* running timeout at a specific time. */
|
||||
if (FLAGS_SET(a, UNIT_ATOM_BEFORE) && other->type == UNIT_DEVICE) {
|
||||
@ -3179,9 +3176,6 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, boo
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
|
||||
return 0;
|
||||
|
||||
r = manager_load_unit(u->manager, name, NULL, NULL, &other);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -3201,9 +3195,6 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
|
||||
return 0;
|
||||
|
||||
r = manager_load_unit(u->manager, name, NULL, NULL, &other);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -3321,9 +3312,6 @@ int unit_set_default_slice(Unit *u) {
|
||||
|
||||
assert(u);
|
||||
|
||||
if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
|
||||
return 0;
|
||||
|
||||
if (UNIT_GET_SLICE(u))
|
||||
return 0;
|
||||
|
||||
|
||||
@ -14,22 +14,6 @@
|
||||
#define _used_ __attribute__((__used__))
|
||||
#define _unused_ __attribute__((__unused__))
|
||||
#define _cleanup_(x) __attribute__((__cleanup__(x)))
|
||||
#define _likely_(x) (__builtin_expect(!!(x), 1))
|
||||
#define _unlikely_(x) (__builtin_expect(!!(x), 0))
|
||||
#if __GNUC__ >= 7
|
||||
#define _fallthrough_ __attribute__((__fallthrough__))
|
||||
#else
|
||||
#define _fallthrough_
|
||||
#endif
|
||||
/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
|
||||
* compiler versions */
|
||||
#ifndef _noreturn_
|
||||
#if __STDC_VERSION__ >= 201112L
|
||||
#define _noreturn_ _Noreturn
|
||||
#else
|
||||
#define _noreturn_ __attribute__((__noreturn__))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define XSTRINGIFY(x) #x
|
||||
#define STRINGIFY(x) XSTRINGIFY(x)
|
||||
@ -50,14 +34,7 @@
|
||||
#define CONCATENATE(x, y) XCONCATENATE(x, y)
|
||||
|
||||
#ifdef SD_BOOT
|
||||
#ifdef NDEBUG
|
||||
#define assert(expr)
|
||||
#define assert_not_reached() __builtin_unreachable()
|
||||
#else
|
||||
void efi_assert(const char *expr, const char *file, unsigned line, const char *function) _noreturn_;
|
||||
#define assert(expr) ({ _likely_(expr) ? VOID_0 : efi_assert(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); })
|
||||
#define assert_not_reached() efi_assert("Code should not be reached", __FILE__, __LINE__, __PRETTY_FUNCTION__)
|
||||
#endif
|
||||
#define assert(expr) do {} while (false)
|
||||
#endif
|
||||
|
||||
#if defined(static_assert)
|
||||
@ -256,10 +233,3 @@
|
||||
(ptr) = NULL; \
|
||||
_ptr_; \
|
||||
})
|
||||
|
||||
/*
|
||||
* STRLEN - return the length of a string literal, minus the trailing NUL byte.
|
||||
* Contrary to strlen(), this is a constant expression.
|
||||
* @x: a string literal.
|
||||
*/
|
||||
#define STRLEN(x) (sizeof(""x"") - sizeof(typeof(x[0])))
|
||||
|
||||
@ -29,7 +29,7 @@ static int bare_udp_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *
|
||||
log_netdev_info(netdev, "BareUDP netdev exists, using existing without changing its parameters.");
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "BareUDP netdev could not be created: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ static int fou_tunnel_create_handler(sd_netlink *rtnl, sd_netlink_message *m, Ne
|
||||
log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ static int geneve_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||
log_netdev_info(netdev, "Geneve netdev exists, using existing without changing its parameters");
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "Geneve netdev could not be created: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ static int l2tp_create_tunnel_handler(sd_netlink *rtnl, sd_netlink_message *m, N
|
||||
log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ static int macsec_receive_association_handler(sd_netlink *rtnl, sd_netlink_messa
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r,
|
||||
"Failed to add receive secure association: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -375,7 +375,7 @@ static int macsec_receive_channel_handler(sd_netlink *rtnl, sd_netlink_message *
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r,
|
||||
"Failed to add receive secure channel: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -387,7 +387,7 @@ static int macsec_receive_channel_handler(sd_netlink *rtnl, sd_netlink_message *
|
||||
if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r,
|
||||
"Failed to configure receive security association: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -441,7 +441,7 @@ static int macsec_transmit_association_handler(sd_netlink *rtnl, sd_netlink_mess
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r,
|
||||
"Failed to add transmit secure association: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -167,54 +167,6 @@ bool netdev_is_managed(NetDev *netdev) {
|
||||
return hashmap_get(netdev->manager->netdevs, netdev->ifname) == netdev;
|
||||
}
|
||||
|
||||
static bool netdev_is_stacked_and_independent(NetDev *netdev) {
|
||||
assert(netdev);
|
||||
|
||||
if (!IN_SET(netdev_get_create_type(netdev), NETDEV_CREATE_STACKED, NETDEV_CREATE_AFTER_CONFIGURED))
|
||||
return false;
|
||||
|
||||
switch (netdev->kind) {
|
||||
case NETDEV_KIND_ERSPAN:
|
||||
return ERSPAN(netdev)->independent;
|
||||
case NETDEV_KIND_GRE:
|
||||
return GRE(netdev)->independent;
|
||||
case NETDEV_KIND_GRETAP:
|
||||
return GRETAP(netdev)->independent;
|
||||
case NETDEV_KIND_IP6GRE:
|
||||
return IP6GRE(netdev)->independent;
|
||||
case NETDEV_KIND_IP6GRETAP:
|
||||
return IP6GRETAP(netdev)->independent;
|
||||
case NETDEV_KIND_IP6TNL:
|
||||
return IP6TNL(netdev)->independent;
|
||||
case NETDEV_KIND_IPIP:
|
||||
return IPIP(netdev)->independent;
|
||||
case NETDEV_KIND_SIT:
|
||||
return SIT(netdev)->independent;
|
||||
case NETDEV_KIND_VTI:
|
||||
return VTI(netdev)->independent;
|
||||
case NETDEV_KIND_VTI6:
|
||||
return VTI6(netdev)->independent;
|
||||
case NETDEV_KIND_VXLAN:
|
||||
return VXLAN(netdev)->independent;
|
||||
case NETDEV_KIND_XFRM:
|
||||
return XFRM(netdev)->independent;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool netdev_is_stacked(NetDev *netdev) {
|
||||
assert(netdev);
|
||||
|
||||
if (!IN_SET(netdev_get_create_type(netdev), NETDEV_CREATE_STACKED, NETDEV_CREATE_AFTER_CONFIGURED))
|
||||
return false;
|
||||
|
||||
if (netdev_is_stacked_and_independent(netdev))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void netdev_detach_from_manager(NetDev *netdev) {
|
||||
if (netdev->ifname && netdev->manager)
|
||||
hashmap_remove(netdev->manager->netdevs, netdev->ifname);
|
||||
@ -250,19 +202,9 @@ static NetDev *netdev_free(NetDev *netdev) {
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(NetDev, netdev, netdev_free);
|
||||
|
||||
void netdev_drop(NetDev *netdev) {
|
||||
if (!netdev)
|
||||
if (!netdev || netdev->state == NETDEV_STATE_LINGER)
|
||||
return;
|
||||
|
||||
if (netdev_is_stacked(netdev)) {
|
||||
/* The netdev may be removed due to the underlying device removal, and the device may
|
||||
* be re-added later. */
|
||||
netdev->state = NETDEV_STATE_LOADING;
|
||||
netdev->ifindex = 0;
|
||||
|
||||
log_netdev_debug(netdev, "netdev removed");
|
||||
return;
|
||||
}
|
||||
|
||||
netdev->state = NETDEV_STATE_LINGER;
|
||||
|
||||
log_netdev_debug(netdev, "netdev removed");
|
||||
@ -290,8 +232,9 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void netdev_enter_failed(NetDev *netdev) {
|
||||
static int netdev_enter_failed(NetDev *netdev) {
|
||||
netdev->state = NETDEV_STATE_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netdev_enter_ready(NetDev *netdev) {
|
||||
@ -323,7 +266,7 @@ static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev
|
||||
log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
netdev_drop(netdev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -617,12 +560,12 @@ static bool netdev_is_ready_to_create(NetDev *netdev, Link *link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_stacked_netdev(Request *req) {
|
||||
int request_process_create_stacked_netdev(Request *req) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_STACKED_NETDEV);
|
||||
assert(req->type == REQUEST_TYPE_CREATE_STACKED_NETDEV);
|
||||
assert(req->netdev);
|
||||
assert(req->netlink_handler);
|
||||
|
||||
@ -689,42 +632,46 @@ static int link_create_stacked_netdev_after_configured_handler(sd_netlink *rtnl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_request_stacked_netdev(Link *link, NetDev *netdev) {
|
||||
int link_request_to_crate_stacked_netdev(Link *link, NetDev *netdev) {
|
||||
NetDevCreateType create_type;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(netdev);
|
||||
|
||||
if (!netdev_is_stacked(netdev))
|
||||
create_type = netdev_get_create_type(netdev);
|
||||
if (!IN_SET(create_type, NETDEV_CREATE_STACKED, NETDEV_CREATE_AFTER_CONFIGURED))
|
||||
return -EINVAL;
|
||||
|
||||
if (!IN_SET(netdev->state, NETDEV_STATE_LOADING, NETDEV_STATE_FAILED) || netdev->ifindex > 0)
|
||||
return 0; /* Already created. */
|
||||
if (netdev->state != NETDEV_STATE_LOADING || netdev->ifindex > 0)
|
||||
/* Already created (or removed?) */
|
||||
return 0;
|
||||
|
||||
if (netdev_get_create_type(netdev) == NETDEV_CREATE_STACKED) {
|
||||
if (create_type == NETDEV_CREATE_STACKED) {
|
||||
link->stacked_netdevs_created = false;
|
||||
r = link_queue_request(link, REQUEST_TYPE_STACKED_NETDEV, netdev, false,
|
||||
r = link_queue_request(link, REQUEST_TYPE_CREATE_STACKED_NETDEV, netdev, false,
|
||||
&link->create_stacked_netdev_messages,
|
||||
link_create_stacked_netdev_handler,
|
||||
NULL);
|
||||
} else {
|
||||
link->stacked_netdevs_after_configured_created = false;
|
||||
r = link_queue_request(link, REQUEST_TYPE_STACKED_NETDEV, netdev, false,
|
||||
r = link_queue_request(link, REQUEST_TYPE_CREATE_STACKED_NETDEV, netdev, false,
|
||||
&link->create_stacked_netdev_after_configured_messages,
|
||||
link_create_stacked_netdev_after_configured_handler,
|
||||
NULL);
|
||||
}
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request stacked netdev '%s': %m",
|
||||
return log_link_error_errno(link, r, "Failed to request to create stacked netdev '%s': %m",
|
||||
netdev->ifname);
|
||||
|
||||
log_link_debug(link, "Requested stacked netdev '%s'", netdev->ifname);
|
||||
log_link_debug(link, "Requested to create stacked netdev '%s'", netdev->ifname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int netdev_load_one(Manager *manager, const char *filename) {
|
||||
_cleanup_(netdev_unrefp) NetDev *netdev_raw = NULL, *netdev = NULL;
|
||||
const char *dropin_dirname;
|
||||
bool independent = false;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
@ -845,7 +792,48 @@ int netdev_load_one(Manager *manager, const char *filename) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (netdev_is_stacked_and_independent(netdev)) {
|
||||
switch (netdev->kind) {
|
||||
case NETDEV_KIND_IPIP:
|
||||
independent = IPIP(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_GRE:
|
||||
independent = GRE(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_GRETAP:
|
||||
independent = GRETAP(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_IP6GRE:
|
||||
independent = IP6GRE(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_IP6GRETAP:
|
||||
independent = IP6GRETAP(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_SIT:
|
||||
independent = SIT(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_VTI:
|
||||
independent = VTI(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_VTI6:
|
||||
independent = VTI6(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_IP6TNL:
|
||||
independent = IP6TNL(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_ERSPAN:
|
||||
independent = ERSPAN(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_XFRM:
|
||||
independent = XFRM(netdev)->independent;
|
||||
break;
|
||||
case NETDEV_KIND_VXLAN:
|
||||
independent = VXLAN(netdev)->independent;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (independent) {
|
||||
r = netdev_create(netdev, NULL, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -184,7 +184,6 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
|
||||
int netdev_load(Manager *manager, bool reload);
|
||||
int netdev_load_one(Manager *manager, const char *filename);
|
||||
void netdev_drop(NetDev *netdev);
|
||||
void netdev_enter_failed(NetDev *netdev);
|
||||
|
||||
NetDev *netdev_unref(NetDev *netdev);
|
||||
NetDev *netdev_ref(NetDev *netdev);
|
||||
@ -197,8 +196,8 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
|
||||
int netdev_get_mac(const char *ifname, struct ether_addr **ret);
|
||||
int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb);
|
||||
|
||||
int request_process_stacked_netdev(Request *req);
|
||||
int link_request_stacked_netdev(Link *link, NetDev *netdev);
|
||||
int request_process_create_stacked_netdev(Request *req);
|
||||
int link_request_to_crate_stacked_netdev(Link *link, NetDev *netdev);
|
||||
|
||||
const char *netdev_kind_to_string(NetDevKind d) _const_;
|
||||
NetDevKind netdev_kind_from_string(const char *d) _pure_;
|
||||
|
||||
@ -594,7 +594,7 @@ static int link_request_stacked_netdevs(Link *link) {
|
||||
link->stacked_netdevs_after_configured_created = false;
|
||||
|
||||
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs) {
|
||||
r = link_request_stacked_netdev(link, netdev);
|
||||
r = link_request_to_crate_stacked_netdev(link, netdev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -32,6 +32,8 @@ static void request_free_object(RequestType type, void *object) {
|
||||
case REQUEST_TYPE_BRIDGE_MDB:
|
||||
bridge_mdb_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_CREATE_STACKED_NETDEV:
|
||||
break;
|
||||
case REQUEST_TYPE_DHCP_SERVER:
|
||||
case REQUEST_TYPE_DHCP4_CLIENT:
|
||||
case REQUEST_TYPE_DHCP6_CLIENT:
|
||||
@ -54,7 +56,6 @@ static void request_free_object(RequestType type, void *object) {
|
||||
routing_policy_rule_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_SET_LINK:
|
||||
case REQUEST_TYPE_STACKED_NETDEV:
|
||||
case REQUEST_TYPE_UP_DOWN:
|
||||
break;
|
||||
default:
|
||||
@ -109,7 +110,7 @@ static void request_hash_func(const Request *req, struct siphash *state) {
|
||||
case REQUEST_TYPE_ADDRESS_LABEL:
|
||||
case REQUEST_TYPE_BRIDGE_FDB:
|
||||
case REQUEST_TYPE_BRIDGE_MDB:
|
||||
case REQUEST_TYPE_STACKED_NETDEV:
|
||||
case REQUEST_TYPE_CREATE_STACKED_NETDEV:
|
||||
/* TODO: Currently, these types do not have any specific hash and compare functions.
|
||||
* Fortunately, all these objects are 'static', thus we can use the trivial functions. */
|
||||
trivial_hash_func(req->object, state);
|
||||
@ -172,7 +173,7 @@ static int request_compare_func(const struct Request *a, const struct Request *b
|
||||
case REQUEST_TYPE_ADDRESS_LABEL:
|
||||
case REQUEST_TYPE_BRIDGE_FDB:
|
||||
case REQUEST_TYPE_BRIDGE_MDB:
|
||||
case REQUEST_TYPE_STACKED_NETDEV:
|
||||
case REQUEST_TYPE_CREATE_STACKED_NETDEV:
|
||||
return trivial_compare_func(a->object, b->object);
|
||||
case REQUEST_TYPE_DHCP_SERVER:
|
||||
case REQUEST_TYPE_DHCP4_CLIENT:
|
||||
@ -305,6 +306,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
case REQUEST_TYPE_BRIDGE_MDB:
|
||||
r = request_process_bridge_mdb(req);
|
||||
break;
|
||||
case REQUEST_TYPE_CREATE_STACKED_NETDEV:
|
||||
r = request_process_create_stacked_netdev(req);
|
||||
break;
|
||||
case REQUEST_TYPE_DHCP_SERVER:
|
||||
r = request_process_dhcp_server(req);
|
||||
break;
|
||||
@ -335,9 +339,6 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
case REQUEST_TYPE_SET_LINK:
|
||||
r = request_process_set_link(req);
|
||||
break;
|
||||
case REQUEST_TYPE_STACKED_NETDEV:
|
||||
r = request_process_stacked_netdev(req);
|
||||
break;
|
||||
case REQUEST_TYPE_UP_DOWN:
|
||||
r = request_process_link_up_or_down(req);
|
||||
break;
|
||||
|
||||
@ -26,6 +26,7 @@ typedef enum RequestType {
|
||||
REQUEST_TYPE_ADDRESS_LABEL,
|
||||
REQUEST_TYPE_BRIDGE_FDB,
|
||||
REQUEST_TYPE_BRIDGE_MDB,
|
||||
REQUEST_TYPE_CREATE_STACKED_NETDEV,
|
||||
REQUEST_TYPE_DHCP_SERVER,
|
||||
REQUEST_TYPE_DHCP4_CLIENT,
|
||||
REQUEST_TYPE_DHCP6_CLIENT,
|
||||
@ -36,7 +37,6 @@ typedef enum RequestType {
|
||||
REQUEST_TYPE_ROUTE,
|
||||
REQUEST_TYPE_ROUTING_POLICY_RULE,
|
||||
REQUEST_TYPE_SET_LINK,
|
||||
REQUEST_TYPE_STACKED_NETDEV,
|
||||
REQUEST_TYPE_UP_DOWN,
|
||||
_REQUEST_TYPE_MAX,
|
||||
_REQUEST_TYPE_INVALID = -EINVAL,
|
||||
|
||||
@ -362,8 +362,9 @@ void dns_server_packet_rcode_downgrade(DnsServer *s, DnsServerFeatureLevel level
|
||||
if (s->possible_feature_level > level) {
|
||||
s->possible_feature_level = level;
|
||||
dns_server_reset_counters(s);
|
||||
log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", strna(dns_server_string_full(s)));
|
||||
}
|
||||
|
||||
log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", strna(dns_server_string_full(s)));
|
||||
}
|
||||
|
||||
void dns_server_packet_invalid(DnsServer *s, DnsServerFeatureLevel level) {
|
||||
|
||||
@ -1142,18 +1142,6 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
|
||||
break;
|
||||
}
|
||||
|
||||
/* SERVFAIL can happen for many reasons and may be transient.
|
||||
* To avoid unnecessary downgrades retry once with the initial level.
|
||||
* Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
|
||||
* first attempt to downgrade. If so, clamp to the current value so that the transaction
|
||||
* is retried without actually downgrading. If the next try also fails we will downgrade by
|
||||
* hitting the else branch below. */
|
||||
if (DNS_PACKET_RCODE(p) == DNS_RCODE_SERVFAIL &&
|
||||
t->clamp_feature_level_servfail < 0) {
|
||||
t->clamp_feature_level_servfail = t->current_feature_level;
|
||||
log_debug("Server returned error %s, retrying transaction.",
|
||||
dns_rcode_to_string(DNS_PACKET_RCODE(p)));
|
||||
} else {
|
||||
/* Reduce this feature level by one and try again. */
|
||||
switch (t->current_feature_level) {
|
||||
case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
|
||||
@ -1170,7 +1158,6 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
|
||||
log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
|
||||
dns_rcode_to_string(DNS_PACKET_RCODE(p)),
|
||||
dns_server_feature_level_to_string(t->clamp_feature_level_servfail));
|
||||
}
|
||||
|
||||
dns_transaction_retry(t, false /* use the same server */);
|
||||
return;
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
/* Do some basic checks on STRLEN() and DECIMAL_STR_MAX() */
|
||||
assert_cc(STRLEN("xxx") == 3);
|
||||
assert_cc(STRLEN("") == 0);
|
||||
assert_cc(STRLEN(L"xxx") == 3 * sizeof(wchar_t));
|
||||
assert_cc(STRLEN(L"") == 0);
|
||||
assert_cc(DECIMAL_STR_MAX(uint8_t) == 5);
|
||||
assert_cc(DECIMAL_STR_MAX(int8_t) == 5);
|
||||
assert_cc(DECIMAL_STR_MAX(uint64_t) == 22);
|
||||
|
||||
@ -1183,25 +1183,6 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, ' mtu 2000 ')
|
||||
self.assertRegex(output, 'macvlan mode ' + mode + ' ')
|
||||
|
||||
rc = call("ip link del test1")
|
||||
self.assertEqual(rc, 0)
|
||||
time.sleep(1)
|
||||
|
||||
rc = call("ip link add test1 type dummy")
|
||||
self.assertEqual(rc, 0)
|
||||
time.sleep(1)
|
||||
|
||||
self.wait_online(['macvlan99:degraded', 'test1:degraded'])
|
||||
|
||||
output = check_output('ip -d link show test1')
|
||||
print(output)
|
||||
self.assertRegex(output, ' mtu 2000 ')
|
||||
|
||||
output = check_output('ip -d link show macvlan99')
|
||||
print(output)
|
||||
self.assertRegex(output, ' mtu 2000 ')
|
||||
self.assertRegex(output, 'macvlan mode ' + mode + ' ')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('ipvlan')
|
||||
def test_ipvlan(self):
|
||||
for mode, flag in [['L2', 'private'], ['L3', 'vepa'], ['L3S', 'bridge']]:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user