1
0
mirror of https://github.com/systemd/systemd synced 2025-10-09 13:44:44 +02:00

Compare commits

...

17 Commits

Author SHA1 Message Date
Yu Watanabe
ffe8f21302 basic/include: replace _Static_assert() with static_assert()
If one of the header is included in a C++ source file, then using
_Static_assert() triggers compile error for some reasons.
Let's use static_assert(), which can be used by both C and C++ code.
2025-07-06 22:02:18 +09:00
Luca Boccassi
a8f8b3efb5 ci: add test timeout multiplier for ppc64le
The slow tests have timed out at least a couple of times,
so add a multiplier

1252/1633 systemd:libsystemd / test-sd-device      TIMEOUT 30.04s killed by signal 15 SIGTERM
1633/1633 systemd:libsystemd / test-journal-verify TIMEOUT 90.01s killed by signal 15 SIGTERM

Follow-up for 8a1d1341444aaf143108e0ca85741c779014d8b2
2025-07-06 12:35:01 +01:00
Yu Watanabe
2643cb1ade core: rename ExecContext.ioprio_set -> .ioprio_is_set
To make it not conflict with syscall ioprio_set().
This is important as we have
```
 #define ioprio_set missing_ioprio_set
```
in missing_syscall.h.
2025-07-06 13:31:40 +02:00
Yu Watanabe
c56e251d3f analyze: include unistd.h
The source file uses symbols e.g. execl(), execvp(), _exit(), and so on,
without including unistd.h.

Continuation of 4f18ff2e29b8054f30b084abcabf5f689f4b340b.

Follow-up for 9a08000d186396bc8bcb8fe057720417543c3bf0.
2025-07-06 13:31:17 +02:00
Yu Watanabe
8d29f31bf6 namespace-util,nsresource: explicitly include sched.h
These source files uses symbols provided by sched.h, e.g.
setns(), unshare(), CLONE_NEWNS, and friends, but they do not explicitly
include sched.h. Currently, it is included indirectly via missing_syscall.h,
which is included by e.g. pidfd-util.h.
Let's explicitly include headers that provides symbols used in the code.

This is similar to 4f18ff2e29b8054f30b084abcabf5f689f4b340b, but for sched.h.
2025-07-06 13:28:46 +02:00
Yu Watanabe
cfba9b9eab tree-wide: several cleanups for reading/writing /proc/sys/fs/nr_open
- use unsigned for the return value of read_nr_open(), as it does not
  fail, and the kernel internally uses unsigned for the value,
- when bumping the value by PID1, let's start from the kernel's maximum
  value defined in fs/file.c. The maximum value should be mostly an API
  of the kernel, but may changed in a future, hence still try several
  times if we fail to bump the value.

Co-authored-by: Jared Baur <jaredbaur@fastmail.com>
Co-authored-by: John Rinehart <johnrichardrinehart@gmail.com>
2025-07-06 13:22:56 +02:00
Luca Boccassi
6cc01c8cc4 ukify: fix parsing uname version with '+'
Debian started using '+' in the kernel uname version, which fails the
regex in ukify. Fix it.
2025-07-06 10:49:22 +01:00
Yu Watanabe
ebfd56975e
cgroup-util: clean up skip_{slices,session,user_manager} (#38089) 2025-07-06 16:37:28 +09:00
Yu Watanabe
b0d40944b3
hwdb: fix typo in 70-maker-tools.hwdb, and add the file to meson.build (#38090) 2025-07-06 16:31:23 +09:00
Yu Watanabe
e7f04514c1
meson fixlets (#38086)
Some fixes for issues found while doing a minimal aarch64 cross build
2025-07-06 16:27:31 +09:00
AsciiWolf
225de2729d hwdb: fix typo in 70-maker-tools.hwdb 2025-07-05 23:44:08 +02:00
AsciiWolf
cdbc500faa
hwdb: add 70-maker-tools.hwdb to meson.build
The hwdb file was not added there in 3dcb56f5e0fe4d937a003bf89496a27b52c5c69e for some reason
2025-07-05 23:32:09 +02:00
Mike Yuan
b6fde0875b
core/cgroup: drop outdated comment 2025-07-05 22:26:23 +02:00
Mike Yuan
d33104eba2
cgroup-util: clean up skip_{slices,session,user_manager}
Let's avoid obscure memcmp()s in skip_* and instead use
strndupa() to extract the bits we care and call usual
string routines on it.
2025-07-05 22:26:23 +02:00
Mike Yuan
68c703872c
string-table: drop unneeded initialization 2025-07-05 22:26:23 +02:00
Luca Boccassi
163e666204 meson: call qemu with -machine virt on aarch64
'qemu-system-aarch64 -device help' fails when no machine is specified.
Use the 'virt' type which seems to be what everyone uses for VMs.
2025-07-05 20:21:51 +01:00
Luca Boccassi
ec0bbbd2a9 meson: do not reference variable unless feature that defines it is enabled
SYSTEMD_LANGUAGE_FALLBACK_MAP is used by the localed test, and
language_fallback_map is defined by the localed meson.
If the feature is disabled, the test is not built so the env var
is not needed, and the meson variable is not defined so the build
fails.
2025-07-05 20:21:00 +01:00
27 changed files with 116 additions and 140 deletions

View File

@ -91,11 +91,18 @@ for phase in "${PHASES[@]}"; do
mv /etc/machine-id /etc/machine-id.bak
fi
fi
# On ppc64le the workers are slower and some slow tests time out
MESON_TEST_ARGS=()
if [[ "$(uname -m)" != "x86_64" ]] && [[ "$(uname -m)" != "aarch64" ]]; then
MESON_TEST_ARGS+=(--timeout-multiplier=3)
fi
MESON_ARGS+=(--fatal-meson-warnings)
run_meson -Dnobody-group=nogroup --werror -Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true "${MESON_ARGS[@]}" build
ninja -C build -v
# Ensure setting a timezone (like the reproducible build tests do) does not break time/date unit tests
TZ=GMT+12 meson test -C build --print-errorlogs
TZ=GMT+12 meson test "${MESON_TEST_ARGS[@]}" -C build --print-errorlogs
;;
RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN_NO_DEPS)
MESON_ARGS=(--optimization=1)

View File

@ -68,5 +68,5 @@ usb:v2B71p000E*
# PowerSpec Ultra 3DPrinter
usb:v0315p0001*
usb:v2B71p00F6*
usb:v2B71p00FF
usb:v2B71p00FF*
ID_MAKER_TOOL=1

View File

@ -31,6 +31,7 @@ hwdb_files_test = files(
'70-cameras.hwdb',
'70-hardware-wallets.hwdb',
'70-joystick.hwdb',
'70-maker-tools.hwdb',
'70-mouse.hwdb',
'70-pda.hwdb',
'70-pointingstick.hwdb',

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "sd-bus.h"

View File

@ -933,28 +933,19 @@ int cg_path_decode_unit(const char *cgroup, char **ret_unit) {
}
static bool valid_slice_name(const char *p, size_t n) {
if (!p)
return false;
assert(p || n == 0);
if (n < STRLEN("x.slice"))
return false;
if (memcmp(p + n - 6, ".slice", 6) == 0) {
char buf[n+1], *c;
char *c = strndupa_safe(p, n);
if (!endswith(c, ".slice"))
return false;
memcpy(buf, p, n);
buf[n] = 0;
c = cg_unescape(buf);
return unit_name_is_valid(c, UNIT_NAME_PLAIN);
}
return false;
return unit_name_is_valid(cg_unescape(c), UNIT_NAME_PLAIN);
}
static const char *skip_slices(const char *p) {
static const char* skip_slices(const char *p) {
assert(p);
/* Skips over all slice assignments */
@ -1005,7 +996,7 @@ int cg_path_get_unit_path(const char *path, char **ret) {
if (!path_copy)
return -ENOMEM;
unit_name = (char *)skip_slices(path_copy);
unit_name = (char*) skip_slices(path_copy);
unit_name[strcspn(unit_name, "/")] = 0;
if (!unit_name_is_valid(cg_unescape(unit_name), UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
@ -1052,12 +1043,11 @@ int cg_pidref_get_unit(const PidRef *pidref, char **ret) {
return 0;
}
/**
* Skip session-*.scope, but require it to be there.
*/
static const char *skip_session(const char *p) {
static const char* skip_session(const char *p) {
size_t n;
/* Skip session-*.scope, but require it to be there. */
if (isempty(p))
return NULL;
@ -1067,34 +1057,29 @@ static const char *skip_session(const char *p) {
if (n < STRLEN("session-x.scope"))
return NULL;
if (memcmp(p, "session-", 8) == 0 && memcmp(p + n - 6, ".scope", 6) == 0) {
char buf[n - 8 - 6 + 1];
const char *s = startswith(p, "session-");
if (!s)
return NULL;
memcpy(buf, p + 8, n - 8 - 6);
buf[n - 8 - 6] = 0;
/* Note that session scopes never need unescaping, since they cannot conflict with the kernel's
* own names, hence we don't need to call cg_unescape() here. */
char *f = strndupa_safe(s, p + n - s),
*e = endswith(f, ".scope");
if (!e)
return NULL;
*e = '\0';
/* Note that session scopes never need unescaping,
* since they cannot conflict with the kernel's own
* names, hence we don't need to call cg_unescape()
* here. */
if (!session_id_valid(f))
return NULL;
if (!session_id_valid(buf))
return NULL;
p += n;
p += strspn(p, "/");
return p;
}
return NULL;
return skip_leading_slash(p + n);
}
/**
* Skip user@*.service or capsule@*.service, but require either of them to be there.
*/
static const char *skip_user_manager(const char *p) {
static const char* skip_user_manager(const char *p) {
size_t n;
/* Skip user@*.service or capsule@*.service, but require either of them to be there. */
if (isempty(p))
return NULL;
@ -1119,26 +1104,14 @@ static const char *skip_user_manager(const char *p) {
/* Note that user manager services never need unescaping, since they cannot conflict with the
* kernel's own names, hence we don't need to call cg_unescape() here. Prudently check validity of
* instance names, they should be always valid as we validate them upon unit start. */
if (startswith(unit_name, "user@")) {
if (parse_uid(i, NULL) < 0)
return NULL;
if (!(startswith(unit_name, "user@") && parse_uid(i, NULL) >= 0) &&
!(startswith(unit_name, "capsule@") && capsule_name_is_valid(i) > 0))
return NULL;
p += n;
p += strspn(p, "/");
return p;
} else if (startswith(unit_name, "capsule@")) {
if (capsule_name_is_valid(i) <= 0)
return NULL;
p += n;
p += strspn(p, "/");
return p;
}
return NULL;
return skip_leading_slash(p + n);
}
static const char *skip_user_prefix(const char *path) {
static const char* skip_user_prefix(const char *path) {
const char *e, *t;
assert(path);

View File

@ -226,7 +226,7 @@ int cg_pid_get_user_slice(pid_t pid, char **ret_slice);
int cg_path_decode_unit(const char *cgroup, char **ret_unit);
bool cg_needs_escape(const char *p);
bool cg_needs_escape(const char *p) _pure_;
int cg_escape(const char *p, char **ret);
char* cg_unescape(const char *p) _pure_;

View File

@ -990,7 +990,7 @@ int fd_verify_safe_flags_full(int fd, int extra_flags) {
return flags & (O_ACCMODE_STRICT | extra_flags); /* return the flags variable, but remove the noise */
}
int read_nr_open(void) {
unsigned read_nr_open(void) {
_cleanup_free_ char *nr_open = NULL;
int r;
@ -1001,9 +1001,9 @@ int read_nr_open(void) {
if (r < 0)
log_debug_errno(r, "Failed to read /proc/sys/fs/nr_open, ignoring: %m");
else {
int v;
unsigned v;
r = safe_atoi(nr_open, &v);
r = safe_atou(nr_open, &v);
if (r < 0)
log_debug_errno(r, "Failed to parse /proc/sys/fs/nr_open value '%s', ignoring: %m", nr_open);
else
@ -1011,7 +1011,7 @@ int read_nr_open(void) {
}
/* If we fail, fall back to the hard-coded kernel limit of 1024 * 1024. */
return 1024 * 1024;
return NR_OPEN_DEFAULT;
}
int fd_get_diskseq(int fd, uint64_t *ret) {

View File

@ -50,6 +50,13 @@
* around the problems with musl's definition. */
#define O_ACCMODE_STRICT (O_RDONLY|O_WRONLY|O_RDWR)
/* The default, minimum, and maximum values of /proc/sys/fs/nr_open. See kernel's fs/file.c.
* These values have been unchanged since kernel-2.6.26:
* https://github.com/torvalds/linux/commit/eceea0b3df05ed262ae32e0c6340cc7a3626632d */
#define NR_OPEN_DEFAULT ((unsigned) (1024 * 1024))
#define NR_OPEN_MINIMUM ((unsigned) (sizeof(long) * 8))
#define NR_OPEN_MAXIMUM ((unsigned) (CONST_MIN((size_t) INT_MAX, SIZE_MAX / __SIZEOF_POINTER__) & ~(sizeof(long) * 8 - 1)))
int close_nointr(int fd);
int safe_close(int fd);
void safe_close_pair(int p[static 2]);
@ -148,7 +155,7 @@ static inline int fd_verify_safe_flags(int fd) {
return fd_verify_safe_flags_full(fd, 0);
}
int read_nr_open(void);
unsigned read_nr_open(void);
int fd_get_diskseq(int fd, uint64_t *ret);
int path_is_root_at(int dir_fd, const char *path);

View File

@ -8,19 +8,21 @@
#include_next <sched.h>
#include <assert.h>
/* 769071ac9f20b6a447410c7eaa55d1a5233ef40c (5.8),
* defined in sched.h since glibc-2.36. */
#ifndef CLONE_NEWTIME
# define CLONE_NEWTIME 0x00000080
#else
_Static_assert(CLONE_NEWTIME == 0x00000080, "");
static_assert(CLONE_NEWTIME == 0x00000080, "");
#endif
/* Not exposed yet. Defined at include/linux/sched.h */
#ifndef PF_KTHREAD
# define PF_KTHREAD 0x00200000
#else
_Static_assert(PF_KTHREAD == 0x00200000, "");
static_assert(PF_KTHREAD == 0x00200000, "");
#endif
/* The maximum thread/process name length including trailing NUL byte. This mimics the kernel definition of
@ -31,5 +33,5 @@ _Static_assert(PF_KTHREAD == 0x00200000, "");
#ifndef TASK_COMM_LEN
# define TASK_COMM_LEN 16
#else
_Static_assert(TASK_COMM_LEN == 16, "");
static_assert(TASK_COMM_LEN == 16, "");
#endif

View File

@ -3,16 +3,18 @@
#include_next <sys/mman.h>
#include <assert.h>
/* since glibc-2.38 */
#ifndef MFD_NOEXEC_SEAL
# define MFD_NOEXEC_SEAL 0x0008U
#else
_Static_assert(MFD_NOEXEC_SEAL == 0x0008U, "");
static_assert(MFD_NOEXEC_SEAL == 0x0008U, "");
#endif
/* since glibc-2.38 */
#ifndef MFD_EXEC
# define MFD_EXEC 0x0010U
#else
_Static_assert(MFD_EXEC == 0x0010U, "");
static_assert(MFD_EXEC == 0x0010U, "");
#endif

View File

@ -3,9 +3,11 @@
#include_next <sys/random.h>
#include <assert.h>
/* Defined since glibc-2.32. */
#ifndef GRND_INSECURE
# define GRND_INSECURE 0x0004
#else
_Static_assert(GRND_INSECURE == 0x0004, "");
static_assert(GRND_INSECURE == 0x0004, "");
#endif

View File

@ -3,9 +3,11 @@
#include_next <sys/wait.h>
#include <assert.h>
/* since glibc-2.36 */
#ifndef P_PIDFD
# define P_PIDFD 3
#else
_Static_assert(P_PIDFD == 3, "");
static_assert(P_PIDFD == 3, "");
#endif

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <sched.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <unistd.h>

View File

@ -42,6 +42,7 @@ int string_table_lookup_to_string_fallback(const char * const *table, size_t len
if (i < 0 || i > (ssize_t) max)
return -ERANGE;
if (i < (ssize_t) len && table[i]) {
s = strdup(table[i]);
if (!s)
@ -54,14 +55,14 @@ int string_table_lookup_to_string_fallback(const char * const *table, size_t len
}
ssize_t string_table_lookup_from_string_fallback(const char * const *table, size_t len, const char *s, size_t max) {
unsigned u = 0;
if (!s)
return -EINVAL;
ssize_t i = string_table_lookup_from_string(table, len, s);
if (i >= 0)
return i;
unsigned u;
if (safe_atou(s, &u) < 0)
return -EINVAL;
if (u > max)

View File

@ -1993,8 +1993,7 @@ static int unit_watch_cgroup(Unit *u) {
assert(u);
/* Watches the "cgroups.events" attribute of this unit's cgroup for "empty" events, but only if
* cgroupv2 is available. */
/* Watches the "cgroups.events" attribute of this unit's cgroup for "empty" events. */
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
if (!crt || !crt->cgroup_path)
@ -2038,8 +2037,7 @@ static int unit_watch_cgroup_memory(Unit *u) {
assert(u);
/* Watches the "memory.events" attribute of this unit's cgroup for "oom_kill" events, but only if
* cgroupv2 is available. */
/* Watches the "memory.events" attribute of this unit's cgroup for "oom_kill" events. */
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
if (!crt || !crt->cgroup_path)

View File

@ -3028,7 +3028,7 @@ int bus_exec_context_set_transient_property(
return r;
c->ioprio = ioprio_normalize(ioprio_prio_value(q, ioprio_prio_data(c->ioprio)));
c->ioprio_set = true;
c->ioprio_is_set = true;
unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
}
@ -3047,7 +3047,7 @@ int bus_exec_context_set_transient_property(
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
c->ioprio = ioprio_normalize(ioprio_prio_value(ioprio_prio_class(c->ioprio), p));
c->ioprio_set = true;
c->ioprio_is_set = true;
unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
}

View File

@ -5137,7 +5137,7 @@ int exec_invoke(
}
}
if (context->ioprio_set)
if (context->ioprio_is_set)
if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
*exit_status = EXIT_IOPRIO;
return log_error_errno(errno, "Failed to set up IO scheduling priority: %m");

View File

@ -1253,16 +1253,13 @@ static int exec_parameters_serialize(const ExecParameters *p, const ExecContext
}
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
int r, nr_open;
int r;
assert(p);
assert(f);
assert(fds);
nr_open = read_nr_open();
if (nr_open < 3)
nr_open = HIGH_RLIMIT_NOFILE;
assert(nr_open > 0); /* For compilers/static analyzers */
unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
for (;;) {
_cleanup_free_ char *l = NULL;
@ -1290,7 +1287,7 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
if (r < 0)
return r;
if (p->n_socket_fds > (size_t) nr_open)
if (p->n_socket_fds > nr_open)
return -EINVAL; /* too many, someone is playing games with us */
} else if ((val = startswith(l, "exec-parameters-n-storage-fds="))) {
if (p->fds)
@ -1300,7 +1297,7 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
if (r < 0)
return r;
if (p->n_storage_fds > (size_t) nr_open)
if (p->n_storage_fds > nr_open)
return -EINVAL; /* too many, someone is playing games with us */
} else if ((val = startswith(l, "exec-parameters-n-extra-fds="))) {
if (p->fds)
@ -1310,7 +1307,7 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
if (r < 0)
return r;
if (p->n_extra_fds > (size_t) nr_open)
if (p->n_extra_fds > nr_open)
return -EINVAL; /* too many, someone is playing games with us */
} else if ((val = startswith(l, "exec-parameters-fds="))) {
if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds == 0)
@ -1318,7 +1315,7 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
SYNTHETIC_ERRNO(EINVAL),
"Got exec-parameters-fds= without "
"prior exec-parameters-n-socket-fds= or exec-parameters-n-storage-fds= or exec-parameters-n-extra-fds=");
if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds > (size_t) nr_open)
if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds > nr_open)
return -EINVAL; /* too many, someone is playing games with us */
if (p->fds)
@ -1894,7 +1891,7 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
return r;
}
if (c->ioprio_set) {
if (c->ioprio_is_set) {
r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
if (r < 0)
return r;
@ -2859,7 +2856,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
r = safe_atoi(val, &c->ioprio);
if (r < 0)
return r;
c->ioprio_set = true;
c->ioprio_is_set = true;
} else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
c->cpu_sched_policy = sched_policy_from_string(val);
if (c->cpu_sched_policy < 0)

View File

@ -1245,7 +1245,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
prefix, rlimit_to_string(i), c->rlimit[i]->rlim_cur);
}
if (c->ioprio_set) {
if (c->ioprio_is_set) {
_cleanup_free_ char *class_str = NULL;
r = ioprio_class_to_string_alloc(ioprio_prio_class(c->ioprio), &class_str);
@ -1607,7 +1607,7 @@ int exec_context_get_effective_ioprio(const ExecContext *c) {
assert(c);
if (c->ioprio_set)
if (c->ioprio_is_set)
return c->ioprio;
p = ioprio_get(IOPRIO_WHO_PROCESS, 0);

View File

@ -190,7 +190,7 @@ typedef struct ExecContext {
bool oom_score_adjust_set:1;
bool coredump_filter_set:1;
bool nice_set:1;
bool ioprio_set:1;
bool ioprio_is_set:1;
bool cpu_sched_set:1;
/* This is not exposed to the user but available internally. We need it to make sure that whenever we

View File

@ -1450,7 +1450,7 @@ int config_parse_exec_io_class(
assert(rvalue);
if (isempty(rvalue)) {
c->ioprio_set = false;
c->ioprio_is_set = false;
c->ioprio = IOPRIO_DEFAULT_CLASS_AND_PRIO;
return 0;
}
@ -1462,7 +1462,7 @@ int config_parse_exec_io_class(
}
c->ioprio = ioprio_normalize(ioprio_prio_value(x, ioprio_prio_data(c->ioprio)));
c->ioprio_set = true;
c->ioprio_is_set = true;
return 0;
}
@ -1487,7 +1487,7 @@ int config_parse_exec_io_priority(
assert(rvalue);
if (isempty(rvalue)) {
c->ioprio_set = false;
c->ioprio_is_set = false;
c->ioprio = IOPRIO_DEFAULT_CLASS_AND_PRIO;
return 0;
}
@ -1499,7 +1499,7 @@ int config_parse_exec_io_priority(
}
c->ioprio = ioprio_normalize(ioprio_prio_value(ioprio_prio_class(c->ioprio), i));
c->ioprio_set = true;
c->ioprio_is_set = true;
return 0;
}

View File

@ -1275,38 +1275,20 @@ static void bump_file_max_and_nr_open(void) {
#endif
#if BUMP_PROC_SYS_FS_NR_OPEN
int v = INT_MAX;
/* The kernel enforces maximum and minimum values on the fs.nr_open, but they are not directly
* exposed, but hardcoded in fs/file.c. Hopefully, these values will not be changed, but not sure.
* Let's first try the hardcoded maximum value, and if it does not work, try the half of it. */
/* Argh! The kernel enforces maximum and minimum values on the fs.nr_open, but we don't really know
* what they are. The expression by which the maximum is determined is dependent on the architecture,
* and is something we don't really want to copy to userspace, as it is dependent on implementation
* details of the kernel. Since the kernel doesn't expose the maximum value to us, we can only try
* and hope. Hence, let's start with INT_MAX, and then keep halving the value until we find one that
* works. Ugly? Yes, absolutely, but kernel APIs are kernel APIs, so what do can we do... 🤯 */
for (;;) {
int k;
v &= ~(__SIZEOF_POINTER__ - 1); /* Round down to next multiple of the pointer size */
if (v < 1024) {
log_warning("Can't bump fs.nr_open, value too small.");
break;
}
k = read_nr_open();
if (k < 0) {
log_error_errno(k, "Failed to read fs.nr_open: %m");
break;
}
for (unsigned v = NR_OPEN_MAXIMUM; v >= NR_OPEN_MINIMUM; v /= 2) {
unsigned k = read_nr_open();
if (k >= v) { /* Already larger */
log_debug("Skipping bump, value is already larger.");
break;
}
r = sysctl_writef("fs/nr_open", "%i", v);
r = sysctl_writef("fs/nr_open", "%u", v);
if (r == -EINVAL) {
log_debug("Couldn't write fs.nr_open as %i, halving it.", v);
v /= 2;
log_debug("Couldn't write fs.nr_open as %u, halving it.", v);
continue;
}
if (r < 0) {
@ -1314,7 +1296,7 @@ static void bump_file_max_and_nr_open(void) {
break;
}
log_debug("Successfully bumped fs.nr_open to %i", v);
log_debug("Successfully bumped fs.nr_open to %u", v);
break;
}
#endif
@ -1322,10 +1304,10 @@ static void bump_file_max_and_nr_open(void) {
static int bump_rlimit_nofile(const struct rlimit *saved_rlimit) {
struct rlimit new_rlimit;
int r, nr;
int r;
/* Get the underlying absolute limit the kernel enforces */
nr = read_nr_open();
unsigned nr = read_nr_open();
/* Calculate the new limits to use for us. Never lower from what we inherited. */
new_rlimit = (struct rlimit) {
@ -2690,14 +2672,8 @@ static void fallback_rlimit_nofile(const struct rlimit *saved_rlimit_nofile) {
* (and thus use poll()/epoll instead of select(), the way everybody should) can
* explicitly opt into high fds by bumping their soft limit beyond 1024, to the hard limit
* we pass. */
if (arg_runtime_scope == RUNTIME_SCOPE_SYSTEM) {
int nr;
/* Get the underlying absolute limit the kernel enforces */
nr = read_nr_open();
rl->rlim_max = MIN((rlim_t) nr, MAX(rl->rlim_max, (rlim_t) HIGH_RLIMIT_NOFILE));
}
if (arg_runtime_scope == RUNTIME_SCOPE_SYSTEM)
rl->rlim_max = MIN((rlim_t) read_nr_open(), MAX(rl->rlim_max, (rlim_t) HIGH_RLIMIT_NOFILE));
/* If for some reason we were invoked with a soft limit above 1024 (which should never
* happen!, but who knows what we get passed in from pam_limit when invoked as --user

View File

@ -6,6 +6,7 @@
#include <linux/veth.h>
#include <net/if.h>
#include <poll.h>
#include <sched.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>

View File

@ -12,7 +12,9 @@ generated_sources += test_hashmap_ordered_c
path = run_command(sh, '-c', 'echo "$PATH"', check: true).stdout().strip()
test_env = environment()
test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
if conf.get('ENABLE_LOCALED') == 1
test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
endif
test_env.set('PATH', meson.project_build_root() + ':' + path)
test_env.set('PROJECT_BUILD_ROOT', meson.project_build_root())
test_env.set('SYSTEMD_SLOW_TESTS', want_slow_tests ? '1' : '0')

View File

@ -228,7 +228,7 @@ TEST(rearrange_stdio) {
}
TEST(read_nr_open) {
log_info("nr-open: %i", read_nr_open());
log_info("nr-open: %u", read_nr_open());
}
static size_t validate_fds(

View File

@ -310,7 +310,7 @@ class UkifyConfig:
class Uname:
# This class is here purely as a namespace for the functions
VERSION_PATTERN = r'(?P<version>[a-z0-9._-]+) \([^ )]+\) (?:#.*)'
VERSION_PATTERN = r'(?P<version>[a-z0-9._+-]+) \([^ )]+\) (?:#.*)'
NOTES_PATTERN = r'^\s+Linux\s+0x[0-9a-f]+\s+OPEN\n\s+description data: (?P<version>[0-9a-f ]+)\s*$'

View File

@ -7,7 +7,10 @@ udev_storage_test_template = {
}
qemu = find_program('qemu-system-@0@'.format(host_machine.cpu_family()), 'qemu-kvm', dirs : ['/usr/libexec'], native : true, required : false)
if qemu.found()
if qemu.found() and host_machine.cpu_family() == 'aarch64'
# qemu-system-aarch64 errors out if no machine is specified
devices = run_command(qemu, '-device', 'help', '-machine', 'virt', check : true).stdout().strip()
elif qemu.found()
devices = run_command(qemu, '-device', 'help', check : true).stdout().strip()
else
devices = ''