1
0
mirror of https://github.com/systemd/systemd synced 2026-04-12 10:04:50 +02:00

Compare commits

..

12 Commits

Author SHA1 Message Date
Jan Janssen
f699bd81e8 boot-timestamps: Discard firmware init time when running in a VM
Fixes: #22060
2022-01-09 19:21:16 +01:00
Zbigniew Jędrzejewski-Szmek
46004616a1 bpf: actually skip RestrictFileSystems= when not supported
Units would fail to start, incl. systemd-journald.service and systemd-udevd.service.
Since unit->manager->restrict_fs will be set if and only if we can use it,
we can just check for that and remove the other checks.
Follow-up for 299d9417238e0727a48ebaabb5a9de0c908ec5c8.
2022-01-09 18:04:49 +00:00
Frantisek Sumsal
fd5e5a87fb test: explicitly configure oomd stuff via dropins
so we don't get overridden by distro-shipped ones.

Fixes: #22030
2022-01-09 17:56:57 +00:00
Luca Boccassi
e683878c0f test: store empty files rather than symlinks for test-fstab-generator
Dangling symlinks get pruned when packaging up the installation
directory. Just store empty files instead, and compare the names
rather than the content for .requires/.wants - the filename is
what is important anyway, the content is ignored.

Fixes #22059
2022-01-09 18:17:40 +01:00
Jan Janssen
b3c5a7074c meson: Use files() for source lists for boot and fundamental
This fixes build reproducibility as otherwise the full path
of the source files ends up in the output binary.
2022-01-09 18:02:34 +01:00
Luca Boccassi
f2d323a3ab
Merge pull request #22028 from medhefgo/boot-cleanup
boot: Cleanup
2022-01-09 15:44:55 +00:00
Jan Janssen
ad9962bb7e boot: Simplify line_edit 2022-01-06 14:16:34 +01:00
Jan Janssen
6893c4c553 boot: Switch to insertion sort
We can do a little better than bubble sort without ramping up the
code complexity.
2022-01-06 14:16:34 +01:00
Jan Janssen
163d1ea5dd boot: Do more config handling in config_load_all_entries 2022-01-06 14:16:34 +01:00
Jan Janssen
b00e37daa6 boot: Remove no_autoselect 2022-01-06 14:16:34 +01:00
Jan Janssen
dd4ddc82e6 boot: Close xbootldr root_dir 2022-01-06 14:16:34 +01:00
Jan Janssen
a45d4f3543 boot: Simplify config_entry_add_osx 2022-01-06 14:16:34 +01:00
29 changed files with 110 additions and 153 deletions

View File

@ -42,6 +42,7 @@ _used_ _section_(".osrel") static const char osrel[] =
enum loader_type { enum loader_type {
LOADER_UNDEFINED, LOADER_UNDEFINED,
LOADER_AUTO,
LOADER_EFI, LOADER_EFI,
LOADER_LINUX, LOADER_LINUX,
LOADER_STUB, LOADER_STUB,
@ -60,7 +61,6 @@ typedef struct {
CHAR16 *options; CHAR16 *options;
CHAR16 key; CHAR16 key;
EFI_STATUS (*call)(void); EFI_STATUS (*call)(void);
BOOLEAN no_autoselect;
BOOLEAN non_unique; BOOLEAN non_unique;
UINTN tries_done; UINTN tries_done;
UINTN tries_left; UINTN tries_left;
@ -142,27 +142,20 @@ static BOOLEAN line_edit(
UINTN y_pos) { UINTN y_pos) {
_cleanup_freepool_ CHAR16 *line = NULL, *print = NULL; _cleanup_freepool_ CHAR16 *line = NULL, *print = NULL;
UINTN size, len, first, cursor, clear; UINTN size, len, first = 0, cursor = 0, clear = 0;
BOOLEAN exit, enter;
assert(line_out); assert(line_out);
if (!line_in) if (!line_in)
line_in = L""; line_in = L"";
size = StrLen(line_in) + 1024; len = StrLen(line_in);
size = len + 1024;
line = xnew(CHAR16, size); line = xnew(CHAR16, size);
StrCpy(line, line_in);
len = StrLen(line);
print = xnew(CHAR16, x_max + 1); print = xnew(CHAR16, x_max + 1);
StrCpy(line, line_in);
first = 0; for (;;) {
cursor = 0;
clear = 0;
enter = FALSE;
exit = FALSE;
while (!exit) {
EFI_STATUS err; EFI_STATUS err;
UINT64 key; UINT64 key;
UINTN j; UINTN j;
@ -196,8 +189,7 @@ static BOOLEAN line_edit(
case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'g'): case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'g'):
case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('c')): case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('c')):
case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('g')): case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('g')):
exit = TRUE; return FALSE;
break;
case KEYPRESS(0, SCAN_HOME, 0): case KEYPRESS(0, SCAN_HOME, 0):
case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'a'): case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'a'):
@ -324,9 +316,7 @@ static BOOLEAN line_edit(
case KEYPRESS(0, CHAR_CARRIAGE_RETURN, CHAR_CARRIAGE_RETURN): /* Teclast X98+ II firmware sends malformed events */ case KEYPRESS(0, CHAR_CARRIAGE_RETURN, CHAR_CARRIAGE_RETURN): /* Teclast X98+ II firmware sends malformed events */
if (StrCmp(line, line_in) != 0) if (StrCmp(line, line_in) != 0)
*line_out = TAKE_PTR(line); *line_out = TAKE_PTR(line);
enter = TRUE; return TRUE;
exit = TRUE;
break;
case KEYPRESS(0, 0, CHAR_BACKSPACE): case KEYPRESS(0, 0, CHAR_BACKSPACE):
if (len == 0) if (len == 0)
@ -373,8 +363,6 @@ static BOOLEAN line_edit(
continue; continue;
} }
} }
return enter;
} }
static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
@ -541,7 +529,6 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) {
ps_string(L" loader: %s\n", entry->loader); ps_string(L" loader: %s\n", entry->loader);
ps_string(L" devicetree: %s\n", entry->devicetree); ps_string(L" devicetree: %s\n", entry->devicetree);
ps_string(L" options: %s\n", entry->options); ps_string(L" options: %s\n", entry->options);
ps_bool(L" auto-select: %s\n", !entry->no_autoselect);
ps_bool(L" internal call: %s\n", !!entry->call); ps_bool(L" internal call: %s\n", !!entry->call);
ps_bool(L"counting boots: %s\n", entry->tries_left != UINTN_MAX); ps_bool(L"counting boots: %s\n", entry->tries_left != UINTN_MAX);
@ -1645,12 +1632,6 @@ static INTN config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
return 0; return 0;
} }
static void config_sort_entries(Config *config) {
assert(config);
sort_pointer_array((void**) config->entries, config->entry_count, (compare_pointer_func_t) config_entry_compare);
}
static UINTN config_entry_find(Config *config, const CHAR16 *needle) { static UINTN config_entry_find(Config *config, const CHAR16 *needle) {
assert(config); assert(config);
@ -1695,14 +1676,16 @@ static void config_default_entry_select(Config *config) {
/* select the last suitable entry */ /* select the last suitable entry */
i = config->entry_count; i = config->entry_count;
while (i--) { while (i--) {
if (config->entries[i]->no_autoselect) if (config->entries[i]->type == LOADER_AUTO || config->entries[i]->call)
continue; continue;
config->idx_default = i; config->idx_default = i;
return; return;
} }
/* no entry found */ /* If no configured entry to select from was found, enable the menu. */
config->idx_default = IDX_INVALID; config->idx_default = 0;
if (config->timeout_sec == 0)
config->timeout_sec = 10;
} }
static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) { static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) {
@ -1808,7 +1791,6 @@ static BOOLEAN config_entry_add_call(
.id = xstrdup(id), .id = xstrdup(id),
.title = xstrdup(title), .title = xstrdup(title),
.call = call, .call = call,
.no_autoselect = TRUE,
.tries_done = UINTN_MAX, .tries_done = UINTN_MAX,
.tries_left = UINTN_MAX, .tries_left = UINTN_MAX,
}; };
@ -1921,19 +1903,16 @@ static BOOLEAN config_entry_add_loader_auto(
return FALSE; return FALSE;
handle->Close(handle); handle->Close(handle);
entry = config_entry_add_loader(config, device, LOADER_UNDEFINED, id, key, title, loader, NULL); entry = config_entry_add_loader(config, device, LOADER_AUTO, id, key, title, loader, NULL);
if (!entry) if (!entry)
return FALSE; return FALSE;
/* do not boot right away into auto-detected entries */
entry->no_autoselect = TRUE;
return TRUE; return TRUE;
} }
static void config_entry_add_osx(Config *config) { static void config_entry_add_osx(Config *config) {
EFI_STATUS err; EFI_STATUS err;
UINTN handle_count = 0; UINTN n_handles = 0;
_cleanup_freepool_ EFI_HANDLE *handles = NULL; _cleanup_freepool_ EFI_HANDLE *handles = NULL;
assert(config); assert(config);
@ -1941,23 +1920,27 @@ static void config_entry_add_osx(Config *config) {
if (!config->auto_entries) if (!config->auto_entries)
return; return;
err = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &handle_count, &handles); err = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &n_handles, &handles);
if (!EFI_ERROR(err)) { if (EFI_ERROR(err))
for (UINTN i = 0; i < handle_count; i++) { return;
EFI_FILE *root;
BOOLEAN found;
root = LibOpenRoot(handles[i]); for (UINTN i = 0; i < n_handles; i++) {
_cleanup_(file_handle_closep) EFI_FILE *root = LibOpenRoot(handles[i]);
if (!root) if (!root)
continue; continue;
found = config_entry_add_loader_auto(config, handles[i], root, NULL, L"auto-osx", 'a', L"macOS",
L"\\System\\Library\\CoreServices\\boot.efi"); if (config_entry_add_loader_auto(
root->Close(root); config,
if (found) handles[i],
root,
NULL,
L"auto-osx",
'a',
L"macOS",
L"\\System\\Library\\CoreServices\\boot.efi"))
break; break;
} }
} }
}
static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) {
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
@ -2147,8 +2130,8 @@ static void config_load_xbootldr(
Config *config, Config *config,
EFI_HANDLE *device) { EFI_HANDLE *device) {
_cleanup_(file_handle_closep) EFI_FILE *root_dir = NULL;
EFI_HANDLE new_device; EFI_HANDLE new_device;
EFI_FILE *root_dir;
EFI_STATUS err; EFI_STATUS err;
assert(config); assert(config);
@ -2344,7 +2327,7 @@ static void config_load_all_entries(
config_load_xbootldr(config, loaded_image->DeviceHandle); config_load_xbootldr(config, loaded_image->DeviceHandle);
/* sort entries after version number */ /* sort entries after version number */
config_sort_entries(config); sort_pointer_array((void **) config->entries, config->entry_count, (compare_pointer_func_t) config_entry_compare);
/* if we find some well-known loaders, add them to the end of the list */ /* if we find some well-known loaders, add them to the end of the list */
config_entry_add_osx(config); config_entry_add_osx(config);
@ -2359,6 +2342,16 @@ static void config_load_all_entries(
L"auto-reboot-to-firmware-setup", L"auto-reboot-to-firmware-setup",
L"Reboot Into Firmware Interface", L"Reboot Into Firmware Interface",
reboot_into_firmware); reboot_into_firmware);
if (config->entry_count == 0)
return
config_write_entries_to_variable(config);
config_title_generate(config);
/* select entry by configured pattern or EFI LoaderDefaultEntry= variable */
config_default_entry_select(config);
} }
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
@ -2410,20 +2403,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
goto out; goto out;
} }
config_write_entries_to_variable(&config);
config_title_generate(&config);
/* select entry by configured pattern or EFI LoaderDefaultEntry= variable */
config_default_entry_select(&config);
/* if no configured entry to select from was found, enable the menu */
if (config.idx_default == IDX_INVALID) {
config.idx_default = 0;
if (config.timeout_sec == 0)
config.timeout_sec = 10;
}
/* select entry or show menu when key is pressed or timeout is set */ /* select entry or show menu when key is pressed or timeout is set */
if (config.force_menu || config.timeout_sec > 0) if (config.force_menu || config.timeout_sec > 0)
menu = TRUE; menu = TRUE;

View File

@ -312,9 +312,10 @@ efi_headers = files(
'shim.h', 'shim.h',
'splash.h', 'splash.h',
'util.h', 'util.h',
'xbootldr.h') 'xbootldr.h',
)
common_sources = [ common_sources = files(
'assert.c', 'assert.c',
'devicetree.c', 'devicetree.c',
'disk.c', 'disk.c',
@ -322,31 +323,34 @@ common_sources = [
'measure.c', 'measure.c',
'pe.c', 'pe.c',
'secure-boot.c', 'secure-boot.c',
'util.c'] 'util.c',
)
systemd_boot_sources = [ systemd_boot_sources = files(
'boot.c', 'boot.c',
'console.c', 'console.c',
'drivers.c', 'drivers.c',
'random-seed.c', 'random-seed.c',
'shim.c', 'shim.c',
'xbootldr.c'] 'xbootldr.c',
)
stub_sources = [ stub_sources = files(
'cpio.c', 'cpio.c',
'initrd.c', 'initrd.c',
'splash.c', 'splash.c',
'stub.c'] 'stub.c',
)
if efi_arch[1] in ['ia32', 'x86_64'] if efi_arch[1] in ['ia32', 'x86_64']
stub_sources += 'linux_x86.c' stub_sources += files('linux_x86.c')
else else
stub_sources += 'linux.c' stub_sources += files('linux.c')
endif endif
# BCD parser only makes sense on arches that Windows supports. # BCD parser only makes sense on arches that Windows supports.
if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64']
systemd_boot_sources += 'bcd.c' systemd_boot_sources += files('bcd.c')
tests += [ tests += [
[['src/boot/efi/test-bcd.c'], [['src/boot/efi/test-bcd.c'],
[], [],
@ -362,9 +366,10 @@ endif
systemd_boot_objects = [] systemd_boot_objects = []
stub_objects = [] stub_objects = []
foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources
o_file = custom_target(file.split('/')[-1] + '.o', # FIXME: replace ''.format(file) with fs.name(file) when meson_version requirement is >= 0.59.0
o_file = custom_target('@0@.o'.format(file).split('/')[-1],
input : file, input : file,
output : file.split('/')[-1] + '.o', output : '@0@.o'.format(file).split('/')[-1],
command : [cc.cmd_array(), '-c', '@INPUT@', '-o', '@OUTPUT@', efi_cflags], command : [cc.cmd_array(), '-c', '@INPUT@', '-o', '@OUTPUT@', efi_cflags],
depend_files : efi_headers + fundamental_headers) depend_files : efi_headers + fundamental_headers)
if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file) if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file)

View File

@ -529,21 +529,17 @@ void sort_pointer_array(
return; return;
for (UINTN i = 1; i < n_members; i++) { for (UINTN i = 1; i < n_members; i++) {
BOOLEAN more = FALSE; UINTN k;
void *entry = array[i];
for (UINTN k = 0; k < n_members - i; k++) { for (k = i; k > 0; k--) {
void *entry; if (compare(array[k - 1], entry) <= 0)
if (compare(array[k], array[k+1]) <= 0)
continue;
entry = array[k];
array[k] = array[k+1];
array[k+1] = entry;
more = TRUE;
}
if (!more)
break; break;
array[k] = array[k - 1];
}
array[k] = entry;
} }
} }

View File

@ -1732,21 +1732,6 @@ static int apply_lock_personality(const Unit* u, const ExecContext *c) {
#endif #endif
#if HAVE_LIBBPF #if HAVE_LIBBPF
static bool skip_lsm_bpf_unsupported(const Unit* u, const char* msg) {
assert(u);
assert(u->manager);
if (lsm_bpf_supported())
return false;
/* lsm_bpf_setup succeeded */
if (u->manager->restrict_fs)
return false;
log_unit_debug(u, "LSM BPF not supported, skipping %s", msg);
return true;
}
static int apply_restrict_filesystems(Unit *u, const ExecContext *c) { static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
assert(u); assert(u);
assert(c); assert(c);
@ -1754,8 +1739,11 @@ static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
if (!exec_context_restrict_filesystems_set(c)) if (!exec_context_restrict_filesystems_set(c))
return 0; return 0;
if (skip_lsm_bpf_unsupported(u, "RestrictFileSystems=")) if (!u->manager->restrict_fs) {
/* LSM BPF is unsupported or lsm_bpf_setup failed */
log_unit_debug(u, "LSM BPF not supported, skipping RestrictFileSystems=");
return 0; return 0;
}
return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, c->restrict_filesystems_allow_list); return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, c->restrict_filesystems_allow_list);
} }
@ -4108,13 +4096,11 @@ static int exec_child(
} }
#if HAVE_LIBBPF #if HAVE_LIBBPF
if (MANAGER_IS_SYSTEM(unit->manager) && lsm_bpf_supported()) { if (unit->manager->restrict_fs) {
int bpf_map_fd = -1; int bpf_map_fd = lsm_bpf_map_restrict_fs_fd(unit);
bpf_map_fd = lsm_bpf_map_restrict_fs_fd(unit);
if (bpf_map_fd < 0) { if (bpf_map_fd < 0) {
*exit_status = EXIT_FDS; *exit_status = EXIT_FDS;
return log_unit_error_errno(unit, r, "Failed to get restrict filesystems BPF map fd: %m"); return log_unit_error_errno(unit, bpf_map_fd, "Failed to get restrict filesystems BPF map fd: %m");
} }
r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, bpf_map_fd, &bpf_map_fd); r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, bpf_map_fd, &bpf_map_fd);

View File

@ -8,20 +8,16 @@ fundamental_headers = files(
'macro-fundamental.h', 'macro-fundamental.h',
'sha256.h', 'sha256.h',
'string-util-fundamental.h', 'string-util-fundamental.h',
'types-fundamental.h') 'types-fundamental.h',
)
sources = '''
bootspec-fundamental.c
efivars-fundamental.c
string-util-fundamental.c
sha256.c
'''.split()
# for sd-boot # for sd-boot
fundamental_source_paths = [] fundamental_source_paths = files(
foreach source : sources 'bootspec-fundamental.c',
fundamental_source_paths += meson.current_source_dir() / source 'efivars-fundamental.c',
endforeach 'sha256.c',
'string-util-fundamental.c',
)
# for libbasic # for libbasic
fundamental_sources = files(sources) + fundamental_headers fundamental_sources = fundamental_source_paths + fundamental_headers

View File

@ -5,11 +5,13 @@
#include "efi-loader.h" #include "efi-loader.h"
#include "macro.h" #include "macro.h"
#include "time-util.h" #include "time-util.h"
#include "virt.h"
int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) { int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) {
usec_t x = 0, y = 0, a; usec_t x = 0, y = 0, a;
int r; int r;
dual_timestamp _n; dual_timestamp _n;
bool use_firmware = true;
assert(firmware); assert(firmware);
assert(loader); assert(loader);
@ -24,6 +26,10 @@ int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_time
r = efi_loader_get_boot_usec(&x, &y); r = efi_loader_get_boot_usec(&x, &y);
if (r < 0) if (r < 0)
return r; return r;
/* If we are running in a VM, the init timestamp would
* be equivalent to the host uptime. */
use_firmware = detect_vm() <= 0;
} }
/* Let's convert this to timestamps where the firmware /* Let's convert this to timestamps where the firmware
@ -33,12 +39,14 @@ int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_time
* the monotonic timestamps here as negative of the actual * the monotonic timestamps here as negative of the actual
* value. */ * value. */
if (use_firmware) {
firmware->monotonic = y; firmware->monotonic = y;
loader->monotonic = y - x;
a = n->monotonic + firmware->monotonic; a = n->monotonic + firmware->monotonic;
firmware->realtime = n->realtime > a ? n->realtime - a : 0; firmware->realtime = n->realtime > a ? n->realtime - a : 0;
} else
firmware->monotonic = firmware->realtime = 0;
loader->monotonic = y - x;
a = n->monotonic + loader->monotonic; a = n->monotonic + loader->monotonic;
loader->realtime = n->realtime > a ? n->realtime - a : 0; loader->realtime = n->realtime > a ? n->realtime - a : 0;

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -ex set -e
if [[ -n "$1" ]]; then if [[ -n "$1" ]]; then
generator=$1 generator=$1
@ -30,7 +30,9 @@ for f in "$src"/test-*.input; do
sed -i -e 's:ExecStart=/lib/systemd/systemd-fsck:ExecStart=/usr/lib/systemd/systemd-fsck:' "$out"/systemd-fsck-root.service sed -i -e 's:ExecStart=/lib/systemd/systemd-fsck:ExecStart=/usr/lib/systemd/systemd-fsck:' "$out"/systemd-fsck-root.service
fi fi
if ! diff -u "$out" "${f%.input}.expected"; then # We store empty files rather than symlinks, so that they don't get pruned when packaged up, so compare
# the list of filenames rather than their content
if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "${f%.input}.expected" -printf '%P\n' | sort); then
echo "**** Unexpected output for $f" echo "**** Unexpected output for $f"
exit 1 exit 1
fi fi

View File

@ -22,7 +22,13 @@ fi
rm -rf /etc/systemd/system/testsuite-55-testbloat.service.d rm -rf /etc/systemd/system/testsuite-55-testbloat.service.d
echo "DefaultMemoryPressureDurationSec=2s" >>/etc/systemd/oomd.conf # Configure oomd explicitly to avoid conflicts with distro dropins
mkdir -p /etc/systemd/oomd.conf.d/
echo -e "[OOM]\nDefaultMemoryPressureDurationSec=2s" >/etc/systemd/oomd.conf.d/99-oomd-test.conf
mkdir -p /etc/systemd/system/-.slice.d/
echo -e "[Slice]\nManagedOOMSwap=auto" >/etc/systemd/system/-.slice.d/99-oomd-test.conf
mkdir -p /etc/systemd/system/user@.service.d/
echo -e "[Service]\nManagedOOMMemoryPressure=auto\nManagedOOMMemoryPressureLimit=0%" >/etc/systemd/system/user@.service.d/99-oomd-test.conf
mkdir -p /etc/systemd/system/systemd-oomd.service.d/ mkdir -p /etc/systemd/system/systemd-oomd.service.d/
echo -e "[Service]\nEnvironment=SYSTEMD_LOG_LEVEL=debug" >/etc/systemd/system/systemd-oomd.service.d/debug.conf echo -e "[Service]\nEnvironment=SYSTEMD_LOG_LEVEL=debug" >/etc/systemd/system/systemd-oomd.service.d/debug.conf