1
0
mirror of https://github.com/systemd/systemd synced 2026-03-28 17:54:51 +01:00

Compare commits

..

No commits in common. "73bf0f2ace1472ceb72295e0fe5e425998af8a86" and "adbd80f51088058d55e703abe0ac11476cfe0ba4" have entirely different histories.

50 changed files with 292 additions and 468 deletions

View File

@ -20,9 +20,9 @@ jobs:
env: env:
- { COMPILER: "gcc", COMPILER_VERSION: "10" } - { COMPILER: "gcc", COMPILER_VERSION: "10" }
- { COMPILER: "gcc", COMPILER_VERSION: "11" } - { COMPILER: "gcc", COMPILER_VERSION: "11" }
- { COMPILER: "clang", COMPILER_VERSION: "10" }
- { COMPILER: "clang", COMPILER_VERSION: "11" } - { COMPILER: "clang", COMPILER_VERSION: "11" }
- { COMPILER: "clang", COMPILER_VERSION: "12" } - { COMPILER: "clang", COMPILER_VERSION: "12" }
- { COMPILER: "clang", COMPILER_VERSION: "13" }
env: ${{ matrix.env }} env: ${{ matrix.env }}
steps: steps:
- name: Repository checkout - name: Repository checkout

View File

@ -151,16 +151,6 @@
<listitem><para>Decrease the timeout</para></listitem> <listitem><para>Decrease the timeout</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><keycap>r</keycap></term>
<listitem><para>Change screen resolution, skipping any unsupported modes.</para></listitem>
</varlistentry>
<varlistentry>
<term><keycap>R</keycap></term>
<listitem><para>Reset screen resolution to firmware or configuration file default.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><keycap>p</keycap></term> <term><keycap>p</keycap></term>
<listitem><para>Print status</para></listitem> <listitem><para>Print status</para></listitem>

View File

@ -30,16 +30,14 @@
/* The maximum size of the file we'll read in one go in read_full_file() (64M). */ /* The maximum size of the file we'll read in one go in read_full_file() (64M). */
#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U) #define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U)
/* The maximum size of virtual files (i.e. procfs, sysfs, and other virtual "API" files) we'll read in one go /* The maximum size of virtual files we'll read in one go in read_virtual_file() (4M). Note that this limit
* in read_virtual_file(). Note that this limit is different (and much lower) than the READ_FULL_BYTES_MAX * is different (and much lower) than the READ_FULL_BYTES_MAX limit. This reflects the fact that we use
* limit. This reflects the fact that we use different strategies for reading virtual and regular files: * different strategies for reading virtual and regular files: virtual files are generally size constrained:
* virtual files we generally have to read in a single read() syscall since the kernel doesn't support * there we allocate the full buffer size in advance. Regular files OTOH can be much larger, and here we grow
* continuation read()s for them. Thankfully they are somewhat size constrained. Thus we can allocate the * the allocations exponentially in a loop. In glibc large allocations are immediately backed by mmap()
* full potential buffer in advance. Regular files OTOH can be much larger, and there we grow the allocations * making them relatively slow (measurably so). Thus, when allocating the full buffer in advance the large
* exponentially in a loop. We use a size limit of 4M-2 because 4M-1 is the maximum buffer that /proc/sys/ * limit is a problem. When allocating piecemeal it's not. Hence pick two distinct limits. */
* allows us to read() (larger reads will fail with ENOMEM), and we want to read one extra byte so that we #define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 1U)
* can detect EOFs. */
#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 2U)
int fopen_unlocked(const char *path, const char *options, FILE **ret) { int fopen_unlocked(const char *path, const char *options, FILE **ret) {
assert(ret); assert(ret);
@ -395,7 +393,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
* contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on * contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on
* partial success, 1 if untruncated contents were read. */ * partial success, 1 if untruncated contents were read. */
fd = open(filename, O_RDONLY|O_NOCTTY|O_CLOEXEC); fd = open(filename, O_RDONLY|O_CLOEXEC);
if (fd < 0) if (fd < 0)
return -errno; return -errno;

View File

@ -3,15 +3,15 @@
#include "nulstr-util.h" #include "nulstr-util.h"
#include "string-util.h" #include "string-util.h"
const char* nulstr_get(const char *nulstr, const char *needle) { bool nulstr_contains(const char *nulstr, const char *needle) {
const char *i; const char *i;
if (!nulstr) if (!nulstr)
return NULL; return false;
NULSTR_FOREACH(i, nulstr) NULSTR_FOREACH(i, nulstr)
if (streq(i, needle)) if (streq(i, needle))
return i; return true;
return NULL; return false;
} }

View File

@ -10,8 +10,4 @@
#define NULSTR_FOREACH_PAIR(i, j, l) \ #define NULSTR_FOREACH_PAIR(i, j, l) \
for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
const char* nulstr_get(const char *nulstr, const char *needle); bool nulstr_contains(const char *nulstr, const char *needle);
static inline bool nulstr_contains(const char *nulstr, const char *needle) {
return nulstr_get(nulstr, needle);
}

View File

@ -1254,7 +1254,7 @@ int safe_fork_full(
pid_t original_pid, pid; pid_t original_pid, pid;
sigset_t saved_ss, ss; sigset_t saved_ss, ss;
_unused_ _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL; _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL;
bool block_signals = false, block_all = false; bool block_signals = false, block_all = false;
int prio, r; int prio, r;

View File

@ -793,7 +793,7 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
/* Let's refuse "all" and "default" as interface name, to avoid collisions with the special sysctl /* Let's refuse "all" and "default" as interface name, to avoid collisions with the special sysctl
* directories /proc/sys/net/{ipv4,ipv6}/conf/{all,default} */ * directories /proc/sys/net/{ipv4,ipv6}/conf/{all,default} */
if (!FLAGS_SET(flags, IFNAME_VALID_SPECIAL) && STR_IN_SET(p, "all", "default")) if (STR_IN_SET(p, "all", "default"))
return false; return false;
for (const char *t = p; *t; t++) { for (const char *t = p; *t; t++) {

View File

@ -135,10 +135,9 @@ int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s); int ip_tos_from_string(const char *s);
typedef enum { typedef enum {
IFNAME_VALID_ALTERNATIVE = 1 << 0, /* Allow "altnames" too */ IFNAME_VALID_ALTERNATIVE = 1 << 0,
IFNAME_VALID_NUMERIC = 1 << 1, /* Allow decimal formatted ifindexes too */ IFNAME_VALID_NUMERIC = 1 << 1,
IFNAME_VALID_SPECIAL = 1 << 2, /* Allow the special names "all" and "default" */ _IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC,
_IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC | IFNAME_VALID_SPECIAL,
} IfnameValidFlags; } IfnameValidFlags;
bool ifname_valid_char(char a); bool ifname_valid_char(char a);
bool ifname_valid_full(const char *p, IfnameValidFlags flags); bool ifname_valid_full(const char *p, IfnameValidFlags flags);

View File

@ -5,13 +5,11 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include "af-list.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "log.h" #include "log.h"
#include "macro.h" #include "macro.h"
#include "path-util.h" #include "path-util.h"
#include "socket-util.h"
#include "string-util.h" #include "string-util.h"
#include "sysctl-util.h" #include "sysctl-util.h"
@ -38,7 +36,7 @@ char *sysctl_normalize(char *s) {
path_simplify(s); path_simplify(s);
/* Kill the leading slash, but keep the first character of the string in the same place. */ /* Kill the leading slash, but keep the first character of the string in the same place. */
if (s[0] == '/' && s[1] != 0) if (*s == '/' && *(s+1))
memmove(s, s+1, strlen(s)); memmove(s, s+1, strlen(s));
return s; return s;
@ -46,19 +44,25 @@ char *sysctl_normalize(char *s) {
int sysctl_write(const char *property, const char *value) { int sysctl_write(const char *property, const char *value) {
char *p; char *p;
_cleanup_close_ int fd = -1;
assert(property); assert(property);
assert(value); assert(value);
log_debug("Setting '%s' to '%.*s'.", property, (int) strcspn(value, NEWLINE), value);
p = strjoina("/proc/sys/", property); p = strjoina("/proc/sys/", property);
fd = open(p, O_WRONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
path_simplify(p); if (!endswith(value, "\n"))
if (!path_is_normalized(p)) value = strjoina(value, "\n");
return -EINVAL;
log_debug("Setting '%s' to '%s'", p, value); if (write(fd, value, strlen(value)) < 0)
return -errno;
return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER); return 0;
} }
int sysctl_writef(const char *property, const char *format, ...) { int sysctl_writef(const char *property, const char *format, ...) {
@ -79,59 +83,48 @@ int sysctl_writef(const char *property, const char *format, ...) {
int sysctl_write_ip_property(int af, const char *ifname, const char *property, const char *value) { int sysctl_write_ip_property(int af, const char *ifname, const char *property, const char *value) {
const char *p; const char *p;
assert(IN_SET(af, AF_INET, AF_INET6));
assert(property); assert(property);
assert(value); assert(value);
if (!IN_SET(af, AF_INET, AF_INET6)) p = strjoina("/proc/sys/net/ipv", af == AF_INET ? "4" : "6",
return -EAFNOSUPPORT; ifname ? "/conf/" : "", strempty(ifname),
property[0] == '/' ? "" : "/", property);
if (ifname) { log_debug("Setting '%s' to '%s'", p, value);
if (!ifname_valid_full(ifname, IFNAME_VALID_SPECIAL))
return -EINVAL;
p = strjoina("net/", af_to_ipv4_ipv6(af), "/conf/", ifname, "/", property); return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
} else
p = strjoina("net/", af_to_ipv4_ipv6(af), "/", property);
return sysctl_write(p, value);
} }
int sysctl_read(const char *property, char **ret) { int sysctl_read(const char *property, char **ret) {
char *p; char *p;
int r;
assert(property); assert(property);
assert(ret);
p = strjoina("/proc/sys/", property); p = strjoina("/proc/sys/", property);
return read_full_virtual_file(p, ret, NULL);
path_simplify(p);
if (!path_is_normalized(p)) /* Filter out attempts to write to /proc/sys/../../…, just in case */
return -EINVAL;
r = read_full_virtual_file(p, ret, NULL);
if (r < 0)
return r;
if (ret)
delete_trailing_chars(*ret, NEWLINE);
return r;
} }
int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret) { int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret) {
_cleanup_free_ char *value = NULL;
const char *p; const char *p;
int r;
assert(IN_SET(af, AF_INET, AF_INET6));
assert(property); assert(property);
if (!IN_SET(af, AF_INET, AF_INET6)) p = strjoina("/proc/sys/net/ipv", af == AF_INET ? "4" : "6",
return -EAFNOSUPPORT; ifname ? "/conf/" : "", strempty(ifname),
property[0] == '/' ? "" : "/", property);
if (ifname) { r = read_full_virtual_file(p, &value, NULL);
if (!ifname_valid_full(ifname, IFNAME_VALID_SPECIAL)) if (r < 0)
return -EINVAL; return r;
p = strjoina("net/", af_to_ipv4_ipv6(af), "/conf/", ifname, "/", property); truncate_nl(value);
} else if (ret)
p = strjoina("net/", af_to_ipv4_ipv6(af), "/", property); *ret = TAKE_PTR(value);
return sysctl_read(p, ret); return r;
} }

View File

@ -286,8 +286,7 @@ int unit_file_build_name_map(
FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) { FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
char *filename; char *filename;
_unused_ _cleanup_free_ char *_filename_free = NULL; _cleanup_free_ char *_filename_free = NULL, *simplified = NULL;
_cleanup_free_ char *simplified = NULL;
const char *suffix, *dst = NULL; const char *suffix, *dst = NULL;
bool valid_unit_name; bool valid_unit_name;

View File

@ -69,8 +69,8 @@ typedef struct {
BOOLEAN auto_entries; BOOLEAN auto_entries;
BOOLEAN auto_firmware; BOOLEAN auto_firmware;
BOOLEAN force_menu; BOOLEAN force_menu;
INT64 console_mode; UINTN console_mode;
INT64 console_mode_efivar; enum console_mode_change_type console_mode_change;
RandomSeedMode random_seed_mode; RandomSeedMode random_seed_mode;
} Config; } Config;
@ -370,13 +370,13 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
UINTN timeout; UINTN timeout;
BOOLEAN modevar; BOOLEAN modevar;
_cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL; _cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL;
UINTN x_max, y_max; UINTN x, y;
assert(config); assert(config);
assert(loaded_image_path); assert(loaded_image_path);
clear_screen(COLOR_NORMAL); uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, COLOR_NORMAL);
console_query_mode(&x_max, &y_max); uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
Print(L"systemd-boot version: " GIT_VERSION "\n"); Print(L"systemd-boot version: " GIT_VERSION "\n");
Print(L"architecture: " EFI_MACHINE_TYPE_NAME "\n"); Print(L"architecture: " EFI_MACHINE_TYPE_NAME "\n");
@ -384,8 +384,10 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L"UEFI specification: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); Print(L"UEFI specification: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
Print(L"firmware vendor: %s\n", ST->FirmwareVendor); Print(L"firmware vendor: %s\n", ST->FirmwareVendor);
Print(L"firmware version: %d.%02d\n", ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); Print(L"firmware version: %d.%02d\n", ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
Print(L"console mode: %d/%ld\n", ST->ConOut->Mode->Mode, ST->ConOut->Mode->MaxMode - 1LL);
Print(L"console size: %d x %d\n", x_max, y_max); if (uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &x, &y) == EFI_SUCCESS)
Print(L"console size: %d x %d\n", x, y);
Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled())); Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled()));
if (efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &modevar) == EFI_SUCCESS) if (efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &modevar) == EFI_SUCCESS)
@ -497,6 +499,8 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L"\n--- press key ---\n\n"); Print(L"\n--- press key ---\n\n");
console_key_read(&key, 0); console_key_read(&key, 0);
} }
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
} }
static BOOLEAN menu_run( static BOOLEAN menu_run(
@ -509,115 +513,107 @@ static BOOLEAN menu_run(
assert(loaded_image_path); assert(loaded_image_path);
EFI_STATUS err; EFI_STATUS err;
UINTN visible_max = 0; UINTN visible_max;
UINTN idx_highlight = config->idx_default; UINTN idx_highlight = config->idx_default;
UINTN idx_highlight_prev = 0; UINTN idx_highlight_prev = 0;
UINTN idx_first = 0, idx_last = 0; UINTN idx_first;
BOOLEAN new_mode = TRUE, clear = TRUE; UINTN idx_last;
BOOLEAN refresh = TRUE, highlight = FALSE; BOOLEAN refresh = TRUE;
UINTN x_start = 0, y_start = 0, y_status = 0; BOOLEAN highlight = FALSE;
UINTN x_max, y_max; UINTN line_width = 0;
CHAR16 **lines = NULL, *status = NULL, *clearline = NULL; UINTN entry_padding = 3;
CHAR16 **lines;
UINTN x_start;
UINTN y_start;
UINTN x_max;
UINTN y_max;
CHAR16 *status = NULL;
CHAR16 *clearline;
UINTN timeout_remain = config->timeout_sec; UINTN timeout_remain = config->timeout_sec;
INT16 idx; INT16 idx;
BOOLEAN exit = FALSE, run = TRUE; BOOLEAN exit = FALSE;
INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar; BOOLEAN run = TRUE;
graphics_mode(FALSE); graphics_mode(FALSE);
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE); uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE); uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, COLOR_NORMAL);
/* draw a single character to make ClearScreen work on some firmware */ /* draw a single character to make ClearScreen work on some firmware */
Print(L" "); Print(L" ");
err = console_set_mode(config->console_mode_efivar != CONSOLE_MODE_KEEP ? if (config->console_mode_change != CONSOLE_MODE_KEEP) {
config->console_mode_efivar : config->console_mode); 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);
}
} else
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
err = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &x_max, &y_max);
if (EFI_ERROR(err)) { if (EFI_ERROR(err)) {
clear_screen(COLOR_NORMAL); x_max = 80;
log_error_stall(L"Error switching console mode: %r", err); y_max = 25;
} }
visible_max = y_max - 2;
/* Drawing entries starts at idx_first until idx_last. We want to make
* sure that idx_highlight is centered, but not if we are close to the
* beginning/end of the entry list. Otherwise we would have a half-empty
* screen. */
if (config->entry_count <= visible_max || idx_highlight <= visible_max / 2)
idx_first = 0;
else if (idx_highlight >= config->entry_count - (visible_max / 2))
idx_first = config->entry_count - visible_max;
else
idx_first = idx_highlight - (visible_max / 2);
idx_last = idx_first + visible_max - 1;
/* length of the longest entry */
for (UINTN i = 0; i < config->entry_count; i++)
line_width = MAX(line_width, StrLen(config->entries[i]->title_show));
line_width = MIN(line_width + 2 * entry_padding, x_max);
/* offsets to center the entries on the screen */
x_start = (x_max - (line_width)) / 2;
if (config->entry_count < visible_max)
y_start = ((visible_max - config->entry_count) / 2) + 1;
else
y_start = 0;
/* menu entries title lines */
lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count);
for (UINTN i = 0; i < config->entry_count; i++) {
UINTN j;
lines[i] = AllocatePool(((line_width + 1) * sizeof(CHAR16)));
UINTN padding = (line_width - MIN(StrLen(config->entries[i]->title_show), line_width)) / 2;
for (j = 0; j < padding; j++)
lines[i][j] = ' ';
for (UINTN k = 0; config->entries[i]->title_show[k] != '\0' && j < line_width; j++, k++)
lines[i][j] = config->entries[i]->title_show[k];
for (; j < line_width; j++)
lines[i][j] = ' ';
lines[i][line_width] = '\0';
}
clearline = AllocatePool((x_max+1) * sizeof(CHAR16));
for (UINTN i = 0; i < x_max; i++)
clearline[i] = ' ';
clearline[x_max] = 0;
while (!exit) { while (!exit) {
UINT64 key; UINT64 key;
if (new_mode) {
UINTN line_width = 0, entry_padding = 3;
console_query_mode(&x_max, &y_max);
/* account for padding+status */
visible_max = y_max - 2;
/* Drawing entries starts at idx_first until idx_last. We want to make
* sure that idx_highlight is centered, but not if we are close to the
* beginning/end of the entry list. Otherwise we would have a half-empty
* screen. */
if (config->entry_count <= visible_max || idx_highlight <= visible_max / 2)
idx_first = 0;
else if (idx_highlight >= config->entry_count - (visible_max / 2))
idx_first = config->entry_count - visible_max;
else
idx_first = idx_highlight - (visible_max / 2);
idx_last = idx_first + visible_max - 1;
/* length of the longest entry */
for (UINTN i = 0; i < config->entry_count; i++)
line_width = MAX(line_width, StrLen(config->entries[i]->title_show));
line_width = MIN(line_width + 2 * entry_padding, x_max);
/* offsets to center the entries on the screen */
x_start = (x_max - (line_width)) / 2;
if (config->entry_count < visible_max)
y_start = ((visible_max - config->entry_count) / 2) + 1;
else
y_start = 0;
/* Put status line after the entry list, but give it some breathing room. */
y_status = MIN(y_start + MIN(visible_max, config->entry_count) + 4, y_max - 1);
if (lines) {
for (UINTN i = 0; i < config->entry_count; i++)
FreePool(lines[i]);
FreePool(lines);
FreePool(clearline);
}
/* menu entries title lines */
lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count);
for (UINTN i = 0; i < config->entry_count; i++) {
UINTN j, padding;
lines[i] = AllocatePool(((line_width + 1) * sizeof(CHAR16)));
padding = (line_width - MIN(StrLen(config->entries[i]->title_show), line_width)) / 2;
for (j = 0; j < padding; j++)
lines[i][j] = ' ';
for (UINTN k = 0; config->entries[i]->title_show[k] != '\0' && j < line_width; j++, k++)
lines[i][j] = config->entries[i]->title_show[k];
for (; j < line_width; j++)
lines[i][j] = ' ';
lines[i][line_width] = '\0';
}
clearline = AllocatePool((x_max+1) * sizeof(CHAR16));
for (UINTN i = 0; i < x_max; i++)
clearline[i] = ' ';
clearline[x_max] = 0;
new_mode = FALSE;
clear = TRUE;
}
if (clear) {
clear_screen(COLOR_NORMAL);
clear = FALSE;
refresh = TRUE;
}
if (refresh) { if (refresh) {
for (UINTN i = idx_first; i <= idx_last && i < config->entry_count; i++) { for (UINTN i = 0; i < config->entry_count; i++) {
if (i < idx_first || i > idx_last)
continue;
print_at(x_start, y_start + i - idx_first, print_at(x_start, y_start + i - idx_first,
(i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_ENTRY, (i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_ENTRY,
lines[i]); lines[i]);
@ -653,7 +649,7 @@ static BOOLEAN menu_run(
x = (x_max - len) / 2; x = (x_max - len) / 2;
else else
x = 0; x = 0;
print_at(0, y_status, COLOR_NORMAL, clearline + (x_max - x)); print_at(0, y_max - 1, COLOR_NORMAL, clearline + (x_max - x));
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, status); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, status);
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len);
} }
@ -675,7 +671,7 @@ static BOOLEAN menu_run(
if (status) { if (status) {
FreePool(status); FreePool(status);
status = NULL; status = NULL;
print_at(0, y_status, COLOR_NORMAL, clearline + 1); print_at(0, y_max - 1, COLOR_NORMAL, clearline + 1);
} }
idx_highlight_prev = idx_highlight; idx_highlight_prev = idx_highlight;
@ -737,7 +733,7 @@ static BOOLEAN menu_run(
case KEYPRESS(0, 0, 'H'): case KEYPRESS(0, 0, 'H'):
case KEYPRESS(0, 0, '?'): case KEYPRESS(0, 0, '?'):
/* This must stay below 80 characters! Q/v/Ctrl+l deliberately not advertised. */ /* This must stay below 80 characters! Q/v/Ctrl+l deliberately not advertised. */
status = StrDuplicate(L"(d)efault (t/T)timeout (e)dit (r/R)resolution (p)rint (h)elp"); status = StrDuplicate(L"(d)efault (t/T)timeout (e)dit (p)rint (h)elp");
break; break;
case KEYPRESS(0, 0, 'Q'): case KEYPRESS(0, 0, 'Q'):
@ -817,9 +813,9 @@ static BOOLEAN menu_run(
* causing a scroll to happen that screws with our beautiful boot loader output. * causing a scroll to happen that screws with our beautiful boot loader output.
* Since we cannot paint the last character of the edit line, we simply start * Since we cannot paint the last character of the edit line, we simply start
* at x-offset 1 for symmetry. */ * at x-offset 1 for symmetry. */
print_at(1, y_status, COLOR_EDIT, clearline + 2); print_at(1, y_max - 1, COLOR_EDIT, clearline + 2);
exit = line_edit(config->entries[idx_highlight]->options, &config->options_edit, x_max - 2, y_status); exit = line_edit(config->entries[idx_highlight]->options, &config->options_edit, x_max-2, y_max-1);
print_at(1, y_status, COLOR_NORMAL, clearline + 2); print_at(1, y_max - 1, COLOR_NORMAL, clearline + 2);
break; break;
case KEYPRESS(0, 0, 'v'): case KEYPRESS(0, 0, 'v'):
@ -831,35 +827,12 @@ static BOOLEAN menu_run(
case KEYPRESS(0, 0, 'p'): case KEYPRESS(0, 0, 'p'):
case KEYPRESS(0, 0, 'P'): case KEYPRESS(0, 0, 'P'):
print_status(config, loaded_image_path); print_status(config, loaded_image_path);
clear = TRUE; refresh = TRUE;
break; break;
case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'l'): case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'l'):
case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('l')): case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('l')):
clear = TRUE; refresh = TRUE;
break;
case KEYPRESS(0, 0, 'r'):
err = console_set_mode(CONSOLE_MODE_NEXT);
if (EFI_ERROR(err))
status = PoolPrint(L"Error changing console mode: %r", err);
else {
config->console_mode_efivar = ST->ConOut->Mode->Mode;
status = PoolPrint(L"Console mode changed to %ld.", config->console_mode_efivar);
}
new_mode = TRUE;
break;
case KEYPRESS(0, 0, 'R'):
config->console_mode_efivar = CONSOLE_MODE_KEEP;
err = console_set_mode(config->console_mode == CONSOLE_MODE_KEEP ?
console_mode_initial : config->console_mode);
if (EFI_ERROR(err))
status = PoolPrint(L"Error resetting console mode: %r", err);
else
status = PoolPrint(L"Console mode reset to %s default.",
config->console_mode == CONSOLE_MODE_KEEP ? L"firmware" : L"configuration file");
new_mode = TRUE;
break; break;
default: default:
@ -887,23 +860,13 @@ static BOOLEAN menu_run(
*chosen_entry = config->entries[idx_highlight]; *chosen_entry = config->entries[idx_highlight];
/* The user is likely to cycle through several modes before
* deciding to keep one. Therefore, we update the EFI var after
* we left the menu to reduce nvram writes. */
if (console_mode_efivar_saved != config->console_mode_efivar) {
if (config->console_mode_efivar == CONSOLE_MODE_KEEP)
efivar_set(LOADER_GUID, L"LoaderConfigConsoleMode", NULL, EFI_VARIABLE_NON_VOLATILE);
else
efivar_set_uint_string(LOADER_GUID, L"LoaderConfigConsoleMode",
config->console_mode_efivar, EFI_VARIABLE_NON_VOLATILE);
}
for (UINTN i = 0; i < config->entry_count; i++) for (UINTN i = 0; i < config->entry_count; i++)
FreePool(lines[i]); FreePool(lines[i]);
FreePool(lines); FreePool(lines);
FreePool(clearline); FreePool(clearline);
clear_screen(COLOR_NORMAL); uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, COLOR_NORMAL);
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
return run; return run;
} }
@ -1064,16 +1027,17 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) {
if (strcmpa((CHAR8 *)"console-mode", key) == 0) { if (strcmpa((CHAR8 *)"console-mode", key) == 0) {
if (strcmpa((CHAR8 *)"auto", value) == 0) if (strcmpa((CHAR8 *)"auto", value) == 0)
config->console_mode = CONSOLE_MODE_AUTO; config->console_mode_change = CONSOLE_MODE_AUTO;
else if (strcmpa((CHAR8 *)"max", value) == 0) else if (strcmpa((CHAR8 *)"max", value) == 0)
config->console_mode = CONSOLE_MODE_FIRMWARE_MAX; config->console_mode_change = CONSOLE_MODE_MAX;
else if (strcmpa((CHAR8 *)"keep", value) == 0) else if (strcmpa((CHAR8 *)"keep", value) == 0)
config->console_mode = CONSOLE_MODE_KEEP; config->console_mode_change = CONSOLE_MODE_KEEP;
else { else {
_cleanup_freepool_ CHAR16 *s = NULL; _cleanup_freepool_ CHAR16 *s = NULL;
s = stra_to_str(value); s = stra_to_str(value);
config->console_mode = MIN(Atoi(s), (UINTN)CONSOLE_MODE_RANGE_MAX); config->console_mode = Atoi(s);
config->console_mode_change = CONSOLE_MODE_SET;
} }
continue; continue;
@ -1446,7 +1410,7 @@ static VOID config_entry_add_from_file(
static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
_cleanup_freepool_ CHAR8 *content = NULL; _cleanup_freepool_ CHAR8 *content = NULL;
UINTN value; UINTN sec;
EFI_STATUS err; EFI_STATUS err;
assert(root_dir); assert(root_dir);
@ -1457,33 +1421,27 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
.auto_firmware = TRUE, .auto_firmware = TRUE,
.random_seed_mode = RANDOM_SEED_WITH_SYSTEM_TOKEN, .random_seed_mode = RANDOM_SEED_WITH_SYSTEM_TOKEN,
.idx_default_efivar = -1, .idx_default_efivar = -1,
.console_mode = CONSOLE_MODE_KEEP,
.console_mode_efivar = CONSOLE_MODE_KEEP,
}; };
err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL); err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL);
if (!EFI_ERROR(err)) if (!EFI_ERROR(err))
config_defaults_load_from_file(config, content); config_defaults_load_from_file(config, content);
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &value); err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &sec);
if (!EFI_ERROR(err)) { if (!EFI_ERROR(err)) {
config->timeout_sec_efivar = value > INTN_MAX ? INTN_MAX : value; config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec;
config->timeout_sec = value; config->timeout_sec = sec;
} else } else
config->timeout_sec_efivar = -1; config->timeout_sec_efivar = -1;
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &value); err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &sec);
if (!EFI_ERROR(err)) { if (!EFI_ERROR(err)) {
/* Unset variable now, after all it's "one shot". */ /* Unset variable now, after all it's "one shot". */
(void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, EFI_VARIABLE_NON_VOLATILE); (void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
config->timeout_sec = value; config->timeout_sec = sec;
config->force_menu = TRUE; /* force the menu when this is set */ config->force_menu = TRUE; /* force the menu when this is set */
} }
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigConsoleMode", &value);
if (!EFI_ERROR(err))
config->console_mode_efivar = value;
} }
static VOID config_load_entries( static VOID config_load_entries(

View File

@ -8,9 +8,6 @@
#define SYSTEM_FONT_WIDTH 8 #define SYSTEM_FONT_WIDTH 8
#define SYSTEM_FONT_HEIGHT 19 #define SYSTEM_FONT_HEIGHT 19
#define HORIZONTAL_MAX_OK 1920
#define VERTICAL_MAX_OK 1080
#define VIEWPORT_RATIO 10
#define EFI_SIMPLE_TEXT_INPUT_EX_GUID \ #define EFI_SIMPLE_TEXT_INPUT_EX_GUID \
&(const EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID &(const EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
@ -118,36 +115,51 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
static EFI_STATUS change_mode(INT64 mode) { static EFI_STATUS change_mode(UINTN mode) {
EFI_STATUS err; EFI_STATUS err;
INT32 old_mode;
/* SetMode expects a UINTN, so make sure these values are sane. */
mode = CLAMP(mode, CONSOLE_MODE_RANGE_MIN, CONSOLE_MODE_RANGE_MAX);
old_mode = MAX(CONSOLE_MODE_RANGE_MIN, ST->ConOut->Mode->Mode);
err = uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, mode); err = uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, mode);
if (!EFI_ERROR(err))
return EFI_SUCCESS;
/* Something went wrong. Output is probably borked, so try to revert to previous mode. */ /* Special case mode 1: when using OVMF and qemu, setting it returns error
if (!EFI_ERROR(uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, old_mode))) * and breaks console output. */
return err; if (EFI_ERROR(err) && mode == 1)
uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, (UINTN)0);
/* Maybe the device is on fire? */
uefi_call_wrapper(ST->ConOut->Reset, 2, ST->ConOut, TRUE);
uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, CONSOLE_MODE_RANGE_MIN);
return err; return err;
} }
static INT64 get_auto_mode(void) { static UINT64 text_area_from_font_size(void) {
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_STATUS err; EFI_STATUS err;
UINT64 text_area;
UINTN rows, columns;
err = LibLocateProtocol(&GraphicsOutputProtocol, (VOID **)&GraphicsOutput); err = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &columns, &rows);
if (EFI_ERROR(err)) {
columns = 80;
rows = 25;
}
text_area = SYSTEM_FONT_WIDTH * SYSTEM_FONT_HEIGHT * (UINT64)rows * (UINT64)columns;
return text_area;
}
static EFI_STATUS mode_auto(UINTN *mode) {
const UINT32 HORIZONTAL_MAX_OK = 1920;
const UINT32 VERTICAL_MAX_OK = 1080;
const UINT64 VIEWPORT_RATIO = 10;
UINT64 screen_area, text_area;
static const EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
EFI_STATUS err;
BOOLEAN keep = FALSE;
assert(mode);
err = LibLocateProtocol((EFI_GUID*) &GraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
if (!EFI_ERROR(err) && GraphicsOutput->Mode && GraphicsOutput->Mode->Info) { if (!EFI_ERROR(err) && GraphicsOutput->Mode && GraphicsOutput->Mode->Info) {
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info = GraphicsOutput->Mode->Info; Info = GraphicsOutput->Mode->Info;
BOOLEAN keep = FALSE;
/* Start verifying if we are in a resolution larger than Full HD /* Start verifying if we are in a resolution larger than Full HD
* (1920x1080). If we're not, assume we're in a good mode and do not * (1920x1080). If we're not, assume we're in a good mode and do not
@ -158,19 +170,19 @@ static INT64 get_auto_mode(void) {
* area to the text viewport area. If it's less than 10 times bigger, * area to the text viewport area. If it's less than 10 times bigger,
* then assume the text is readable and keep the text mode. */ * then assume the text is readable and keep the text mode. */
else { else {
UINT64 text_area; screen_area = (UINT64)Info->HorizontalResolution * (UINT64)Info->VerticalResolution;
UINTN x_max, y_max; text_area = text_area_from_font_size();
UINT64 screen_area = (UINT64)Info->HorizontalResolution * (UINT64)Info->VerticalResolution;
console_query_mode(&x_max, &y_max);
text_area = SYSTEM_FONT_WIDTH * SYSTEM_FONT_HEIGHT * (UINT64)x_max * (UINT64)y_max;
if (text_area != 0 && screen_area/text_area < VIEWPORT_RATIO) if (text_area != 0 && screen_area/text_area < VIEWPORT_RATIO)
keep = TRUE; keep = TRUE;
} }
}
if (keep) if (keep) {
return ST->ConOut->Mode->Mode; /* Just clear the screen instead of changing the mode and return. */
*mode = ST->ConOut->Mode->Mode;
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
return EFI_SUCCESS;
} }
/* If we reached here, then we have a high resolution screen and the text /* If we reached here, then we have a high resolution screen and the text
@ -179,72 +191,32 @@ static INT64 get_auto_mode(void) {
* standard mode, which is provided by the device manufacturer, so it should * standard mode, which is provided by the device manufacturer, so it should
* be a good mode. * be a good mode.
* Note: MaxMode is the number of modes, not the last mode. */ * Note: MaxMode is the number of modes, not the last mode. */
if (ST->ConOut->Mode->MaxMode > CONSOLE_MODE_FIRMWARE_FIRST) if (ST->ConOut->Mode->MaxMode > 2)
return CONSOLE_MODE_FIRMWARE_FIRST; *mode = 2;
/* Try again with mode different than zero (assume user requests /* Try again with mode different than zero (assume user requests
* auto mode due to some problem with mode zero). */ * auto mode due to some problem with mode zero). */
if (ST->ConOut->Mode->MaxMode > CONSOLE_MODE_80_50) else if (ST->ConOut->Mode->MaxMode == 2)
return CONSOLE_MODE_80_50; *mode = 1;
/* Else force mode change to zero. */
else
*mode = 0;
return CONSOLE_MODE_80_25; return change_mode(*mode);
} }
EFI_STATUS console_set_mode(INT64 mode) { EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how) {
switch (mode) { assert(mode);
case CONSOLE_MODE_KEEP:
/* If the firmware indicates the current mode is invalid, change it anyway. */
if (ST->ConOut->Mode->Mode < CONSOLE_MODE_RANGE_MIN)
return change_mode(CONSOLE_MODE_RANGE_MIN);
return EFI_SUCCESS;
case CONSOLE_MODE_NEXT: if (how == CONSOLE_MODE_AUTO)
if (ST->ConOut->Mode->MaxMode <= CONSOLE_MODE_RANGE_MIN) return mode_auto(mode);
return EFI_UNSUPPORTED;
mode = MAX(CONSOLE_MODE_RANGE_MIN, ST->ConOut->Mode->Mode); if (how == CONSOLE_MODE_MAX) {
do {
mode = (mode + 1) % ST->ConOut->Mode->MaxMode;
if (!EFI_ERROR(change_mode(mode)))
break;
/* If this mode is broken/unsupported, try the next.
* If mode is 0, we wrapped around and should stop. */
} while (mode > CONSOLE_MODE_RANGE_MIN);
return EFI_SUCCESS;
case CONSOLE_MODE_AUTO:
return change_mode(get_auto_mode());
case CONSOLE_MODE_FIRMWARE_MAX:
/* Note: MaxMode is the number of modes, not the last mode. */ /* Note: MaxMode is the number of modes, not the last mode. */
return change_mode(ST->ConOut->Mode->MaxMode - 1LL); if (ST->ConOut->Mode->MaxMode > 0)
*mode = ST->ConOut->Mode->MaxMode-1;
default: else
return change_mode(mode); *mode = 0;
}
}
EFI_STATUS console_query_mode(UINTN *x_max, UINTN *y_max) {
EFI_STATUS err;
assert(x_max);
assert(y_max);
err = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, x_max, y_max);
if (EFI_ERROR(err)) {
/* Fallback values mandated by UEFI spec. */
switch (ST->ConOut->Mode->Mode) {
case CONSOLE_MODE_80_50:
*x_max = 80;
*y_max = 50;
break;
case CONSOLE_MODE_80_25:
default:
*x_max = 80;
*y_max = 25;
}
} }
return err; return change_mode(*mode);
} }

View File

@ -9,23 +9,12 @@
#define KEYCHAR(k) ((k) & 0xffff) #define KEYCHAR(k) ((k) & 0xffff)
#define CHAR_CTRL(c) ((c) - 'a' + 1) #define CHAR_CTRL(c) ((c) - 'a' + 1)
enum { enum console_mode_change_type {
/* Console mode is a INT32 in EFI. We use INT64 to make room for our special values. */ CONSOLE_MODE_KEEP = 0,
CONSOLE_MODE_RANGE_MIN = 0, CONSOLE_MODE_SET,
CONSOLE_MODE_RANGE_MAX = INT32_MAX, /* This is just the theoretical limit. */
CONSOLE_MODE_INVALID = -1, /* UEFI uses -1 if the device is not in a valid text mode. */
CONSOLE_MODE_80_25 = 0, /* 80x25 is required by UEFI spec. */
CONSOLE_MODE_80_50 = 1, /* 80x50 may be supported. */
CONSOLE_MODE_FIRMWARE_FIRST = 2, /* First custom mode, if supported. */
/* These are our own mode values that map to concrete values at runtime. */
CONSOLE_MODE_KEEP = CONSOLE_MODE_RANGE_MAX + 1LL,
CONSOLE_MODE_NEXT,
CONSOLE_MODE_AUTO, CONSOLE_MODE_AUTO,
CONSOLE_MODE_FIRMWARE_MAX, /* 'max' in config. */ CONSOLE_MODE_MAX,
}; };
EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec); EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec);
EFI_STATUS console_set_mode(INT64 mode); EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how);
EFI_STATUS console_query_mode(UINTN *x_max, UINTN *y_max);

View File

@ -522,8 +522,3 @@ VOID print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str) {
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, attr); uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, attr);
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, (CHAR16*)str); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, (CHAR16*)str);
} }
VOID clear_screen(UINTN attr) {
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, attr);
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
}

View File

@ -93,4 +93,3 @@ static inline VOID *mempmem_safe(const VOID *haystack, UINTN haystack_len, const
} }
VOID print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str); VOID print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str);
VOID clear_screen(UINTN attr);

View File

@ -1758,7 +1758,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
{ {
/* This block is (optionally) done with the reloading counter bumped */ /* This block is (optionally) done with the reloading counter bumped */
_unused_ _cleanup_(manager_reloading_stopp) Manager *reloading = NULL; _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
/* If we will deserialize make sure that during enumeration this is already known, so we increase the /* If we will deserialize make sure that during enumeration this is already known, so we increase the
* counter here already */ * counter here already */
@ -3237,7 +3237,7 @@ int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
} }
int manager_reload(Manager *m) { int manager_reload(Manager *m) {
_unused_ _cleanup_(manager_reloading_stopp) Manager *reloading = NULL; _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
_cleanup_fdset_free_ FDSet *fds = NULL; _cleanup_fdset_free_ FDSet *fds = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
int r; int r;

View File

@ -853,7 +853,7 @@ static int mount_private_dev(MountEntry *m) {
char temporary_mount[] = "/tmp/namespace-dev-XXXXXX"; char temporary_mount[] = "/tmp/namespace-dev-XXXXXX";
const char *d, *dev = NULL, *devpts = NULL, *devshm = NULL, *devhugepages = NULL, *devmqueue = NULL, *devlog = NULL, *devptmx = NULL; const char *d, *dev = NULL, *devpts = NULL, *devshm = NULL, *devhugepages = NULL, *devmqueue = NULL, *devlog = NULL, *devptmx = NULL;
bool can_mknod = true; bool can_mknod = true;
_unused_ _cleanup_umask_ mode_t u; _cleanup_umask_ mode_t u;
int r; int r;
assert(m); assert(m);

View File

@ -1674,7 +1674,7 @@ static int run(int argc, char *argv[]) {
verb = argv[1]; verb = argv[1];
if (streq(verb, "attach")) { if (streq(verb, "attach")) {
_unused_ _cleanup_(remove_and_erasep) const char *destroy_key_file = NULL; _cleanup_(remove_and_erasep) const char *destroy_key_file = NULL;
_cleanup_(erase_and_freep) void *key_data = NULL; _cleanup_(erase_and_freep) void *key_data = NULL;
const char *volume, *source, *key_file, *options; const char *volume, *source, *key_file, *options;
crypt_status_info status; crypt_status_info status;

View File

@ -14,7 +14,7 @@
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL; _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r; int r;
log_setup(); log_setup();

View File

@ -166,10 +166,10 @@ static void context_read_os_release(Context *c) {
c->etc_os_release_stat = current_stat; c->etc_os_release_stat = current_stat;
} }
static const char* valid_chassis(const char *chassis) { static bool valid_chassis(const char *chassis) {
assert(chassis); assert(chassis);
return nulstr_get( return nulstr_contains(
"vm\0" "vm\0"
"container\0" "container\0"
"desktop\0" "desktop\0"
@ -190,7 +190,6 @@ static bool valid_deployment(const char *deployment) {
} }
static const char* fallback_chassis(void) { static const char* fallback_chassis(void) {
const char *chassis;
char *type; char *type;
unsigned t; unsigned t;
int v, r; int v, r;
@ -262,14 +261,14 @@ try_acpi:
r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type); r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
if (r < 0) { if (r < 0) {
log_debug_errno(r, "Failed read ACPI PM profile, ignoring: %m"); log_debug_errno(r, "Failed read ACPI PM profile, ignoring: %m");
goto try_devicetree; return NULL;
} }
r = safe_atou(type, &t); r = safe_atou(type, &t);
free(type); free(type);
if (r < 0) { if (r < 0) {
log_debug_errno(r, "Failed parse ACPI PM profile, ignoring: %m"); log_debug_errno(r, "Failed parse ACPI PM profile, ignoring: %m");
goto try_devicetree; return NULL;
} }
/* We only list the really obvious cases here as the ACPI data is not really super reliable. /* We only list the really obvious cases here as the ACPI data is not really super reliable.
@ -301,24 +300,7 @@ try_acpi:
log_debug("Unhandled ACPI PM profile 0x%02x, ignoring.", t); log_debug("Unhandled ACPI PM profile 0x%02x, ignoring.", t);
} }
try_devicetree: return NULL;
r = read_one_line_file("/sys/firmware/devicetree/base/chassis-type", &type);
if (r < 0) {
log_debug_errno(r, "Failed to read device-tree chassis type, ignoring: %m");
return NULL;
}
/* Note that the Devicetree specification uses the very same vocabulary
* of chassis types as we do, hence we do not need to translate these types:
*
* https://github.com/devicetree-org/devicetree-specification/blob/master/source/chapter3-devicenodes.rst */
chassis = valid_chassis(type);
if (!chassis)
log_debug("Invalid device-tree chassis type '%s', ignoring.", type);
free(type);
return chassis;
} }
static char* context_fallback_icon_name(Context *c) { static char* context_fallback_icon_name(Context *c) {

View File

@ -311,7 +311,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(server_done) Server server = { .epoll_fd = -1 }; _cleanup_(server_done) Server server = { .epoll_fd = -1 };
_unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL; _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r, n; int r, n;
if (argc > 1) if (argc > 1)

View File

@ -1099,7 +1099,7 @@ static int load_certificates(char **key, char **cert, char **trust) {
static int run(int argc, char **argv) { static int run(int argc, char **argv) {
_cleanup_(journal_remote_server_destroy) RemoteServer s = {}; _cleanup_(journal_remote_server_destroy) RemoteServer s = {};
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL; _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_(erase_and_freep) char *key = NULL; _cleanup_(erase_and_freep) char *key = NULL;
_cleanup_free_ char *cert = NULL, *trust = NULL; _cleanup_free_ char *cert = NULL, *trust = NULL;
int r; int r;

View File

@ -272,7 +272,7 @@ int journal_remote_add_source(RemoteServer *s, int fd, char* name, bool own_name
int journal_remote_add_raw_socket(RemoteServer *s, int fd) { int journal_remote_add_raw_socket(RemoteServer *s, int fd) {
int r; int r;
_unused_ _cleanup_close_ int fd_ = fd; _cleanup_close_ int fd_ = fd;
char name[STRLEN("raw-socket-") + DECIMAL_STR_MAX(int) + 1]; char name[STRLEN("raw-socket-") + DECIMAL_STR_MAX(int) + 1];
assert(fd >= 0); assert(fd >= 0);

View File

@ -820,7 +820,7 @@ static int open_journal(sd_journal **j) {
static int run(int argc, char **argv) { static int run(int argc, char **argv) {
_cleanup_(destroy_uploader) Uploader u = {}; _cleanup_(destroy_uploader) Uploader u = {};
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL; _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
bool use_journal; bool use_journal;
int r; int r;

View File

@ -903,7 +903,7 @@ static void dispatch_message_real(
pid_t object_pid) { pid_t object_pid) {
char source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)]; char source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)];
_unused_ _cleanup_free_ char *cmdline1 = NULL, *cmdline2 = NULL; _cleanup_free_ char *cmdline1 = NULL, *cmdline2 = NULL;
uid_t journal_uid; uid_t journal_uid;
ClientContext *o; ClientContext *o;

View File

@ -94,8 +94,7 @@ int device_add_property_aux(sd_device *device, const char *key, const char *valu
properties = &device->properties; properties = &device->properties;
if (value) { if (value) {
_unused_ _cleanup_free_ char *old_value = NULL; _cleanup_free_ char *new_key = NULL, *new_value = NULL, *old_key = NULL, *old_value = NULL;
_cleanup_free_ char *new_key = NULL, *new_value = NULL, *old_key = NULL;
int r; int r;
r = ordered_hashmap_ensure_allocated(properties, &string_hash_ops_free_free); r = ordered_hashmap_ensure_allocated(properties, &string_hash_ops_free_free);
@ -120,8 +119,7 @@ int device_add_property_aux(sd_device *device, const char *key, const char *valu
TAKE_PTR(new_key); TAKE_PTR(new_key);
TAKE_PTR(new_value); TAKE_PTR(new_value);
} else { } else {
_unused_ _cleanup_free_ char *old_value = NULL; _cleanup_free_ char *old_key = NULL, *old_value = NULL;
_cleanup_free_ char *old_key = NULL;
old_value = ordered_hashmap_remove2(*properties, key, (void**) &old_key); old_value = ordered_hashmap_remove2(*properties, key, (void**) &old_key);
} }
@ -1941,8 +1939,7 @@ _public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) {
} }
static int device_cache_sysattr_value(sd_device *device, const char *key, char *value) { static int device_cache_sysattr_value(sd_device *device, const char *key, char *value) {
_unused_ _cleanup_free_ char *old_value = NULL; _cleanup_free_ char *new_key = NULL, *old_value = NULL;
_cleanup_free_ char *new_key = NULL;
int r; int r;
assert(device); assert(device);

View File

@ -53,7 +53,7 @@ static void test_catalog_import_invalid(void) {
} }
static void test_catalog_import_badid(void) { static void test_catalog_import_badid(void) {
_unused_ _cleanup_ordered_hashmap_free_free_free_ OrderedHashmap *h = NULL; _cleanup_ordered_hashmap_free_free_free_ OrderedHashmap *h = NULL;
const char *input = const char *input =
"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \ "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \
"Subject: message\n" \ "Subject: message\n" \

View File

@ -703,7 +703,7 @@ bool manager_all_buttons_ignored(Manager *m) {
int manager_read_utmp(Manager *m) { int manager_read_utmp(Manager *m) {
#if ENABLE_UTMP #if ENABLE_UTMP
int r; int r;
_unused_ _cleanup_(utxent_cleanup) bool utmpx = false; _cleanup_(utxent_cleanup) bool utmpx = false;
assert(m); assert(m);

View File

@ -1323,7 +1323,7 @@ bool session_is_controller(Session *s, const char *sender) {
} }
static void session_release_controller(Session *s, bool notify) { static void session_release_controller(Session *s, bool notify) {
_unused_ _cleanup_free_ char *name = NULL; _cleanup_free_ char *name = NULL;
SessionDevice *sd; SessionDevice *sd;
if (!s->controller) if (!s->controller)

View File

@ -1157,7 +1157,7 @@ static int manager_run(Manager *m) {
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_unrefp) Manager *m = NULL; _cleanup_(manager_unrefp) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL; _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
int r; int r;
log_set_facility(LOG_AUTH); log_set_facility(LOG_AUTH);

View File

@ -702,10 +702,8 @@ int config_parse_dhcp_send_option(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL; _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL, *old4 = NULL;
_cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL; _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL, *old6 = NULL;
_unused_ _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *old4 = NULL;
_unused_ _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *old6 = NULL;
uint32_t uint32_data, enterprise_identifier = 0; uint32_t uint32_data, enterprise_identifier = 0;
_cleanup_free_ char *word = NULL, *q = NULL; _cleanup_free_ char *word = NULL, *q = NULL;
OrderedHashmap **options = data; OrderedHashmap **options = data;

View File

@ -19,7 +19,7 @@
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL; _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
int r; int r;
log_setup(); log_setup();

View File

@ -195,7 +195,7 @@ static int parse_argv(int argc, char *argv[]) {
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL; _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
int r; int r;
log_setup(); log_setup();

View File

@ -2196,7 +2196,7 @@ static int copy_devnodes(const char *dest) {
"tty\0" "tty\0"
"net/tun\0"; "net/tun\0";
_unused_ _cleanup_umask_ mode_t u; _cleanup_umask_ mode_t u;
const char *d; const char *d;
int r = 0; int r = 0;
@ -2279,7 +2279,7 @@ static int copy_devnodes(const char *dest) {
} }
static int make_extra_nodes(const char *dest) { static int make_extra_nodes(const char *dest) {
_unused_ _cleanup_umask_ mode_t u; _cleanup_umask_ mode_t u;
size_t i; size_t i;
int r; int r;
@ -2480,7 +2480,7 @@ static int setup_kmsg(int kmsg_socket) {
_cleanup_(unlink_and_freep) char *from = NULL; _cleanup_(unlink_and_freep) char *from = NULL;
_cleanup_free_ char *fifo = NULL; _cleanup_free_ char *fifo = NULL;
_cleanup_close_ int fd = -1; _cleanup_close_ int fd = -1;
_unused_ _cleanup_umask_ mode_t u; _cleanup_umask_ mode_t u;
int r; int r;
assert(kmsg_socket >= 0); assert(kmsg_socket >= 0);

View File

@ -303,7 +303,7 @@ enum nss_status userdb_getgrnam(
} }
if (!g) { if (!g) {
_unused_ _cleanup_(_nss_systemd_unblockp) bool blocked = false; _cleanup_(_nss_systemd_unblockp) bool blocked = false;
if (strv_isempty(members)) if (strv_isempty(members))
return NSS_STATUS_NOTFOUND; return NSS_STATUS_NOTFOUND;
@ -365,7 +365,7 @@ enum nss_status userdb_getgrgid(
} }
if (!g) { if (!g) {
_unused_ _cleanup_(_nss_systemd_unblockp) bool blocked = false; _cleanup_(_nss_systemd_unblockp) bool blocked = false;
/* So, quite possibly we have to extend an existing group record with additional members. But /* So, quite possibly we have to extend an existing group record with additional members. But
* to do this we need to know the group name first. The group didn't exist via non-NSS * to do this we need to know the group name first. The group didn't exist via non-NSS

View File

@ -387,7 +387,7 @@ static void clear_candidate_hashmapp(Manager **m) {
static int monitor_memory_pressure_contexts_handler(sd_event_source *s, uint64_t usec, void *userdata) { static int monitor_memory_pressure_contexts_handler(sd_event_source *s, uint64_t usec, void *userdata) {
/* Don't want to use stale candidate data. Setting this will clear the candidate hashmap on return unless we /* Don't want to use stale candidate data. Setting this will clear the candidate hashmap on return unless we
* update the candidate data (in which case clear_candidates will be NULL). */ * update the candidate data (in which case clear_candidates will be NULL). */
_unused_ _cleanup_(clear_candidate_hashmapp) Manager *clear_candidates = userdata; _cleanup_(clear_candidate_hashmapp) Manager *clear_candidates = userdata;
_cleanup_set_free_ Set *targets = NULL; _cleanup_set_free_ Set *targets = NULL;
bool in_post_action_delay = false; bool in_post_action_delay = false;
Manager *m = userdata; Manager *m = userdata;

View File

@ -116,7 +116,7 @@ static int parse_argv(int argc, char *argv[]) {
} }
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_unused_ _cleanup_(notify_on_cleanup) const char *notify_msg = NULL; _cleanup_(notify_on_cleanup) const char *notify_msg = NULL;
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_cleanup_free_ char *swap = NULL; _cleanup_free_ char *swap = NULL;
unsigned long long s = 0; unsigned long long s = 0;

View File

@ -904,8 +904,7 @@ static void context_place_partitions(Context *context) {
for (size_t i = 0; i < context->n_free_areas; i++) { for (size_t i = 0; i < context->n_free_areas; i++) {
FreeArea *a = context->free_areas[i]; FreeArea *a = context->free_areas[i];
_unused_ uint64_t left; uint64_t start, left;
uint64_t start;
if (a->after) { if (a->after) {
assert(a->after->offset != UINT64_MAX); assert(a->after->offset != UINT64_MAX);

View File

@ -274,7 +274,7 @@ static int dns_cache_link_item(DnsCache *c, DnsCacheItem *i) {
first = hashmap_get(c->by_key, i->key); first = hashmap_get(c->by_key, i->key);
if (first) { if (first) {
_unused_ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL; _cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;
/* Keep a reference to the original key, while we manipulate the list. */ /* Keep a reference to the original key, while we manipulate the list. */
k = dns_resource_key_ref(first->key); k = dns_resource_key_ref(first->key);

View File

@ -165,7 +165,7 @@ static int dns_query_candidate_add_transaction(
} }
static int dns_query_candidate_go(DnsQueryCandidate *c) { static int dns_query_candidate_go(DnsQueryCandidate *c) {
_unused_ _cleanup_(dns_query_candidate_unrefp) DnsQueryCandidate *keep_c = NULL; _cleanup_(dns_query_candidate_unrefp) DnsQueryCandidate *keep_c = NULL;
DnsTransaction *t; DnsTransaction *t;
int r; int r;
unsigned n = 0; unsigned n = 0;

View File

@ -23,7 +23,7 @@
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL; _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r; int r;
log_setup(); log_setup();

View File

@ -90,7 +90,7 @@
* Returns: 0 on success, negative error code on failure. * Returns: 0 on success, negative error code on failure.
*/ */
int barrier_create(Barrier *b) { int barrier_create(Barrier *b) {
_unused_ _cleanup_(barrier_destroyp) Barrier *staging = b; _cleanup_(barrier_destroyp) Barrier *staging = b;
int r; int r;
assert(b); assert(b);

View File

@ -81,7 +81,7 @@ int make_inaccessible_nodes(
{ "inaccessible/blk", S_IFBLK | 0000 }, { "inaccessible/blk", S_IFBLK | 0000 },
}; };
_unused_ _cleanup_umask_ mode_t u; _cleanup_umask_ mode_t u;
int r; int r;
if (!parent_dir) if (!parent_dir)

View File

@ -25,7 +25,7 @@
#include "utmp-wtmp.h" #include "utmp-wtmp.h"
int utmp_get_runlevel(int *runlevel, int *previous) { int utmp_get_runlevel(int *runlevel, int *previous) {
_unused_ _cleanup_(utxent_cleanup) bool utmpx = false; _cleanup_(utxent_cleanup) bool utmpx = false;
struct utmpx *found, lookup = { .ut_type = RUN_LVL }; struct utmpx *found, lookup = { .ut_type = RUN_LVL };
const char *e; const char *e;
@ -87,7 +87,7 @@ static void init_entry(struct utmpx *store, usec_t t) {
} }
static int write_entry_utmp(const struct utmpx *store) { static int write_entry_utmp(const struct utmpx *store) {
_unused_ _cleanup_(utxent_cleanup) bool utmpx = false; _cleanup_(utxent_cleanup) bool utmpx = false;
assert(store); assert(store);
@ -215,7 +215,7 @@ int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line
} }
int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) { int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
_unused_ _cleanup_(utxent_cleanup) bool utmpx = false; _cleanup_(utxent_cleanup) bool utmpx = false;
struct utmpx lookup = { struct utmpx lookup = {
.ut_type = INIT_PROCESS /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */ .ut_type = INIT_PROCESS /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */
}, store, store_wtmp, *found; }, store, store_wtmp, *found;
@ -340,7 +340,7 @@ int utmp_wall(
bool (*match_tty)(const char *tty, void *userdata), bool (*match_tty)(const char *tty, void *userdata),
void *userdata) { void *userdata) {
_unused_ _cleanup_(utxent_cleanup) bool utmpx = false; _cleanup_(utxent_cleanup) bool utmpx = false;
_cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL; _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL;
struct utmpx *u; struct utmpx *u;
int r; int r;

View File

@ -30,7 +30,7 @@ static int update_timeout(void) {
flags = WDIOS_DISABLECARD; flags = WDIOS_DISABLECARD;
if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0)
return log_warning_errno(errno, "Failed to disable hardware watchdog, ignoring: %m"); return log_warning_errno(errno, "Failed to disable hardware watchdog: %m");
} else { } else {
int sec, flags; int sec, flags;
usec_t t; usec_t t;
@ -38,7 +38,7 @@ static int update_timeout(void) {
t = DIV_ROUND_UP(watchdog_timeout, USEC_PER_SEC); t = DIV_ROUND_UP(watchdog_timeout, USEC_PER_SEC);
sec = MIN(t, (usec_t) INT_MAX); /* Saturate */ sec = MIN(t, (usec_t) INT_MAX); /* Saturate */
if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec) < 0) if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec) < 0)
return log_warning_errno(errno, "Failed to set timeout to %is, ignoring: %m", sec); return log_warning_errno(errno, "Failed to set timeout to %is: %m", sec);
/* Just in case the driver is buggy */ /* Just in case the driver is buggy */
assert(sec > 0); assert(sec > 0);
@ -50,14 +50,14 @@ static int update_timeout(void) {
flags = WDIOS_ENABLECARD; flags = WDIOS_ENABLECARD;
if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) { if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) {
/* ENOTTY means the watchdog is always enabled so we're fine */ /* ENOTTY means the watchdog is always enabled so we're fine */
log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno, log_full(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING,
"Failed to enable hardware watchdog, ignoring: %m"); "Failed to enable hardware watchdog: %m");
if (!ERRNO_IS_NOT_SUPPORTED(errno)) if (!ERRNO_IS_NOT_SUPPORTED(errno))
return -errno; return -errno;
} }
if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0) if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
return log_warning_errno(errno, "Failed to ping hardware watchdog, ignoring: %m"); return log_warning_errno(errno, "Failed to ping hardware watchdog: %m");
watchdog_last_ping = now(clock_boottime_or_monotonic()); watchdog_last_ping = now(clock_boottime_or_monotonic());
} }
@ -75,10 +75,10 @@ static int open_watchdog(void) {
fn = watchdog_device ?: "/dev/watchdog"; fn = watchdog_device ?: "/dev/watchdog";
watchdog_fd = open(fn, O_WRONLY|O_CLOEXEC); watchdog_fd = open(fn, O_WRONLY|O_CLOEXEC);
if (watchdog_fd < 0) if (watchdog_fd < 0)
return log_debug_errno(errno, "Failed to open watchdog device %s, ignoring: %m", fn); return log_debug_errno(errno, "Failed to open watchdog device %s: %m", fn);
if (ioctl(watchdog_fd, WDIOC_GETSUPPORT, &ident) < 0) if (ioctl(watchdog_fd, WDIOC_GETSUPPORT, &ident) < 0)
log_debug_errno(errno, "Hardware watchdog %s does not support WDIOC_GETSUPPORT ioctl, ignoring: %m", fn); log_debug_errno(errno, "Hardware watchdog %s does not support WDIOC_GETSUPPORT ioctl: %m", fn);
else else
log_info("Using hardware watchdog '%s', version %x, device %s", log_info("Using hardware watchdog '%s', version %x, device %s",
ident.identity, ident.identity,
@ -156,7 +156,7 @@ int watchdog_ping(void) {
} }
if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0) if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
return log_warning_errno(errno, "Failed to ping hardware watchdog, ignoring: %m"); return log_warning_errno(errno, "Failed to ping hardware watchdog: %m");
watchdog_last_ping = ntime; watchdog_last_ping = ntime;
return 0; return 0;
@ -172,7 +172,7 @@ void watchdog_close(bool disarm) {
/* Explicitly disarm it */ /* Explicitly disarm it */
flags = WDIOS_DISABLECARD; flags = WDIOS_DISABLECARD;
if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0)
log_warning_errno(errno, "Failed to disable hardware watchdog, ignoring: %m"); log_warning_errno(errno, "Failed to disable hardware watchdog: %m");
/* To be sure, use magic close logic, too */ /* To be sure, use magic close logic, too */
for (;;) { for (;;) {
@ -182,7 +182,7 @@ void watchdog_close(bool disarm) {
break; break;
if (errno != EINTR) { if (errno != EINTR) {
log_warning_errno(errno, "Failed to disarm watchdog timer, ignoring: %m"); log_error_errno(errno, "Failed to disarm watchdog timer: %m");
break; break;
} }
} }

View File

@ -1,14 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-id128.h"
#include "errno-util.h"
#include "hostname-util.h"
#include "strv.h" #include "strv.h"
#include "sysctl-util.h" #include "sysctl-util.h"
#include "tests.h" #include "tests.h"
static const char* const cases[] = { static const char* cases[] = {
"a.b.c", "a/b/c", "a.b.c", "a/b/c",
"a/b/c", "a/b/c", "a/b/c", "a/b/c",
"a/b.c/d", "a/b.c/d", "a/b.c/d", "a/b.c/d",
@ -28,7 +24,7 @@ static void test_sysctl_normalize(void) {
log_info("/* %s */", __func__); log_info("/* %s */", __func__);
const char **s, **expected; const char **s, **expected;
STRV_FOREACH_PAIR(s, expected, (const char**) cases) { STRV_FOREACH_PAIR(s, expected, cases) {
_cleanup_free_ char *t; _cleanup_free_ char *t;
assert_se(t = strdup(*s)); assert_se(t = strdup(*s));
@ -39,44 +35,10 @@ static void test_sysctl_normalize(void) {
} }
} }
static void test_sysctl_read(void) {
_cleanup_free_ char *s = NULL, *h = NULL;
sd_id128_t a, b;
int r;
assert_se(sysctl_read("kernel/random/boot_id", &s) >= 0);
assert_se(sd_id128_from_string(s, &a) >= 0);
assert_se(sd_id128_get_boot(&b) >= 0);
assert_se(sd_id128_equal(a, b));
s = mfree(s);
assert_se(sysctl_read_ip_property(AF_INET, "lo", "forwarding", &s));
assert_se(STR_IN_SET(s, "0", "1"));
r = sysctl_write_ip_property(AF_INET, "lo", "forwarding", s);
assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS);
s = mfree(s);
assert_se(sysctl_read_ip_property(AF_INET, NULL, "ip_forward", &s));
assert_se(STR_IN_SET(s, "0", "1"));
r = sysctl_write_ip_property(AF_INET, NULL, "ip_forward", s);
assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS);
s = mfree(s);
assert_se(sysctl_read("kernel/hostname", &s) >= 0);
assert_se(gethostname_full(GET_HOSTNAME_ALLOW_NONE|GET_HOSTNAME_ALLOW_LOCALHOST, &h) >= 0);
assert_se(streq(s, h));
r = sysctl_write("kernel/hostname", s);
assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO); test_setup_logging(LOG_INFO);
test_sysctl_normalize(); test_sysctl_normalize();
test_sysctl_read();
return 0; return 0;
} }

View File

@ -87,7 +87,7 @@ settime:
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message = NULL; _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
const char *user = "systemd-timesync"; const char *user = "systemd-timesync";
uid_t uid, uid_current; uid_t uid, uid_current;
gid_t gid; gid_t gid;

View File

@ -338,8 +338,7 @@ static int process_and_watch_password_files(bool watch) {
_FD_MAX _FD_MAX
}; };
_unused_ _cleanup_close_ int tty_block_fd = -1; _cleanup_close_ int notify = -1, signal_fd = -1, tty_block_fd = -1;
_cleanup_close_ int notify = -1, signal_fd = -1;
struct pollfd pollfd[_FD_MAX]; struct pollfd pollfd[_FD_MAX];
sigset_t mask; sigset_t mask;
int r; int r;

View File

@ -1136,8 +1136,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
manager_reload(manager); manager_reload(manager);
break; break;
case UDEV_CTRL_SET_ENV: { case UDEV_CTRL_SET_ENV: {
_unused_ _cleanup_free_ char *old_val = NULL; _cleanup_free_ char *key = NULL, *val = NULL, *old_key = NULL, *old_val = NULL;
_cleanup_free_ char *key = NULL, *val = NULL, *old_key = NULL;
const char *eq; const char *eq;
eq = strchr(value->buf, '='); eq = strchr(value->buf, '=');

View File

@ -24,7 +24,7 @@
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL; _cleanup_(manager_freep) Manager *m = NULL;
_unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL; _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r; int r;
log_setup(); log_setup();