mirror of
https://github.com/systemd/systemd
synced 2025-10-09 13:44:44 +02:00
Compare commits
17 Commits
f89a52e360
...
ffe8f21302
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ffe8f21302 | ||
![]() |
a8f8b3efb5 | ||
![]() |
2643cb1ade | ||
![]() |
c56e251d3f | ||
![]() |
8d29f31bf6 | ||
![]() |
cfba9b9eab | ||
![]() |
6cc01c8cc4 | ||
![]() |
ebfd56975e | ||
![]() |
b0d40944b3 | ||
![]() |
e7f04514c1 | ||
![]() |
225de2729d | ||
![]() |
cdbc500faa | ||
![]() |
b6fde0875b | ||
![]() |
d33104eba2 | ||
![]() |
68c703872c | ||
![]() |
163e666204 | ||
![]() |
ec0bbbd2a9 |
9
.github/workflows/unit_tests.sh
vendored
9
.github/workflows/unit_tests.sh
vendored
@ -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)
|
||||
|
@ -68,5 +68,5 @@ usb:v2B71p000E*
|
||||
# PowerSpec Ultra 3DPrinter
|
||||
usb:v0315p0001*
|
||||
usb:v2B71p00F6*
|
||||
usb:v2B71p00FF
|
||||
usb:v2B71p00FF*
|
||||
ID_MAKER_TOOL=1
|
||||
|
@ -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',
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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')
|
||||
|
@ -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(
|
||||
|
@ -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*$'
|
||||
|
||||
|
@ -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 = ''
|
||||
|
Loading…
x
Reference in New Issue
Block a user