1
0
mirror of https://github.com/systemd/systemd synced 2026-04-09 16:44:51 +02:00

Compare commits

..

28 Commits

Author SHA1 Message Date
Yu Watanabe
99f8a6d7f5
Merge pull request #21581 from keszybz/really-random-fixlets
Really random fixlets
2021-12-01 12:54:00 +09:00
Yu Watanabe
361bf5fb77
Merge pull request #21564 from yuwata/errno-eagain-eintr
tree-wide: introduce ERRNO_IS_TRANSIENT() and use it
2021-12-01 12:52:27 +09:00
Yu Watanabe
db58f6a933
Merge pull request #21536 from medhefgo/test
test: Introduce TEST_RET macro
2021-12-01 12:52:10 +09:00
Yu Watanabe
c8cbe8e0eb
Merge pull request #21288 from loongarch64/la64/main
Add support for the LoongArch architecture.
2021-12-01 12:51:48 +09:00
Luca Boccassi
c7b5d3b5e4
Merge pull request #21553 from yuwata/network-wireguard-add-routes-to-allowed-ips
network: wireguard: add routes to AllowedIPs=
2021-11-30 23:30:31 +00:00
Zbigniew Jędrzejewski-Szmek
160dadc035 tmpfiles: 'st' may have been used uninitialized 2021-11-30 22:57:31 +01:00
Zbigniew Jędrzejewski-Szmek
baf60a80b5 man: prettify line number handling in python example
This way the 'line_number' variable contains the actual line number as we think
of it, instead of adjusting it on output.
2021-11-30 22:56:51 +01:00
Zbigniew Jędrzejewski-Szmek
75c293f37d test-sizeof: show stack and heap randomization
It's useful to reassure yourself those those things actually work ;)
2021-11-30 22:55:15 +01:00
Yu Watanabe
6387cac3f3 test-network: add tests for creating routes to wireguard's AllowedIPs= 2021-12-01 04:00:16 +09:00
Yu Watanabe
e908434458 network: wireguard: automatically configure routes to addresses specified in AllowedIPs=
Closes #14176.
2021-12-01 04:00:11 +09:00
Yu Watanabe
28870a9d2e network: route: expose route_hash_ops 2021-12-01 03:56:00 +09:00
Yu Watanabe
9e11bd58fb network/wireguard: drop unnecessary .in6 specifier
This should not change any behavior, as the size of the IPv4 address is
smaller than IPv6.
2021-12-01 03:56:00 +09:00
Yu Watanabe
5e82a61375 network: route: read RTA_TABLE attribute to get route table
If the table of a route is larger than 255, then the value is stored in
RTA_TABLE attribute. But the attribute is not supported by old kernels.
So, first try to read the value from RTA_TABLE attribute, then fallback
to the value in the message header.
2021-12-01 03:53:09 +09:00
Yu Watanabe
af31670340 network: route: use typesafe function 2021-12-01 03:52:11 +09:00
Zbigniew Jędrzejewski-Szmek
5f1d6ebd2a oomd: use type suffix instead of casting
The end result is the same.
2021-11-30 18:42:47 +01:00
Xiaotian Wu
0444a6e4be gpt: update the gpt test case for LoongArch 2021-11-30 23:34:29 +08:00
Wu Xiaotian
5c0968a2d1 architecture: Add support for the LoongArch architecture 2021-11-30 23:34:20 +08:00
Yu Watanabe
b3d06b9226 libsystemd: ignore both EINTR and EAGAIN 2021-11-30 23:06:43 +09:00
Yu Watanabe
8add30a03c tree-wide: use ERRNO_IS_TRANSIENT() 2021-11-30 23:06:43 +09:00
Yu Watanabe
7aad83580f errno-util: introduce ERRNO_IS_TRANSIENT() 2021-11-30 23:06:43 +09:00
Yu Watanabe
16edfadc67 ask-password: fix error handling
ERRNO_IS_NOT_SUPPORTED() also matches positive values.
Fortunately, lookup_key() does not return positive values.
2021-11-30 23:05:24 +09:00
Yu Watanabe
97e80ee4a8 sd-dhcp6-client: fix error handling 2021-11-30 22:37:21 +09:00
Jan Janssen
5a45a6bbb6 test-parse-util: Add SI-suffix parse_size tests 2021-11-28 11:48:34 +01:00
Jan Janssen
d19bff65ee test-namespace: Convert to TEST macro 2021-11-28 11:48:34 +01:00
Jan Janssen
353b980204 test-barrier: Convert to TEST macro 2021-11-28 11:48:34 +01:00
Jan Janssen
26e555cbba test: Convert to TEST/TEST_RET macros
Note that test-cgroup-mask, test-cgroup-unit-default and test-unit-name will now
report being skipped instead of reporting success if not run under systemd.
2021-11-28 11:46:26 +01:00
Jan Janssen
0578dfe3eb test: Add sd_booted condition test to TEST macro
Note that this will only report test skips if they use TEST_RET macro.
Regular TEST macros can still be skipped, but this will not be reported
back to main();
2021-11-28 11:42:28 +01:00
Jan Janssen
4c0acc0761 test: Add TEST_RET macro
This declares a test function whose return code will be passed from
main(). The first test that does not return EXIT_SUCCESS wins.
2021-11-28 11:40:45 +01:00
61 changed files with 904 additions and 615 deletions

View File

@ -13,7 +13,7 @@ def read_os_release():
filename = '/usr/lib/os-release'
f = open(filename)
for line_number, line in enumerate(f):
for line_number, line in enumerate(f, start=1):
line = line.rstrip()
if not line or line.startswith('#'):
continue
@ -23,7 +23,7 @@ def read_os_release():
val = ast.literal_eval(val)
yield name, val
else:
print(f'{filename}:{line_number + 1}: bad line {line!r}',
print(f'{filename}:{line_number}: bad line {line!r}',
file=sys.stderr)
os_release = dict(read_os_release())

View File

@ -1569,6 +1569,29 @@
<para>Sets a firewall mark on outgoing WireGuard packets from this interface. Takes a number between 1 and 4294967295.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteTable=</varname></term>
<listitem>
<para>The table identifier for the routes to the addresses specified in the
<varname>AllowedIPs=</varname>. Takes the special value <literal>off</literal>, one of the
predefined names <literal>default</literal>, <literal>main</literal>, and
<literal>local</literal>, names defined in <varname>RouteTable=</varname> in
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
or a number in the range 1…4294967295. When <literal>off</literal> the routes to the
addresses specified in the <varname>AllowedIPs=</varname> setting will not be configured.
Defaults to <literal>main</literal>. This setting will be ignored when the same setting is
specified in the [WireGuardPeer] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The priority of the routes to the addresses specified in the
<varname>AllowedIPs=</varname>. Takes an integer in the range 0…4294967295. Defaults to 0
for IPv4 addresses, and 1024 for IPv6 addresses. This setting will be ignored when the same
setting is specified in the [WireGuardPeer] section.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -1653,6 +1676,27 @@
Most users will not need this.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteTable=</varname></term>
<listitem>
<para>The table identifier for the routes to the addresses specified in the
<varname>AllowedIPs=</varname>. Takes the special value <literal>off</literal>, one of the
predefined names <literal>default</literal>, <literal>main</literal>, and
<literal>local</literal>, names defined in <varname>RouteTable=</varname> in
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
or a number in the range 1…4294967295. Defaults to unset, and the value specified in the
same setting in the [WireGuard] section will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The priority of the routes to the addresses specified in the
<varname>AllowedIPs=</varname>. Takes an integer in the range 0…4294967295. Defaults to
unset, and the value specified in the same setting in the [WireGuard] section will be used.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -70,6 +70,9 @@ int uname_architecture(void) {
{ "parisc64", ARCHITECTURE_PARISC64 },
{ "parisc", ARCHITECTURE_PARISC },
#elif defined(__loongarch64)
{ "loongarch64", ARCHITECTURE_LOONGARCH64 },
#elif defined(__m68k__)
{ "m68k", ARCHITECTURE_M68K },
@ -137,38 +140,39 @@ int uname_architecture(void) {
/* Maintain same order as in the table above. */
static const char *const architecture_table[_ARCHITECTURE_MAX] = {
[ARCHITECTURE_ARM64] = "arm64",
[ARCHITECTURE_ARM64_BE] = "arm64-be",
[ARCHITECTURE_ARM] = "arm",
[ARCHITECTURE_ARM_BE] = "arm-be",
[ARCHITECTURE_ALPHA] = "alpha",
[ARCHITECTURE_ARC] = "arc",
[ARCHITECTURE_ARC_BE] = "arc-be",
[ARCHITECTURE_CRIS] = "cris",
[ARCHITECTURE_X86_64] = "x86-64",
[ARCHITECTURE_X86] = "x86",
[ARCHITECTURE_IA64] = "ia64",
[ARCHITECTURE_M68K] = "m68k",
[ARCHITECTURE_MIPS64_LE] = "mips64-le",
[ARCHITECTURE_MIPS64] = "mips64",
[ARCHITECTURE_MIPS_LE] = "mips-le",
[ARCHITECTURE_MIPS] = "mips",
[ARCHITECTURE_NIOS2] = "nios2",
[ARCHITECTURE_PARISC64] = "parisc64",
[ARCHITECTURE_PARISC] = "parisc",
[ARCHITECTURE_PPC64_LE] = "ppc64-le",
[ARCHITECTURE_PPC64] = "ppc64",
[ARCHITECTURE_PPC] = "ppc",
[ARCHITECTURE_PPC_LE] = "ppc-le",
[ARCHITECTURE_RISCV32] = "riscv32",
[ARCHITECTURE_RISCV64] = "riscv64",
[ARCHITECTURE_S390X] = "s390x",
[ARCHITECTURE_S390] = "s390",
[ARCHITECTURE_SH64] = "sh64",
[ARCHITECTURE_SH] = "sh",
[ARCHITECTURE_SPARC64] = "sparc64",
[ARCHITECTURE_SPARC] = "sparc",
[ARCHITECTURE_TILEGX] = "tilegx",
[ARCHITECTURE_ARM64] = "arm64",
[ARCHITECTURE_ARM64_BE] = "arm64-be",
[ARCHITECTURE_ARM] = "arm",
[ARCHITECTURE_ARM_BE] = "arm-be",
[ARCHITECTURE_ALPHA] = "alpha",
[ARCHITECTURE_ARC] = "arc",
[ARCHITECTURE_ARC_BE] = "arc-be",
[ARCHITECTURE_CRIS] = "cris",
[ARCHITECTURE_X86_64] = "x86-64",
[ARCHITECTURE_X86] = "x86",
[ARCHITECTURE_IA64] = "ia64",
[ARCHITECTURE_LOONGARCH64] = "loongarch64",
[ARCHITECTURE_M68K] = "m68k",
[ARCHITECTURE_MIPS64_LE] = "mips64-le",
[ARCHITECTURE_MIPS64] = "mips64",
[ARCHITECTURE_MIPS_LE] = "mips-le",
[ARCHITECTURE_MIPS] = "mips",
[ARCHITECTURE_NIOS2] = "nios2",
[ARCHITECTURE_PARISC64] = "parisc64",
[ARCHITECTURE_PARISC] = "parisc",
[ARCHITECTURE_PPC64_LE] = "ppc64-le",
[ARCHITECTURE_PPC64] = "ppc64",
[ARCHITECTURE_PPC] = "ppc",
[ARCHITECTURE_PPC_LE] = "ppc-le",
[ARCHITECTURE_RISCV32] = "riscv32",
[ARCHITECTURE_RISCV64] = "riscv64",
[ARCHITECTURE_S390X] = "s390x",
[ARCHITECTURE_S390] = "s390",
[ARCHITECTURE_SH64] = "sh64",
[ARCHITECTURE_SH] = "sh",
[ARCHITECTURE_SPARC64] = "sparc64",
[ARCHITECTURE_SPARC] = "sparc",
[ARCHITECTURE_TILEGX] = "tilegx",
};
DEFINE_STRING_TABLE_LOOKUP(architecture, int);

View File

@ -20,6 +20,7 @@ typedef enum {
ARCHITECTURE_ARM_BE,
ARCHITECTURE_CRIS,
ARCHITECTURE_IA64,
ARCHITECTURE_LOONGARCH64,
ARCHITECTURE_M68K,
ARCHITECTURE_MIPS,
ARCHITECTURE_MIPS64,
@ -197,6 +198,10 @@ int uname_architecture(void);
# elif defined(__SH4A__)
# define LIB_ARCH_TUPLE "sh4a-linux-gnu"
# endif
#elif defined(__loongarch64)
# pragma message "Please update the Arch tuple of loongarch64 after psABI is stable"
# define native_architecture() ARCHITECTURE_LOONGARCH64
# define LIB_ARCH_TUPLE "loongarch64-linux-gnu"
#elif defined(__m68k__)
# define native_architecture() ARCHITECTURE_M68K
# define LIB_ARCH_TUPLE "m68k-linux-gnu"

View File

@ -70,6 +70,13 @@ static inline int errno_or_else(int fallback) {
return -abs(fallback);
}
/* For send()/recv() or read()/write(). */
static inline bool ERRNO_IS_TRANSIENT(int r) {
return IN_SET(abs(r),
EAGAIN,
EINTR);
}
/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
*
* Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the
@ -100,10 +107,8 @@ static inline bool ERRNO_IS_DISCONNECT(int r) {
* the accept(2) man page. */
static inline bool ERRNO_IS_ACCEPT_AGAIN(int r) {
return ERRNO_IS_DISCONNECT(r) ||
IN_SET(abs(r),
EAGAIN,
EINTR,
EOPNOTSUPP);
ERRNO_IS_TRANSIENT(r) ||
abs(r) == EOPNOTSUPP;
}
/* Resource exhaustion, could be our fault or general system trouble */

View File

@ -453,7 +453,7 @@ int acquire_terminal(
l = read(notify, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EINTR, EAGAIN))
if (ERRNO_IS_TRANSIENT(errno))
continue;
return -errno;

View File

@ -3191,7 +3191,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents,
l = read(fd, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EINTR, EAGAIN))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return log_error_errno(errno, "Failed to read control group inotify events: %m");

View File

@ -2445,18 +2445,19 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
}
n = recvmsg_safe(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC);
if (IN_SET(n, -EAGAIN, -EINTR))
return 0; /* Spurious wakeup, try again */
if (n == -EXFULL) {
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
return 0;
}
if (n < 0)
if (n < 0) {
if (ERRNO_IS_TRANSIENT(n))
return 0; /* Spurious wakeup, try again */
if (n == -EXFULL) {
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
return 0;
}
/* If this is any other, real error, then let's stop processing this socket. This of course
* means we won't take notification messages anymore, but that's still better than busy
* looping around this: being woken up over and over again but being unable to actually read
* the message off the socket. */
return log_error_errno(n, "Failed to receive notification message: %m");
}
CMSG_FOREACH(cmsg, &msghdr) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
@ -2716,19 +2717,18 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
}
n = read(m->signal_fd, &sfsi, sizeof(sfsi));
if (n != sizeof(sfsi)) {
if (n >= 0) {
log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n);
return 0;
}
if (IN_SET(errno, EINTR, EAGAIN))
if (n < 0) {
if (ERRNO_IS_TRANSIENT(errno))
return 0;
/* We return an error here, which will kill this handler,
* to avoid a busy loop on read error. */
return log_error_errno(errno, "Reading from signal fd failed: %m");
}
if (n != sizeof(sfsi)) {
log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n);
return 0;
}
log_received_signal(sfsi.ssi_signo == SIGCHLD ||
(sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m))
@ -4263,7 +4263,7 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re
l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT);
if (l < 0) {
if (IN_SET(errno, EINTR, EAGAIN))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return log_error_errno(errno, "Failed to read from user lookup fd: %m");

View File

@ -184,7 +184,7 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) {
l = read(s->inotify_fd, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return log_error_errno(errno, "Failed to read inotify event: %m");

View File

@ -1122,10 +1122,11 @@ static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *
assert(m);
n = read_datagram(fd, &sender, &datagram, &passed_fd);
if (IN_SET(n, -EAGAIN, -EINTR))
return 0;
if (n < 0)
if (n < 0) {
if (ERRNO_IS_TRANSIENT(n))
return 0;
return log_error_errno(n, "Failed to read notify datagram: %m");
}
if (sender.pid <= 0) {
log_warning("Received notify datagram without valid sender PID, ignoring.");

View File

@ -567,10 +567,11 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void
int r;
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (IN_SET(n, -EAGAIN, -EINTR))
return 0;
if (n < 0)
if (n < 0) {
if (ERRNO_IS_TRANSIENT(n))
return 0;
return (int) n;
}
cmsg_close_all(&msghdr);

View File

@ -326,7 +326,7 @@ static int server_read_dev_kmsg(Server *s) {
return 0;
}
if (IN_SET(errno, EAGAIN, EINTR, EPIPE))
if (ERRNO_IS_TRANSIENT(errno) || errno == EPIPE)
return 0;
return log_error_errno(errno, "Failed to read from /dev/kmsg: %m");

View File

@ -1317,14 +1317,15 @@ int server_process_datagram(
iovec = IOVEC_MAKE(s->buffer, MALLOC_ELEMENTSOF(s->buffer) - 1); /* Leave room for trailing NUL we add later */
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (IN_SET(n, -EINTR, -EAGAIN))
return 0;
if (n == -EXFULL) {
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
return 0;
}
if (n < 0)
if (n < 0) {
if (ERRNO_IS_TRANSIENT(n))
return 0;
if (n == -EXFULL) {
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
return 0;
}
return log_error_errno(n, "recvmsg() failed: %m");
}
CMSG_FOREACH(cmsg, &msghdr)
if (cmsg->cmsg_level == SOL_SOCKET &&

View File

@ -588,7 +588,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (l < 0) {
if (IN_SET(errno, EINTR, EAGAIN))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
log_warning_errno(errno, "Failed to read from stream: %m");

View File

@ -1945,7 +1945,7 @@ static int client_receive_message_udp(
len = recv(fd, message, buflen, 0);
if (len < 0) {
/* see comment above for why we shouldn't error out on ENETDOWN. */
if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
if (ERRNO_IS_TRANSIENT(errno) || errno == ENETDOWN)
return 0;
return log_dhcp_client_errno(client, errno,
@ -2035,12 +2035,12 @@ static int client_receive_message_raw(
iov = IOVEC_MAKE(packet, buflen);
len = recvmsg_safe(fd, &msg, 0);
if (IN_SET(len, -EAGAIN, -EINTR, -ENETDOWN))
return 0;
if (len < 0)
if (len < 0) {
if (ERRNO_IS_TRANSIENT(len) || len == -ENETDOWN)
return 0;
return log_dhcp_client_errno(client, len,
"Could not receive message from raw socket: %m");
}
if ((size_t) len < sizeof(DHCPPacket))
return 0;

View File

@ -1206,10 +1206,12 @@ static int server_receive_message(sd_event_source *s, int fd,
iov = IOVEC_MAKE(message, datagram_size);
len = recvmsg_safe(fd, &msg, 0);
if (IN_SET(len, -EAGAIN, -EINTR))
return 0;
if (len < 0)
if (len < 0) {
if (ERRNO_IS_TRANSIENT(len))
return 0;
return len;
}
if ((size_t) len < sizeof(DHCPMessage))
return 0;

View File

@ -1479,10 +1479,10 @@ static int client_receive_message(
len = recvmsg_safe(fd, &msg, MSG_DONTWAIT);
if (len < 0) {
/* see comment above for why we shouldn't error out on ENETDOWN. */
if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
if (ERRNO_IS_TRANSIENT(len) || len == -ENETDOWN)
return 0;
return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m");
return log_dhcp6_client_errno(client, len, "Could not receive message from UDP socket: %m");
}
if ((size_t) len < sizeof(DHCP6Message)) {

View File

@ -362,7 +362,7 @@ static int ipv4acd_on_packet(
n = recv(fd, &packet, sizeof(struct ether_arp), 0);
if (n < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m");

View File

@ -212,7 +212,7 @@ static int lldp_rx_receive_datagram(sd_event_source *s, int fd, uint32_t revents
length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT);
if (length < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
log_lldp_rx_errno(lldp_rx, errno, "Failed to read LLDP datagram, ignoring: %m");

View File

@ -149,7 +149,7 @@ static int bus_socket_write_auth(sd_bus *b) {
}
if (k < 0)
return errno == EAGAIN ? 0 : -errno;
return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno;
iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
return 1;
@ -565,10 +565,11 @@ static int bus_socket_read_auth(sd_bus *b) {
} else
handle_cmsg = true;
}
if (k == -EAGAIN)
return 0;
if (k < 0)
if (k < 0) {
if (ERRNO_IS_TRANSIENT(k))
return 0;
return (int) k;
}
if (k == 0) {
if (handle_cmsg)
cmsg_close_all(&mh); /* paranoia, we shouldn't have gotten any fds on EOF */
@ -1073,7 +1074,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
}
if (k < 0)
return errno == EAGAIN ? 0 : -errno;
return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno;
*idx += (size_t) k;
return 1;
@ -1230,10 +1231,11 @@ int bus_socket_read_message(sd_bus *bus) {
} else
handle_cmsg = true;
}
if (k == -EAGAIN)
return 0;
if (k < 0)
if (k < 0) {
if (ERRNO_IS_TRANSIENT(k))
return 0;
return (int) k;
}
if (k == 0) {
if (handle_cmsg)
cmsg_close_all(&mh); /* On EOF we shouldn't have gotten an fd, but let's make sure */

View File

@ -445,7 +445,7 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
buflen = recvmsg(m->sock, &smsg, 0);
if (buflen < 0) {
if (errno != EINTR)
if (ERRNO_IS_TRANSIENT(errno))
log_debug_errno(errno, "sd-device-monitor: Failed to receive message: %m");
return -errno;
}

View File

@ -3142,7 +3142,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
ss = read(fd, &x, sizeof(x));
if (ss < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return -errno;
@ -3348,7 +3348,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events, i
n = read(d->fd, &si, sizeof(si));
if (n < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return -errno;
@ -3402,7 +3402,7 @@ static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t
n = read(d->fd, &d->buffer, sizeof(d->buffer));
if (n < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return -errno;

View File

@ -2698,7 +2698,7 @@ _public_ int sd_journal_process(sd_journal *j) {
l = read(j->inotify_fd, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return got_something ? determine_change(j) : SD_JOURNAL_NOP;
return -errno;

View File

@ -235,12 +235,13 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
assert(iov);
n = recvmsg_safe(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
if (n == -ENOBUFS)
return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun");
if (IN_SET(n, -EAGAIN, -EINTR))
return 0;
if (n < 0)
if (n < 0) {
if (n == -ENOBUFS)
return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun");
if (ERRNO_IS_TRANSIENT(n))
return 0;
return (int) n;
}
if (sender.nl.nl_pid != 0) {
/* not from the kernel, ignore */

View File

@ -462,7 +462,7 @@ _public_ int sd_network_monitor_flush(sd_network_monitor *m) {
l = read(fd, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return -errno;

View File

@ -418,7 +418,7 @@ static void* thread_worker(void *p) {
length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0);
if (length < 0) {
if (errno == EINTR)
if (ERRNO_IS_TRANSIENT(errno))
continue;
break;
@ -847,7 +847,7 @@ _public_ int sd_resolve_process(sd_resolve *resolve) {
l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0);
if (l < 0) {
if (errno == EAGAIN)
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return -errno;

View File

@ -229,12 +229,16 @@ WireGuard.FwMark, config_parse_unsigned,
WireGuard.ListenPort, config_parse_wireguard_listen_port, 0, offsetof(Wireguard, port)
WireGuard.PrivateKey, config_parse_wireguard_private_key, 0, 0
WireGuard.PrivateKeyFile, config_parse_wireguard_private_key_file, 0, 0
WireGuard.RouteTable, config_parse_wireguard_route_table, 0, offsetof(Wireguard, route_table)
WireGuard.RouteMetric, config_parse_wireguard_route_priority, 0, offsetof(Wireguard, route_priority)
WireGuardPeer.AllowedIPs, config_parse_wireguard_allowed_ips, 0, 0
WireGuardPeer.Endpoint, config_parse_wireguard_endpoint, 0, 0
WireGuardPeer.PublicKey, config_parse_wireguard_peer_key, 0, 0
WireGuardPeer.PresharedKey, config_parse_wireguard_peer_key, 0, 0
WireGuardPeer.PresharedKeyFile, config_parse_wireguard_preshared_key_file, 0, 0
WireGuardPeer.PersistentKeepalive, config_parse_wireguard_keepalive, 0, 0
WireGuardPeer.RouteTable, config_parse_wireguard_peer_route_table, 0, 0
WireGuardPeer.RouteMetric, config_parse_wireguard_peer_route_priority,0, 0
Xfrm.InterfaceId, config_parse_uint32, 0, offsetof(Xfrm, if_id)
Xfrm.Independent, config_parse_bool, 0, offsetof(Xfrm, independent)
BatmanAdvanced.Aggregation, config_parse_bool, 0, offsetof(BatmanAdvanced, aggregation)

View File

@ -7,6 +7,7 @@
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include <linux/ipv6_route.h>
#include "sd-resolve.h"
@ -18,6 +19,8 @@
#include "memory-util.h"
#include "netlink-util.h"
#include "networkd-manager.h"
#include "networkd-route-util.h"
#include "networkd-route.h"
#include "networkd-util.h"
#include "parse-util.h"
#include "path-util.h"
@ -696,7 +699,7 @@ int config_parse_wireguard_allowed_ips(
*ipmask = (WireguardIPmask) {
.family = family,
.ip.in6 = addr.in6,
.ip = addr,
.cidr = prefixlen,
};
@ -827,6 +830,186 @@ int config_parse_wireguard_keepalive(
return 0;
}
int config_parse_wireguard_route_table(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
NetDev *netdev = userdata;
uint32_t *table = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
assert(userdata);
if (isempty(rvalue)) {
*table = RT_TABLE_MAIN;
return 0;
}
if (streq(rvalue, "off")) {
*table = 0;
return 0;
}
r = manager_get_route_table_from_string(netdev->manager, rvalue, table);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
return 0;
}
int config_parse_wireguard_peer_route_table(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
NetDev *netdev = userdata;
Wireguard *w;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(netdev);
assert(netdev->manager);
w = WIREGUARD(netdev);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
peer->route_table_set = false; /* Use the table specified in [WireGuard] section. */
TAKE_PTR(peer);
return 0;
}
if (streq(rvalue, "off")) {
peer->route_table = 0; /* Disabled. */
peer->route_table_set = true;
TAKE_PTR(peer);
return 0;
}
r = manager_get_route_table_from_string(netdev->manager, rvalue, &peer->route_table);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
peer->route_table_set = true;
TAKE_PTR(peer);
return 0;
}
int config_parse_wireguard_route_priority(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
uint32_t *priority = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
*priority = 0;
return 0;
}
r = safe_atou32(rvalue, priority);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse route priority \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
return 0;
}
int config_parse_wireguard_peer_route_priority(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
Wireguard *w;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(userdata);
w = WIREGUARD(userdata);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
peer->route_priority_set = false; /* Use the priority specified in [WireGuard] section. */
TAKE_PTR(peer);
return 0;
}
r = safe_atou32(rvalue, &peer->route_priority);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse route priority \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
peer->route_priority_set = true;
TAKE_PTR(peer);
return 0;
}
static void wireguard_init(NetDev *netdev) {
Wireguard *w;
@ -835,6 +1018,7 @@ static void wireguard_init(NetDev *netdev) {
assert(w);
w->flags = WGDEVICE_F_REPLACE_PEERS;
w->route_table = RT_TABLE_MAIN;
}
static void wireguard_done(NetDev *netdev) {
@ -852,6 +1036,8 @@ static void wireguard_done(NetDev *netdev) {
hashmap_free_with_destructor(w->peers_by_section, wireguard_peer_free);
set_free(w->peers_with_unresolved_endpoint);
set_free(w->peers_with_failed_endpoint);
set_free(w->routes);
}
static int wireguard_read_key_file(const char *filename, uint8_t dest[static WG_KEY_LEN]) {
@ -924,9 +1110,40 @@ static int wireguard_verify(NetDev *netdev, const char *filename) {
"%s: Missing PrivateKey= or PrivateKeyFile=, "
"Ignoring network device.", filename);
LIST_FOREACH_SAFE(peers, peer, peer_next, w->peers)
if (wireguard_peer_verify(peer) < 0)
LIST_FOREACH_SAFE(peers, peer, peer_next, w->peers) {
WireguardIPmask *ipmask;
if (wireguard_peer_verify(peer) < 0) {
wireguard_peer_free(peer);
continue;
}
if ((peer->route_table_set ? peer->route_table : w->route_table) == 0)
continue;
LIST_FOREACH(ipmasks, ipmask, peer->ipmasks) {
_cleanup_(route_freep) Route *route = NULL;
r = route_new(&route);
if (r < 0)
return log_oom();
route->family = ipmask->family;
route->dst = ipmask->ip;
route->dst_prefixlen = ipmask->cidr;
route->scope = RT_SCOPE_UNIVERSE;
route->protocol = RTPROT_STATIC;
route->table = peer->route_table_set ? peer->route_table : w->route_table;
route->priority = peer->route_priority_set ? peer->route_priority : w->route_priority;
if (route->priority == 0 && route->family == AF_INET6)
route->priority = IP6_RT_PRIO_USER;
route->source = NETWORK_CONFIG_SOURCE_STATIC;
r = set_ensure_consume(&w->routes, &route_hash_ops, TAKE_PTR(route));
if (r < 0)
return log_oom();
}
}
return 0;
}

View File

@ -33,6 +33,11 @@ typedef struct WireguardPeer {
char *endpoint_host;
char *endpoint_port;
uint32_t route_table;
uint32_t route_priority;
bool route_table_set;
bool route_priority_set;
LIST_HEAD(WireguardIPmask, ipmasks);
LIST_FIELDS(struct WireguardPeer, peers);
} WireguardPeer;
@ -55,6 +60,10 @@ struct Wireguard {
unsigned n_retries;
sd_event_source *resolve_retry_event_source;
Set *routes;
uint32_t route_table;
uint32_t route_priority;
};
DEFINE_NETDEV_CAST(WIREGUARD, Wireguard);
@ -68,3 +77,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key_file);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_preshared_key_file);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_keepalive);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_route_table);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_peer_route_table);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_route_priority);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_peer_route_priority);

View File

@ -19,6 +19,7 @@
#include "string-util.h"
#include "strv.h"
#include "vrf.h"
#include "wireguard.h"
int route_new(Route **ret) {
_cleanup_(route_freep) Route *route = NULL;
@ -242,7 +243,7 @@ int route_compare_func(const Route *a, const Route *b) {
}
}
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
route_hash_ops,
Route,
route_hash_func,
@ -673,7 +674,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
return log_link_error_errno(link, r, "Could not set route table: %m");
/* Table attribute to allow more than 256. */
r = sd_netlink_message_append_data(req, RTA_TABLE, &route->table, sizeof(route->table));
r = sd_netlink_message_append_u32(req, RTA_TABLE, route->table);
if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_TABLE attribute: %m");
}
@ -865,6 +866,28 @@ static bool route_by_kernel(const Route *route) {
return false;
}
static void link_unmark_wireguard_routes(Link *link) {
Route *route, *existing;
NetDev *netdev;
Wireguard *w;
assert(link);
if (!streq_ptr(link->kind, "wireguard"))
return;
if (netdev_get(link->manager, link->ifname, &netdev) < 0)
return;
w = WIREGUARD(netdev);
if (!w)
return;
SET_FOREACH(route, w->routes)
if (route_get(NULL, link, route, &existing) >= 0)
route_unmark(existing);
}
int link_drop_foreign_routes(Link *link) {
Route *route;
int k, r;
@ -914,6 +937,8 @@ int link_drop_foreign_routes(Link *link) {
route_unmark(existing);
}
link_unmark_wireguard_routes(link);
r = 0;
SET_FOREACH(route, link->routes) {
if (!route_is_marked(route))
@ -1342,6 +1367,36 @@ static int link_request_static_route(Link *link, Route *route) {
&link->static_route_messages, static_route_handler, NULL);
}
static int link_request_wireguard_routes(Link *link, bool only_ipv4) {
NetDev *netdev;
Wireguard *w;
Route *route;
int r;
assert(link);
if (!streq_ptr(link->kind, "wireguard"))
return 0;
if (netdev_get(link->manager, link->ifname, &netdev) < 0)
return 0;
w = WIREGUARD(netdev);
if (!w)
return 0;
SET_FOREACH(route, w->routes) {
if (only_ipv4 && route->family != AF_INET)
continue;
r = link_request_static_route(link, route);
if (r < 0)
return r;
}
return 0;
}
int link_request_static_routes(Link *link, bool only_ipv4) {
Route *route;
int r;
@ -1363,6 +1418,10 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
return r;
}
r = link_request_wireguard_routes(link, only_ipv4);
if (r < 0)
return r;
if (link->static_route_messages == 0) {
link->static_routes_configured = true;
link_check_ready(link);
@ -1723,12 +1782,16 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma
return 0;
}
r = sd_rtnl_message_route_get_table(message, &table);
r = sd_netlink_message_read_u32(message, RTA_TABLE, &tmp->table);
if (r == -ENODATA) {
r = sd_rtnl_message_route_get_table(message, &table);
if (r >= 0)
tmp->table = table;
}
if (r < 0) {
log_link_warning_errno(link, r, "rtnl: received route message with invalid table, ignoring: %m");
return 0;
}
tmp->table = table;
r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &tmp->priority);
if (r < 0 && r != -ENODATA) {

View File

@ -70,6 +70,7 @@ typedef struct Route {
void route_hash_func(const Route *route, struct siphash *state);
int route_compare_func(const Route *a, const Route *b);
extern const struct hash_ops route_hash_ops;
int route_new(Route **ret);
Route *route_free(Route *route);

View File

@ -4211,14 +4211,15 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
}
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (IN_SET(n, -EAGAIN, -EINTR))
return 0;
if (n == -EXFULL) {
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
return 0;
}
if (n < 0)
if (n < 0) {
if (ERRNO_IS_TRANSIENT(n))
return 0;
if (n == -EXFULL) {
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
return 0;
}
return log_warning_errno(n, "Couldn't read notification socket: %m");
}
cmsg_close_all(&msghdr);

View File

@ -108,10 +108,7 @@ static int process_managed_oom_message(Manager *m, uid_t uid, JsonVariant *param
if (streq(message.property, "ManagedOOMMemoryPressure") && message.limit > 0) {
int permyriad = UINT32_SCALE_TO_PERMYRIAD(message.limit);
r = store_loadavg_fixed_point(
(unsigned long) permyriad / 100,
(unsigned long) permyriad % 100,
&limit);
r = store_loadavg_fixed_point(permyriad / 100LU, permyriad % 100LU, &limit);
if (r < 0)
continue;
}

View File

@ -323,7 +323,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
ssize_t ss = dns_stream_writev(s, iov, ELEMENTSOF(iov), 0);
if (ss < 0) {
if (!IN_SET(-ss, EINTR, EAGAIN))
if (!ERRNO_IS_TRANSIENT(ss))
return dns_stream_complete(s, -ss);
} else {
progressed = true;
@ -347,7 +347,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
ss = dns_stream_read(s, (uint8_t*) &s->read_size + s->n_read, sizeof(s->read_size) - s->n_read);
if (ss < 0) {
if (!IN_SET(-ss, EINTR, EAGAIN))
if (!ERRNO_IS_TRANSIENT(ss))
return dns_stream_complete(s, -ss);
} else if (ss == 0)
return dns_stream_complete(s, ECONNRESET);
@ -400,7 +400,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
(uint8_t*) DNS_PACKET_DATA(s->read_packet) + s->n_read - sizeof(s->read_size),
sizeof(s->read_size) + be16toh(s->read_size) - s->n_read);
if (ss < 0) {
if (!IN_SET(-ss, EINTR, EAGAIN))
if (!ERRNO_IS_TRANSIENT(ss))
return dns_stream_complete(s, -ss);
} else if (ss == 0)
return dns_stream_complete(s, ECONNRESET);

View File

@ -792,10 +792,13 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
iov = IOVEC_MAKE(DNS_PACKET_DATA(p), p->allocated);
l = recvmsg_safe(fd, &mh, 0);
if (IN_SET(l, -EAGAIN, -EINTR))
return 0;
if (l <= 0)
if (l < 0) {
if (ERRNO_IS_TRANSIENT(l))
return 0;
return l;
}
if (l == 0)
return 0;
assert(!(mh.msg_flags & MSG_TRUNC));

View File

@ -153,15 +153,16 @@ static int ask_password_keyring(const char *keyname, AskPasswordFlags flags, cha
return -EUNATCH;
r = lookup_key(keyname, &serial);
if (ERRNO_IS_NOT_SUPPORTED(r) || r == -EPERM) /* when retrieving the distinction between "kernel or
* container manager don't support or allow this" and
* "no matching key known" doesn't matter. Note that we
* propagate EACCESS here (even if EPERM not) since
* that is used if the keyring is available but we lack
* access to the key. */
return -ENOKEY;
if (r < 0)
if (r < 0) {
/* when retrieving the distinction between "kernel or container manager don't support
* or allow this" and "no matching key known" doesn't matter. Note that we propagate
* EACCESS here (even if EPERM not) since that is used if the keyring is available but
* we lack access to the key. */
if (ERRNO_IS_NOT_SUPPORTED(r) || r == -EPERM)
return -ENOKEY;
return r;
}
return retrieve_key(serial, ret);
}
@ -290,12 +291,13 @@ int ask_password_plymouth(
k = read(fd, buffer + p, sizeof(buffer) - p);
if (k < 0) {
if (IN_SET(errno, EINTR, EAGAIN))
if (ERRNO_IS_TRANSIENT(errno))
continue;
r = -errno;
goto finish;
} else if (k == 0) {
}
if (k == 0) {
r = -EIO;
goto finish;
}
@ -521,7 +523,7 @@ int ask_password_tty(
n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1);
if (n < 0) {
if (IN_SET(errno, EINTR, EAGAIN))
if (ERRNO_IS_TRANSIENT(errno))
continue;
r = -errno;
@ -881,20 +883,21 @@ int ask_password_agent(
};
n = recvmsg_safe(socket_fd, &msghdr, 0);
if (IN_SET(n, -EAGAIN, -EINTR))
continue;
if (n == -EXFULL) {
log_debug("Got message with truncated control data, ignoring.");
continue;
}
if (n < 0) {
if (ERRNO_IS_TRANSIENT(n))
continue;
if (n == -EXFULL) {
log_debug("Got message with truncated control data, ignoring.");
continue;
}
r = (int) n;
goto finish;
}
cmsg_close_all(&msghdr);
if (n <= 0) {
if (n == 0) {
log_debug("Message too short");
continue;
}

View File

@ -10,6 +10,7 @@
#include <unistd.h>
#include "barrier.h"
#include "errno-util.h"
#include "fd-util.h"
#include "io-util.h"
#include "macro.h"
@ -178,7 +179,7 @@ static bool barrier_write(Barrier *b, uint64_t buf) {
assert(b->me >= 0);
do {
len = write(b->me, &buf, sizeof(buf));
} while (len < 0 && IN_SET(errno, EAGAIN, EINTR));
} while (len < 0 && ERRNO_IS_TRANSIENT(errno));
if (len != sizeof(buf))
goto error;
@ -230,7 +231,7 @@ static bool barrier_read(Barrier *b, int64_t comp) {
/* events on @them signal new data for us */
len = read(b->them, &buf, sizeof(buf));
if (len < 0 && IN_SET(errno, EAGAIN, EINTR))
if (len < 0 && ERRNO_IS_TRANSIENT(errno))
continue;
if (len != sizeof(buf))

View File

@ -28,16 +28,7 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(ARM, "arm"),
_GPT_ARCH_SEXTET(ARM64, "arm64"),
_GPT_ARCH_SEXTET(IA64, "ia64"),
// TODO: Replace with `_GPT_ARCH_SEXTET(LOONGARCH64, "loongarch64")` once
// https://github.com/systemd/systemd/pull/21288 is merged. */
{ GPT_ROOT_LOONGARCH64, "root-loongarch64", _ARCHITECTURE_INVALID, .is_root = true },
{ GPT_ROOT_LOONGARCH64_VERITY, "root-loongarch64-verity", _ARCHITECTURE_INVALID, .is_root_verity = true },
{ GPT_ROOT_LOONGARCH64_VERITY_SIG, "root-loongarch64-verity-sig", _ARCHITECTURE_INVALID, .is_root_verity_sig = true },
{ GPT_USR_LOONGARCH64, "usr-loongarch64", _ARCHITECTURE_INVALID, .is_usr = true },
{ GPT_USR_LOONGARCH64_VERITY, "usr-loongarch64-verity", _ARCHITECTURE_INVALID, .is_usr_verity = true },
{ GPT_USR_LOONGARCH64_VERITY_SIG, "usr-loongarch64-verity-sig", _ARCHITECTURE_INVALID, .is_usr_verity_sig = true },
_GPT_ARCH_SEXTET(LOONGARCH64, "loongarch64"),
_GPT_ARCH_SEXTET(MIPS_LE, "mips-le"),
_GPT_ARCH_SEXTET(MIPS64_LE, "mips64-le"),
_GPT_ARCH_SEXTET(PPC, "ppc"),

View File

@ -129,7 +129,9 @@ static int rm_rf_children_inner(
assert(fd >= 0);
assert(fname);
if (is_dir < 0 || (is_dir > 0 && (root_dev || (flags & REMOVE_SUBVOLUME)))) {
if (is_dir < 0 ||
root_dev ||
(is_dir > 0 && (root_dev || (flags & REMOVE_SUBVOLUME)))) {
r = fstatat_harder(fd, fname, &st, AT_SYMLINK_NOFOLLOW, flags);
if (r < 0)

View File

@ -39,53 +39,84 @@ bool can_memlock(void);
if (sd_booted() > 0) { \
x; \
} else { \
printf("systemd not booted skipping '%s'\n", #x); \
printf("systemd not booted, skipping '%s'\n", #x); \
}
/* Provide a convenient way to check if we're running in CI. */
const char *ci_environment(void);
typedef struct TestFunc {
void (*f)(void);
const char * const n;
union f {
void (*void_func)(void);
int (*int_func)(void);
} f;
const char * const name;
bool has_ret:1;
bool sd_booted:1;
} TestFunc;
/* See static-destruct.h for an explanation of how this works. */
#define REGISTER_TEST(func) \
static void func(void); \
_section_("SYSTEMD_TEST_TABLE") _alignptr_ _used_ _variable_no_sanitize_address_ \
static const TestFunc UNIQ_T(static_test_table_entry, UNIQ) = { \
.f = &(func), \
.n = STRINGIFY(func), \
#define REGISTER_TEST(func, ...) \
_section_("SYSTEMD_TEST_TABLE") _alignptr_ _used_ _variable_no_sanitize_address_ \
static const TestFunc UNIQ_T(static_test_table_entry, UNIQ) = { \
.f = (union f) &(func), \
.name = STRINGIFY(func), \
.has_ret = __builtin_types_compatible_p(typeof((union f){}.int_func), typeof(&(func))), \
##__VA_ARGS__ \
}
extern const TestFunc _weak_ __start_SYSTEMD_TEST_TABLE[];
extern const TestFunc _weak_ __stop_SYSTEMD_TEST_TABLE[];
#define TEST(name) \
REGISTER_TEST(test_##name); \
#define TEST(name, ...) \
static void test_##name(void); \
REGISTER_TEST(test_##name, ##__VA_ARGS__); \
static void test_##name(void)
static inline void run_test_table(void) {
#define TEST_RET(name, ...) \
static int test_##name(void); \
REGISTER_TEST(test_##name, ##__VA_ARGS__); \
static int test_##name(void)
static inline int run_test_table(void) {
int r = EXIT_SUCCESS;
if (!__start_SYSTEMD_TEST_TABLE)
return;
return r;
const TestFunc *t = ALIGN_TO_PTR(__start_SYSTEMD_TEST_TABLE, sizeof(TestFunc*));
while (t < __stop_SYSTEMD_TEST_TABLE) {
log_info("/* %s */", t->n);
t->f();
if (t->sd_booted && sd_booted() <= 0) {
log_info("/* systemd not booted, skipping %s */", t->name);
if (t->has_ret && r == EXIT_SUCCESS)
r = EXIT_TEST_SKIP;
} else {
log_info("/* %s */", t->name);
if (t->has_ret) {
int r2 = t->f.int_func();
if (r == EXIT_SUCCESS)
r = r2;
} else
t->f.void_func();
}
t = ALIGN_TO_PTR(t + 1, sizeof(TestFunc*));
}
return r;
}
#define DEFINE_CUSTOM_TEST_MAIN(log_level, intro, outro) \
int main(int argc, char *argv[]) { \
int _r = EXIT_SUCCESS; \
test_setup_logging(log_level); \
save_argc_argv(argc, argv); \
intro; \
run_test_table(); \
_r = run_test_table(); \
outro; \
return EXIT_SUCCESS; \
return _r; \
}
#define DEFINE_TEST_MAIN(log_level) DEFINE_CUSTOM_TEST_MAIN(log_level, , )

View File

@ -190,7 +190,7 @@ static int connection_shovel(
} else if (z == 0 || ERRNO_IS_DISCONNECT(errno)) {
*from_source = sd_event_source_unref(*from_source);
*from = safe_close(*from);
} else if (!IN_SET(errno, EAGAIN, EINTR))
} else if (!ERRNO_IS_TRANSIENT(errno))
return log_error_errno(errno, "Failed to splice: %m");
}
@ -202,7 +202,7 @@ static int connection_shovel(
} else if (z == 0 || ERRNO_IS_DISCONNECT(errno)) {
*to_source = sd_event_source_unref(*to_source);
*to = safe_close(*to);
} else if (!IN_SET(errno, EAGAIN, EINTR))
} else if (!ERRNO_IS_TRANSIENT(errno))
return log_error_errno(errno, "Failed to splice: %m");
}
} while (shoveled);

View File

@ -14,15 +14,13 @@
#include "tmpfile-util.h"
#include "user-util.h"
static int test_add_acls_for_user(void) {
TEST_RET(add_acls_for_user) {
char fn[] = "/tmp/test-empty.XXXXXX";
_cleanup_close_ int fd = -1;
char *cmd;
uid_t uid;
int r;
log_info("/* %s */", __func__);
fd = mkostemp_safe(fn);
assert_se(fd >= 0);
@ -71,6 +69,4 @@ static int test_add_acls_for_user(void) {
return 0;
}
int main(int argc, char **argv) {
return test_add_acls_for_user();
}
DEFINE_TEST_MAIN(LOG_INFO);

View File

@ -40,7 +40,7 @@ static void sleep_for(usec_t usecs) {
}
#define TEST_BARRIER(_FUNCTION, _CHILD_CODE, _WAIT_CHILD, _PARENT_CODE, _WAIT_PARENT) \
static void _FUNCTION(void) { \
TEST(_FUNCTION) { \
Barrier b = BARRIER_NULL; \
pid_t pid1, pid2; \
\
@ -100,7 +100,7 @@ static void sleep_for(usec_t usecs) {
* pending HUP on the pipe. However, the barrier_sync() prefers reads on the
* eventfd, thus we can safely wait on the barrier.
*/
TEST_BARRIER(test_barrier_sync,
TEST_BARRIER(barrier_sync,
({
set_alarm(BASE_TIME * 10);
assert_se(barrier_place(&b));
@ -122,7 +122,7 @@ TEST_BARRIER(test_barrier_sync,
* succeed as the child hasn't read the parent's barrier, yet. The following
* barrier and sync synchronize the exit.
*/
TEST_BARRIER(test_barrier_wait_next,
TEST_BARRIER(barrier_wait_next,
({
sleep_for(BASE_TIME);
set_alarm(BASE_TIME * 10);
@ -148,7 +148,7 @@ TEST_BARRIER(test_barrier_wait_next,
* not look at barrier-links so this stall is expected. Thus this test times
* out.
*/
TEST_BARRIER(test_barrier_wait_next_twice,
TEST_BARRIER(barrier_wait_next_twice,
({
sleep_for(BASE_TIME);
set_alarm(BASE_TIME);
@ -171,7 +171,7 @@ TEST_BARRIER(test_barrier_wait_next_twice,
* between both waits. This does not have any effect on the wait so it times out
* like the other test.
*/
TEST_BARRIER(test_barrier_wait_next_twice_local,
TEST_BARRIER(barrier_wait_next_twice_local,
({
sleep_for(BASE_TIME);
set_alarm(BASE_TIME);
@ -196,7 +196,7 @@ TEST_BARRIER(test_barrier_wait_next_twice_local,
* synced wait as the second wait. This works just fine because the local state
* has no barriers placed, therefore, the remote is always in sync.
*/
TEST_BARRIER(test_barrier_wait_next_twice_sync,
TEST_BARRIER(barrier_wait_next_twice_sync,
({
sleep_for(BASE_TIME);
set_alarm(BASE_TIME);
@ -217,7 +217,7 @@ TEST_BARRIER(test_barrier_wait_next_twice_sync,
* synced wait as the second wait. This works just fine because the local state
* is in sync with the remote.
*/
TEST_BARRIER(test_barrier_wait_next_twice_local_sync,
TEST_BARRIER(barrier_wait_next_twice_local_sync,
({
sleep_for(BASE_TIME);
set_alarm(BASE_TIME);
@ -239,7 +239,7 @@ TEST_BARRIER(test_barrier_wait_next_twice_local_sync,
* This tests sync_*() synchronizations and makes sure they work fine if the
* local state is behind the remote state.
*/
TEST_BARRIER(test_barrier_sync_next,
TEST_BARRIER(barrier_sync_next,
({
set_alarm(BASE_TIME * 10);
assert_se(barrier_sync_next(&b));
@ -265,7 +265,7 @@ TEST_BARRIER(test_barrier_sync_next,
* This tests timeouts if sync_*() is used if local barriers are placed but the
* remote didn't place any.
*/
TEST_BARRIER(test_barrier_sync_next_local,
TEST_BARRIER(barrier_sync_next_local,
({
set_alarm(BASE_TIME);
assert_se(barrier_place(&b));
@ -283,7 +283,7 @@ TEST_BARRIER(test_barrier_sync_next_local,
* This is the same as test_barrier_sync_next_local but aborts the sync in the
* parent. Therefore, the sync_next() succeeds just fine due to the abortion.
*/
TEST_BARRIER(test_barrier_sync_next_local_abort,
TEST_BARRIER(barrier_sync_next_local_abort,
({
set_alarm(BASE_TIME * 10);
assert_se(barrier_place(&b));
@ -299,7 +299,7 @@ TEST_BARRIER(test_barrier_sync_next_local_abort,
* Test matched wait_abortion()
* This runs wait_abortion() with remote abortion.
*/
TEST_BARRIER(test_barrier_wait_abortion,
TEST_BARRIER(barrier_wait_abortion,
({
set_alarm(BASE_TIME * 10);
assert_se(barrier_wait_abortion(&b));
@ -315,7 +315,7 @@ TEST_BARRIER(test_barrier_wait_abortion,
* This runs wait_abortion() without any remote abortion going on. It thus must
* timeout.
*/
TEST_BARRIER(test_barrier_wait_abortion_unmatched,
TEST_BARRIER(barrier_wait_abortion_unmatched,
({
set_alarm(BASE_TIME);
assert_se(barrier_wait_abortion(&b));
@ -331,7 +331,7 @@ TEST_BARRIER(test_barrier_wait_abortion_unmatched,
* Test matched wait_abortion() with local abortion
* This runs wait_abortion() with local and remote abortion.
*/
TEST_BARRIER(test_barrier_wait_abortion_local,
TEST_BARRIER(barrier_wait_abortion_local,
({
set_alarm(BASE_TIME * 10);
assert_se(barrier_abort(&b));
@ -347,7 +347,7 @@ TEST_BARRIER(test_barrier_wait_abortion_local,
* Test unmatched wait_abortion() with local abortion
* This runs wait_abortion() with only local abortion. This must time out.
*/
TEST_BARRIER(test_barrier_wait_abortion_local_unmatched,
TEST_BARRIER(barrier_wait_abortion_local_unmatched,
({
set_alarm(BASE_TIME);
assert_se(barrier_abort(&b));
@ -365,7 +365,7 @@ TEST_BARRIER(test_barrier_wait_abortion_local_unmatched,
* Place barrier and sync with the child. The child only exits()s, which should
* cause an implicit abortion and wake the parent.
*/
TEST_BARRIER(test_barrier_exit,
TEST_BARRIER(barrier_exit,
({
}),
TEST_BARRIER_WAIT_SUCCESS(pid1),
@ -382,7 +382,7 @@ TEST_BARRIER(test_barrier_exit,
* child-exit. We add a usleep() which triggers the alarm in the parent and
* causes the test to time out.
*/
TEST_BARRIER(test_barrier_no_exit,
TEST_BARRIER(barrier_no_exit,
({
sleep_for(BASE_TIME * 2);
}),
@ -404,7 +404,7 @@ TEST_BARRIER(test_barrier_no_exit,
* succeeds. Only if we place one more barrier, we're ahead of the remote, thus
* we will fail due to HUP on the pipe.
*/
TEST_BARRIER(test_barrier_pending_exit,
TEST_BARRIER(barrier_pending_exit,
({
set_alarm(BASE_TIME * 4);
sleep_for(BASE_TIME * 2);
@ -421,44 +421,25 @@ TEST_BARRIER(test_barrier_pending_exit,
}),
TEST_BARRIER_WAIT_SUCCESS(pid2));
int main(int argc, char *argv[]) {
int v;
test_setup_logging(LOG_INFO);
DEFINE_CUSTOM_TEST_MAIN(
LOG_INFO,
({
if (!slow_tests_enabled())
return log_tests_skipped("slow tests are disabled");
if (!slow_tests_enabled())
return log_tests_skipped("slow tests are disabled");
/*
* This test uses real-time alarms and sleeps to test for CPU races
* explicitly. This is highly fragile if your system is under load. We
* already increased the BASE_TIME value to make the tests more robust,
* but that just makes the test take significantly longer. Given the recent
* issues when running the test in a virtualized environments, limit it
* to bare metal machines only, to minimize false-positives in CIs.
*/
int v = detect_virtualization();
if (IN_SET(v, -EPERM, -EACCES))
return log_tests_skipped("Cannot detect virtualization");
/*
* This test uses real-time alarms and sleeps to test for CPU races
* explicitly. This is highly fragile if your system is under load. We
* already increased the BASE_TIME value to make the tests more robust,
* but that just makes the test take significantly longer. Given the recent
* issues when running the test in a virtualized environments, limit it
* to bare metal machines only, to minimize false-positives in CIs.
*/
v = detect_virtualization();
if (IN_SET(v, -EPERM, -EACCES))
return log_tests_skipped("Cannot detect virtualization");
if (v != VIRTUALIZATION_NONE)
return log_tests_skipped("This test requires a baremetal machine");
test_barrier_sync();
test_barrier_wait_next();
test_barrier_wait_next_twice();
test_barrier_wait_next_twice_sync();
test_barrier_wait_next_twice_local();
test_barrier_wait_next_twice_local_sync();
test_barrier_sync_next();
test_barrier_sync_next_local();
test_barrier_sync_next_local_abort();
test_barrier_wait_abortion();
test_barrier_wait_abortion_unmatched();
test_barrier_wait_abortion_local();
test_barrier_wait_abortion_local_unmatched();
test_barrier_exit();
test_barrier_no_exit();
test_barrier_pending_exit();
return 0;
}
if (v != VIRTUALIZATION_NONE)
return log_tests_skipped("This test requires a baremetal machine");
}),
/* no outro */);

View File

@ -26,7 +26,7 @@ static void log_cgroup_mask(CGroupMask got, CGroupMask expected) {
log_info("Got mask: %s\n", g_store);
}
static int test_cgroup_mask(void) {
TEST_RET(cgroup_mask, .sd_booted = true) {
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
Unit *son, *daughter, *parent, *root, *grandchild, *parent_deep, *nomem_parent, *nomem_leaf;
@ -138,7 +138,7 @@ static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
assert_se(streq_ptr(b, t));
}
static void test_cg_mask_to_string(void) {
TEST(cg_mask_to_string) {
test_cg_mask_to_string_one(0, NULL);
test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices bpf-foreign bpf-socket-bind bpf-restrict-network-interfaces");
test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
@ -156,13 +156,4 @@ static void test_cg_mask_to_string(void) {
test_cg_mask_to_string_one(CGROUP_MASK_IO|CGROUP_MASK_BLKIO, "io blkio");
}
int main(int argc, char* argv[]) {
int rc = EXIT_SUCCESS;
test_setup_logging(LOG_DEBUG);
test_cg_mask_to_string();
TEST_REQ_RUNNING_SYSTEMD(rc = test_cgroup_mask());
return rc;
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -8,7 +8,7 @@
#include "tests.h"
#include "unit.h"
static int test_default_memory_low(void) {
TEST_RET(default_memory_low, .sd_booted = true) {
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
Unit *root, *dml,
@ -135,12 +135,4 @@ static int test_default_memory_low(void) {
return 0;
}
int main(int argc, char* argv[]) {
int rc = EXIT_SUCCESS;
test_setup_logging(LOG_DEBUG);
TEST_REQ_RUNNING_SYSTEMD(rc = test_default_memory_low());
return rc;
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -28,7 +28,7 @@ static void check_p_d_u(const char *path, int code, const char *result) {
assert_se(streq_ptr(unit, result));
}
static void test_path_decode_unit(void) {
TEST(path_decode_unit) {
check_p_d_u("getty@tty2.service", 0, "getty@tty2.service");
check_p_d_u("getty@tty2.service/", 0, "getty@tty2.service");
check_p_d_u("getty@tty2.service/xxx", 0, "getty@tty2.service");
@ -50,7 +50,7 @@ static void check_p_g_u(const char *path, int code, const char *result) {
assert_se(streq_ptr(unit, result));
}
static void test_path_get_unit(void) {
TEST(path_get_unit) {
check_p_g_u("/system.slice/foobar.service/sdfdsaf", 0, "foobar.service");
check_p_g_u("/system.slice/getty@tty5.service", 0, "getty@tty5.service");
check_p_g_u("/system.slice/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service");
@ -74,7 +74,7 @@ static void check_p_g_u_u(const char *path, int code, const char *result) {
assert_se(streq_ptr(unit, result));
}
static void test_path_get_user_unit(void) {
TEST(path_get_user_unit) {
check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "foobar.service");
check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo.slice/foobar.service", 0, "foobar.service");
check_p_g_u_u("/user.slice/user-1002.slice/session-2.scope/foobar.service/waldo", 0, "foobar.service");
@ -97,7 +97,7 @@ static void check_p_g_s(const char *path, int code, const char *result) {
assert_se(streq_ptr(s, result));
}
static void test_path_get_session(void) {
TEST(path_get_session) {
check_p_g_s("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "2");
check_p_g_s("/session-3.scope", 0, "3");
check_p_g_s("/session-.scope", -ENXIO, NULL);
@ -111,7 +111,7 @@ static void check_p_g_o_u(const char *path, int code, uid_t result) {
assert_se(uid == result);
}
static void test_path_get_owner_uid(void) {
TEST(path_get_owner_uid) {
check_p_g_o_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, 1000);
check_p_g_o_u("/user.slice/user-1006.slice", 0, 1006);
check_p_g_o_u("", -ENXIO, 0);
@ -124,7 +124,7 @@ static void check_p_g_slice(const char *path, int code, const char *result) {
assert_se(streq_ptr(s, result));
}
static void test_path_get_slice(void) {
TEST(path_get_slice) {
check_p_g_slice("/user.slice", 0, "user.slice");
check_p_g_slice("/foobar", 0, SPECIAL_ROOT_SLICE);
check_p_g_slice("/user.slice/user-waldo.slice", 0, "user-waldo.slice");
@ -141,7 +141,7 @@ static void check_p_g_u_slice(const char *path, int code, const char *result) {
assert_se(streq_ptr(s, result));
}
static void test_path_get_user_slice(void) {
TEST(path_get_user_slice) {
check_p_g_u_slice("/user.slice", -ENXIO, NULL);
check_p_g_u_slice("/foobar", -ENXIO, NULL);
check_p_g_u_slice("/user.slice/user-waldo.slice", -ENXIO, NULL);
@ -158,14 +158,14 @@ static void test_path_get_user_slice(void) {
check_p_g_u_slice("/foo.slice//foo-bar.slice/user@1000.service/piep.slice//piep-pap.slice//foo.service", 0, "piep-pap.slice");
}
static void test_get_paths(void) {
TEST(get_paths, .sd_booted = true) {
_cleanup_free_ char *a = NULL;
assert_se(cg_get_root_path(&a) >= 0);
log_info("Root = %s", a);
}
static void test_proc(void) {
TEST(proc) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
int r;
@ -220,7 +220,7 @@ static void test_escape_one(const char *s, const char *r) {
assert_se(streq(cg_unescape(b), s));
}
static void test_escape(void) {
TEST(escape, .sd_booted = true) {
test_escape_one("foobar", "foobar");
test_escape_one(".foobar", "_.foobar");
test_escape_one("foobar.service", "foobar.service");
@ -234,7 +234,7 @@ static void test_escape(void) {
test_escape_one(".", "_.");
}
static void test_controller_is_valid(void) {
TEST(controller_is_valid) {
assert_se(cg_controller_is_valid("foobar"));
assert_se(cg_controller_is_valid("foo_bar"));
assert_se(cg_controller_is_valid("name=foo"));
@ -260,7 +260,7 @@ static void test_slice_to_path_one(const char *unit, const char *path, int error
assert_se(streq_ptr(ret, path));
}
static void test_slice_to_path(void) {
TEST(slice_to_path) {
test_slice_to_path_one("foobar.slice", "foobar.slice", 0);
test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0);
test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL);
@ -292,16 +292,14 @@ static void test_shift_path_one(const char *raw, const char *root, const char *s
assert_se(streq(s, shifted));
}
static void test_shift_path(void) {
TEST(shift_path) {
test_shift_path_one("/foobar/waldo", "/", "/foobar/waldo");
test_shift_path_one("/foobar/waldo", "", "/foobar/waldo");
test_shift_path_one("/foobar/waldo", "/foobar", "/waldo");
test_shift_path_one("/foobar/waldo", "/hogehoge", "/foobar/waldo");
}
static void test_mask_supported(void) {
TEST(mask_supported, .sd_booted = true) {
CGroupMask m;
CGroupController c;
@ -311,7 +309,7 @@ static void test_mask_supported(void) {
printf("'%s' is supported: %s\n", cgroup_controller_to_string(c), yes_no(m & CGROUP_CONTROLLER_TO_MASK(c)));
}
static void test_is_cgroup_fs(void) {
TEST(is_cgroup_fs, .sd_booted = true) {
struct statfs sfs;
assert_se(statfs("/sys/fs/cgroup", &sfs) == 0);
if (is_temporary_fs(&sfs))
@ -319,7 +317,7 @@ static void test_is_cgroup_fs(void) {
assert_se(is_cgroup_fs(&sfs));
}
static void test_fd_is_cgroup_fs(void) {
TEST(fd_is_cgroup_fs, .sd_booted = true) {
int fd;
fd = open("/sys/fs/cgroup", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
@ -333,7 +331,7 @@ static void test_fd_is_cgroup_fs(void) {
fd = safe_close(fd);
}
static void test_cg_tests(void) {
TEST(cg_tests) {
int all, hybrid, systemd, r;
r = cg_unified();
@ -364,7 +362,7 @@ static void test_cg_tests(void) {
assert_se(!systemd);
}
static void test_cg_get_keyed_attribute(void) {
TEST(cg_get_keyed_attribute) {
_cleanup_free_ char *val = NULL;
char *vals3[3] = {}, *vals3a[3] = {};
int i, r;
@ -429,27 +427,4 @@ static void test_cg_get_keyed_attribute(void) {
}
}
int main(void) {
test_setup_logging(LOG_DEBUG);
test_path_decode_unit();
test_path_get_unit();
test_path_get_user_unit();
test_path_get_session();
test_path_get_owner_uid();
test_path_get_slice();
test_path_get_user_slice();
TEST_REQ_RUNNING_SYSTEMD(test_get_paths());
test_proc();
TEST_REQ_RUNNING_SYSTEMD(test_escape());
test_controller_is_valid();
test_slice_to_path();
test_shift_path();
TEST_REQ_RUNNING_SYSTEMD(test_mask_supported());
TEST_REQ_RUNNING_SYSTEMD(test_is_cgroup_fs());
TEST_REQ_RUNNING_SYSTEMD(test_fd_is_cgroup_fs());
test_cg_tests();
test_cg_get_keyed_attribute();
return 0;
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -30,7 +30,7 @@
/* Nontrivial value serves as a placeholder to check that parsing function (didn't) change it */
#define CGROUP_LIMIT_DUMMY 3
static int test_unit_file_get_set(void) {
TEST_RET(unit_file_get_set) {
int r;
Hashmap *h;
UnitFileList *p;
@ -78,7 +78,7 @@ static void check_execcommand(ExecCommand *c,
assert_se(!!(c->flags & EXEC_COMMAND_IGNORE_FAILURE) == ignore);
}
static void test_config_parse_exec(void) {
TEST(config_parse_exec) {
/* int config_parse_exec(
const char *unit,
const char *filename,
@ -422,7 +422,7 @@ static void test_config_parse_exec(void) {
exec_command_free_list(c);
}
static void test_config_parse_log_extra_fields(void) {
TEST(config_parse_log_extra_fields) {
/* int config_parse_log_extra_fields(
const char *unit,
const char *filename,
@ -486,7 +486,7 @@ static void test_config_parse_log_extra_fields(void) {
log_info("/* %s bye */", __func__);
}
static void test_install_printf(void) {
TEST(install_printf, .sd_booted = true) {
char name[] = "name.service",
path[] = "/run/systemd/system/name.service";
UnitFileInstallInfo i = { .name = name, .path = path, };
@ -565,7 +565,7 @@ static uint64_t make_cap(int cap) {
return ((uint64_t) 1ULL << (uint64_t) cap);
}
static void test_config_parse_capability_set(void) {
TEST(config_parse_capability_set) {
/* int config_parse_capability_set(
const char *unit,
const char *filename,
@ -618,7 +618,7 @@ static void test_config_parse_capability_set(void) {
assert_se(capability_bounding_set == (make_cap(CAP_NET_RAW) | make_cap(CAP_NET_ADMIN)));
}
static void test_config_parse_rlimit(void) {
TEST(config_parse_rlimit) {
struct rlimit * rl[_RLIMIT_MAX] = {};
assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0);
@ -732,7 +732,7 @@ static void test_config_parse_rlimit(void) {
rl[RLIMIT_RTTIME] = mfree(rl[RLIMIT_RTTIME]);
}
static void test_config_parse_pass_environ(void) {
TEST(config_parse_pass_environ) {
/* int config_parse_pass_environ(
const char *unit,
const char *filename,
@ -769,11 +769,11 @@ static void test_config_parse_pass_environ(void) {
assert_se(streq(passenv[0], "normal_name"));
}
static void test_unit_dump_config_items(void) {
TEST(unit_dump_config_items) {
unit_dump_config_items(stdout);
}
static void test_config_parse_memory_limit(void) {
TEST(config_parse_memory_limit) {
/* int config_parse_memory_limit(
const char *unit,
const char *filename,
@ -829,7 +829,7 @@ static void test_config_parse_memory_limit(void) {
}
static void test_contains_instance_specifier_superset(void) {
TEST(contains_instance_specifier_superset) {
assert_se(contains_instance_specifier_superset("foobar@a%i"));
assert_se(contains_instance_specifier_superset("foobar@%ia"));
assert_se(contains_instance_specifier_superset("foobar@%n"));
@ -851,7 +851,7 @@ static void test_contains_instance_specifier_superset(void) {
assert_se(!contains_instance_specifier_superset("@%a%b"));
}
static void test_unit_is_recursive_template_dependency(void) {
TEST(unit_is_recursive_template_dependency) {
_cleanup_(manager_freep) Manager *m = NULL;
Unit *u;
int r;
@ -894,29 +894,15 @@ static void test_unit_is_recursive_template_dependency(void) {
assert_se(unit_is_likely_recursive_template_dependency(u, "foobar@foobar@123.mount", "foobar@%n.mount") == 0);
}
int main(int argc, char *argv[]) {
DEFINE_CUSTOM_TEST_MAIN(
LOG_INFO,
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int r;
({
if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
test_setup_logging(LOG_INFO);
assert_se(runtime_dir = setup_fake_runtime_dir());
}),
r = enter_cgroup_subroot(NULL);
if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
assert_se(runtime_dir = setup_fake_runtime_dir());
r = test_unit_file_get_set();
test_config_parse_exec();
test_config_parse_log_extra_fields();
test_config_parse_capability_set();
test_config_parse_rlimit();
test_config_parse_pass_environ();
TEST_REQ_RUNNING_SYSTEMD(test_install_printf());
test_unit_dump_config_items();
test_config_parse_memory_limit();
test_contains_instance_specifier_superset();
test_unit_is_recursive_template_dependency();
return r;
}
/* no outro */);

View File

@ -14,7 +14,7 @@
#include "util.h"
#include "virt.h"
static void test_namespace_cleanup_tmpdir(void) {
TEST(namespace_cleanup_tmpdir) {
{
_cleanup_(namespace_cleanup_tmpdirp) char *dir;
assert_se(dir = strdup(RUN_SYSTEMD_EMPTY));
@ -27,7 +27,7 @@ static void test_namespace_cleanup_tmpdir(void) {
}
}
static void test_tmpdir(const char *id, const char *A, const char *B) {
static void test_tmpdir_one(const char *id, const char *A, const char *B) {
_cleanup_free_ char *a, *b;
struct stat x, y;
char *c, *d;
@ -63,6 +63,26 @@ static void test_tmpdir(const char *id, const char *A, const char *B) {
}
}
TEST(tmpdir) {
_cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;
sd_id128_t bid;
assert_se(sd_id128_get_boot(&bid) >= 0);
x = strjoin("/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-abcd.service-");
y = strjoin("/var/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-abcd.service-");
assert_se(x && y);
test_tmpdir_one("abcd.service", x, y);
z = strjoin("/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
zz = strjoin("/var/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
assert_se(z && zz);
test_tmpdir_one("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);
}
static void test_shareable_ns(unsigned long nsflag) {
_cleanup_close_pair_ int s[2] = { -1, -1 };
pid_t pid1, pid2, pid3;
@ -121,15 +141,15 @@ static void test_shareable_ns(unsigned long nsflag) {
assert_se(n == 1);
}
static void test_netns(void) {
TEST(netns) {
test_shareable_ns(CLONE_NEWNET);
}
static void test_ipcns(void) {
TEST(ipcns) {
test_shareable_ns(CLONE_NEWIPC);
}
static void test_protect_kernel_logs(void) {
TEST(protect_kernel_logs) {
int r;
pid_t pid;
static const NamespaceInfo ns_info = {
@ -200,37 +220,10 @@ static void test_protect_kernel_logs(void) {
assert_se(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG) == EXIT_SUCCESS);
}
int main(int argc, char *argv[]) {
_cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;
sd_id128_t bid;
test_setup_logging(LOG_INFO);
test_namespace_cleanup_tmpdir();
if (!have_namespaces()) {
log_tests_skipped("Don't have namespace support");
return EXIT_TEST_SKIP;
}
assert_se(sd_id128_get_boot(&bid) >= 0);
x = strjoin("/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-abcd.service-");
y = strjoin("/var/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-abcd.service-");
assert_se(x && y);
test_tmpdir("abcd.service", x, y);
z = strjoin("/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
zz = strjoin("/var/tmp/systemd-private-", SD_ID128_TO_STRING(bid), "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
assert_se(z && zz);
test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);
test_netns();
test_ipcns();
test_protect_kernel_logs();
return EXIT_SUCCESS;
}
DEFINE_CUSTOM_TEST_MAIN(
LOG_INFO,
({
if (!have_namespaces())
return log_tests_skipped("Don't have namespace support");
}),
/* no outro */);

View File

@ -94,7 +94,7 @@ TEST(parse_mode) {
assert_se(parse_mode(" 1", &m) >= 0 && m == 1);
}
TEST(parse_size) {
TEST(parse_size_iec) {
uint64_t bytes;
assert_se(parse_size("", 1024, &bytes) == -EINVAL);
@ -164,6 +164,76 @@ TEST(parse_size) {
assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
}
TEST(parse_size_si) {
uint64_t bytes;
assert_se(parse_size("", 1000, &bytes) == -EINVAL);
assert_se(parse_size("111", 1000, &bytes) == 0);
assert_se(bytes == 111);
assert_se(parse_size("111.4", 1000, &bytes) == 0);
assert_se(bytes == 111);
assert_se(parse_size(" 112 B", 1000, &bytes) == 0);
assert_se(bytes == 112);
assert_se(parse_size(" 112.6 B", 1000, &bytes) == 0);
assert_se(bytes == 112);
assert_se(parse_size("3.5 K", 1000, &bytes) == 0);
assert_se(bytes == 3*1000 + 500);
assert_se(parse_size("3. K", 1000, &bytes) == 0);
assert_se(bytes == 3*1000);
assert_se(parse_size("3.0 K", 1000, &bytes) == 0);
assert_se(bytes == 3*1000);
assert_se(parse_size("3. 0 K", 1000, &bytes) == -EINVAL);
assert_se(parse_size(" 4 M 11.5K", 1000, &bytes) == 0);
assert_se(bytes == 4*1000*1000 + 11 * 1000 + 500);
assert_se(parse_size("3B3.5G", 1000, &bytes) == -EINVAL);
assert_se(parse_size("3.5G3B", 1000, &bytes) == 0);
assert_se(bytes == 3ULL*1000*1000*1000 + 500*1000*1000 + 3);
assert_se(parse_size("3.5G 4B", 1000, &bytes) == 0);
assert_se(bytes == 3ULL*1000*1000*1000 + 500*1000*1000 + 4);
assert_se(parse_size("3B3G4T", 1000, &bytes) == -EINVAL);
assert_se(parse_size("4T3G3B", 1000, &bytes) == 0);
assert_se(bytes == (4ULL*1000 + 3)*1000*1000*1000 + 3);
assert_se(parse_size(" 4 T 3 G 3 B", 1000, &bytes) == 0);
assert_se(bytes == (4ULL*1000 + 3)*1000*1000*1000 + 3);
assert_se(parse_size("12P", 1000, &bytes) == 0);
assert_se(bytes == 12ULL * 1000*1000*1000*1000*1000);
assert_se(parse_size("12P12P", 1000, &bytes) == -EINVAL);
assert_se(parse_size("3E 2P", 1000, &bytes) == 0);
assert_se(bytes == (3 * 1000 + 2ULL) * 1000*1000*1000*1000*1000);
assert_se(parse_size("12X", 1000, &bytes) == -EINVAL);
assert_se(parse_size("12.5X", 1000, &bytes) == -EINVAL);
assert_se(parse_size("12.5e3", 1000, &bytes) == -EINVAL);
assert_se(parse_size("1000E", 1000, &bytes) == -ERANGE);
assert_se(parse_size("-1", 1000, &bytes) == -ERANGE);
assert_se(parse_size("-1000E", 1000, &bytes) == -ERANGE);
assert_se(parse_size("-1000P", 1000, &bytes) == -ERANGE);
assert_se(parse_size("-10B 20K", 1000, &bytes) == -ERANGE);
}
TEST(parse_range) {
unsigned lower, upper;

View File

@ -93,5 +93,13 @@ int main(void) {
printf("timeval: %zu\n", sizeof(struct timeval));
printf("timespec: %zu\n", sizeof(struct timespec));
void *x = malloc(100);
printf("local variable: %p\n", &function_pointer);
printf("glibc function: %p\n", memcpy);
printf("heap allocation: %p\n", x);
free(x);
return 0;
}

View File

@ -17,9 +17,8 @@
#include "tests.h"
#include "util.h"
static void test_parse_sleep_config(void) {
TEST(parse_sleep_config) {
_cleanup_(free_sleep_configp) SleepConfig *sleep_config = NULL;
log_info("/* %s */", __func__);
assert_se(parse_sleep_config(&sleep_config) == 0);
@ -43,7 +42,7 @@ static void test_parse_sleep_config(void) {
log_debug(" states: %s", hys);
}
static int test_fiemap(const char *path) {
static int test_fiemap_one(const char *path) {
_cleanup_free_ struct fiemap *fiemap = NULL;
_cleanup_close_ int fd = -1;
int r;
@ -71,7 +70,20 @@ static int test_fiemap(const char *path) {
return 0;
}
static void test_sleep(void) {
TEST_RET(fiemap) {
int r = 0;
assert_se(test_fiemap_one(saved_argv[0]) == 0);
for (int i = 1; i < saved_argc; i++) {
int k = test_fiemap_one(saved_argv[i]);
if (r == 0)
r = k;
}
return r;
}
TEST(sleep) {
_cleanup_strv_free_ char
**standby = strv_new("standby"),
**mem = strv_new("mem"),
@ -83,8 +95,6 @@ static void test_sleep(void) {
**freeze = strv_new("freeze");
int r;
log_info("/* %s */", __func__);
printf("Secure boot: %sd\n", enable_disable(is_efi_secure_boot()));
log_info("/= individual sleep modes =/");
@ -108,25 +118,10 @@ static void test_sleep(void) {
log_info("Suspend-then-Hibernate configured and possible: %s", r >= 0 ? yes_no(r) : strerror_safe(r));
}
int main(int argc, char* argv[]) {
int i, r = 0, k;
test_setup_logging(LOG_DEBUG);
if (getuid() != 0)
log_warning("This program is unlikely to work for unprivileged users");
test_parse_sleep_config();
test_sleep();
if (argc <= 1)
assert_se(test_fiemap(argv[0]) == 0);
else
for (i = 1; i < argc; i++) {
k = test_fiemap(argv[i]);
if (r == 0)
r = k;
}
return r;
}
DEFINE_CUSTOM_TEST_MAIN(
LOG_DEBUG,
({
if (getuid() != 0)
log_warning("This program is unlikely to work for unprivileged users");
}),
/* no outro */);

View File

@ -33,9 +33,7 @@ static void test_unit_name_is_valid_one(const char *name, UnitNameFlags flags, b
assert_se(unit_name_is_valid(name, flags) == expected);
}
static void test_unit_name_is_valid(void) {
log_info("/* %s */", __func__);
TEST(unit_name_is_valid) {
test_unit_name_is_valid_one("foo.service", UNIT_NAME_ANY, true);
test_unit_name_is_valid_one("foo.service", UNIT_NAME_PLAIN, true);
test_unit_name_is_valid_one("foo.service", UNIT_NAME_INSTANCE, false);
@ -91,9 +89,7 @@ static void test_unit_name_replace_instance_one(const char *pattern, const char
assert_se(streq_ptr(t, expected));
}
static void test_unit_name_replace_instance(void) {
log_info("/* %s */", __func__);
TEST(unit_name_replace_instance) {
test_unit_name_replace_instance_one("foo@.service", "waldo", "foo@waldo.service", 0);
test_unit_name_replace_instance_one("foo@xyz.service", "waldo", "foo@waldo.service", 0);
test_unit_name_replace_instance_one("xyz", "waldo", NULL, -EINVAL);
@ -119,9 +115,7 @@ static void test_unit_name_from_path_one(const char *path, const char *suffix, c
}
}
static void test_unit_name_from_path(void) {
log_info("/* %s */", __func__);
TEST(unit_name_from_path) {
test_unit_name_from_path_one("/waldo", ".mount", "waldo.mount", 0);
test_unit_name_from_path_one("/waldo/quuix", ".mount", "waldo-quuix.mount", 0);
test_unit_name_from_path_one("/waldo/quuix/", ".mount", "waldo-quuix.mount", 0);
@ -149,9 +143,7 @@ static void test_unit_name_from_path_instance_one(const char *pattern, const cha
}
}
static void test_unit_name_from_path_instance(void) {
log_info("/* %s */", __func__);
TEST(unit_name_from_path_instance) {
test_unit_name_from_path_instance_one("waldo", "/waldo", ".mount", "waldo@waldo.mount", 0);
test_unit_name_from_path_instance_one("waldo", "/waldo////quuix////", ".mount", "waldo@waldo-quuix.mount", 0);
test_unit_name_from_path_instance_one("waldo", "/", ".mount", "waldo@-.mount", 0);
@ -170,9 +162,7 @@ static void test_unit_name_to_path_one(const char *unit, const char *path, int r
assert_se(streq_ptr(path, p));
}
static void test_unit_name_to_path(void) {
log_info("/* %s */", __func__);
TEST(unit_name_to_path) {
test_unit_name_to_path_one("home.mount", "/home", 0);
test_unit_name_to_path_one("home-lennart.mount", "/home/lennart", 0);
test_unit_name_to_path_one("home-lennart-.mount", NULL, -EINVAL);
@ -201,9 +191,7 @@ static void test_unit_name_mangle_one(bool allow_globs, const char *pattern, con
}
}
static void test_unit_name_mangle(void) {
log_info("/* %s */", __func__);
TEST(unit_name_mangle) {
test_unit_name_mangle_one(false, "foo.service", "foo.service", 0);
test_unit_name_mangle_one(false, "/home", "home.mount", 1);
test_unit_name_mangle_one(false, "/dev/sda", "dev-sda.device", 1);
@ -220,14 +208,12 @@ static void test_unit_name_mangle(void) {
test_unit_name_mangle_one(true, "ü*", "\\xc3\\xbc*", 1);
}
static int test_unit_printf(void) {
TEST_RET(unit_printf, .sd_booted = true) {
_cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
Unit *u;
int r;
log_info("/* %s */", __func__);
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &mid) >= 0 && mid);
assert_se(specifier_boot_id('b', NULL, NULL, NULL, &bid) >= 0 && bid);
assert_se(host = gethostname_malloc());
@ -328,9 +314,7 @@ static int test_unit_printf(void) {
return 0;
}
static void test_unit_instance_is_valid(void) {
log_info("/* %s */", __func__);
TEST(unit_instance_is_valid) {
assert_se(unit_instance_is_valid("fooBar"));
assert_se(unit_instance_is_valid("foo-bar"));
assert_se(unit_instance_is_valid("foo.stUff"));
@ -343,9 +327,7 @@ static void test_unit_instance_is_valid(void) {
assert_se(!unit_instance_is_valid("foo/bar"));
}
static void test_unit_prefix_is_valid(void) {
log_info("/* %s */", __func__);
TEST(unit_prefix_is_valid) {
assert_se(unit_prefix_is_valid("fooBar"));
assert_se(unit_prefix_is_valid("foo-bar"));
assert_se(unit_prefix_is_valid("foo.stUff"));
@ -359,11 +341,9 @@ static void test_unit_prefix_is_valid(void) {
assert_se(!unit_prefix_is_valid("@foo-bar"));
}
static void test_unit_name_change_suffix(void) {
TEST(unit_name_change_suffix) {
char *t;
log_info("/* %s */", __func__);
assert_se(unit_name_change_suffix("foo.mount", ".service", &t) == 0);
assert_se(streq(t, "foo.service"));
free(t);
@ -373,11 +353,9 @@ static void test_unit_name_change_suffix(void) {
free(t);
}
static void test_unit_name_build(void) {
TEST(unit_name_build) {
char *t;
log_info("/* %s */", __func__);
assert_se(unit_name_build("foo", "bar", ".service", &t) == 0);
assert_se(streq(t, "foo@bar.service"));
free(t);
@ -391,9 +369,7 @@ static void test_unit_name_build(void) {
free(t);
}
static void test_slice_name_is_valid(void) {
log_info("/* %s */", __func__);
TEST(slice_name_is_valid) {
assert_se( slice_name_is_valid(SPECIAL_ROOT_SLICE));
assert_se( slice_name_is_valid("foo.slice"));
assert_se( slice_name_is_valid("foo-bar.slice"));
@ -422,12 +398,10 @@ static void test_slice_name_is_valid(void) {
assert_se(!slice_name_is_valid("foo@bar.service"));
}
static void test_build_subslice(void) {
TEST(build_subslice) {
char *a;
char *b;
log_info("/* %s */", __func__);
assert_se(slice_build_subslice(SPECIAL_ROOT_SLICE, "foo", &a) >= 0);
assert_se(slice_build_subslice(a, "bar", &b) >= 0);
free(a);
@ -449,9 +423,7 @@ static void test_build_parent_slice_one(const char *name, const char *expect, in
assert_se(streq_ptr(s, expect));
}
static void test_build_parent_slice(void) {
log_info("/* %s */", __func__);
TEST(build_parent_slice) {
test_build_parent_slice_one(SPECIAL_ROOT_SLICE, NULL, 0);
test_build_parent_slice_one("foo.slice", SPECIAL_ROOT_SLICE, 1);
test_build_parent_slice_one("foo-bar.slice", "foo.slice", 1);
@ -470,12 +442,10 @@ static void test_build_parent_slice(void) {
test_build_parent_slice_one("@.slice", NULL, -EINVAL);
}
static void test_unit_name_to_instance(void) {
TEST(unit_name_to_instance) {
UnitNameFlags r;
char *instance;
log_info("/* %s */", __func__);
r = unit_name_to_instance("foo@bar.service", &instance);
assert_se(r == UNIT_NAME_INSTANCE);
assert_se(streq(instance, "bar"));
@ -504,11 +474,9 @@ static void test_unit_name_to_instance(void) {
assert_se(!instance);
}
static void test_unit_name_escape(void) {
TEST(unit_name_escape) {
_cleanup_free_ char *r;
log_info("/* %s */", __func__);
r = unit_name_escape("ab+-c.a/bc@foo.service");
assert_se(r);
assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
@ -522,9 +490,7 @@ static void test_u_n_t_one(const char *name, const char *expected, int ret) {
assert_se(streq_ptr(f, expected));
}
static void test_unit_name_template(void) {
log_info("/* %s */", __func__);
TEST(unit_name_template) {
test_u_n_t_one("foo@bar.service", "foo@.service", 0);
test_u_n_t_one("foo.mount", NULL, -EINVAL);
}
@ -536,9 +502,7 @@ static void test_unit_name_path_unescape_one(const char *name, const char *path,
assert_se(streq_ptr(path, p));
}
static void test_unit_name_path_unescape(void) {
log_info("/* %s */", __func__);
TEST(unit_name_path_unescape) {
test_unit_name_path_unescape_one("foo", "/foo", 0);
test_unit_name_path_unescape_one("foo-bar", "/foo/bar", 0);
test_unit_name_path_unescape_one("foo-.bar", "/foo/.bar", 0);
@ -560,9 +524,7 @@ static void test_unit_name_to_prefix_one(const char *input, int ret, const char
assert_se(streq_ptr(k, output));
}
static void test_unit_name_to_prefix(void) {
log_info("/* %s */", __func__);
TEST(unit_name_to_prefix) {
test_unit_name_to_prefix_one("foobar.service", 0, "foobar");
test_unit_name_to_prefix_one("", -EINVAL, NULL);
test_unit_name_to_prefix_one("foobar", -EINVAL, NULL);
@ -582,9 +544,7 @@ static void test_unit_name_from_dbus_path_one(const char *input, int ret, const
assert_se(streq_ptr(k, output));
}
static void test_unit_name_from_dbus_path(void) {
log_info("/* %s */", __func__);
TEST(unit_name_from_dbus_path) {
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dbus_2esocket", 0, "dbus.socket");
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2emount", 0, "-.mount");
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2eslice", 0, "-.slice");
@ -870,9 +830,7 @@ static void test_unit_name_from_dbus_path(void) {
test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/wpa_5fsupplicant_2eservice", 0, "wpa_supplicant.service");
}
static void test_unit_name_prefix_equal(void) {
log_info("/* %s */", __func__);
TEST(unit_name_prefix_equal) {
assert_se(unit_name_prefix_equal("a.service", "a.service"));
assert_se(unit_name_prefix_equal("a.service", "a.mount"));
assert_se(unit_name_prefix_equal("a@b.service", "a.service"));
@ -886,39 +844,15 @@ static void test_unit_name_prefix_equal(void) {
assert_se(!unit_name_prefix_equal("a", "a"));
}
int main(int argc, char* argv[]) {
DEFINE_CUSTOM_TEST_MAIN(
LOG_INFO,
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int r, rc = 0;
({
if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
test_setup_logging(LOG_INFO);
assert_se(runtime_dir = setup_fake_runtime_dir());
}),
r = enter_cgroup_subroot(NULL);
if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
assert_se(runtime_dir = setup_fake_runtime_dir());
test_unit_name_is_valid();
test_unit_name_replace_instance();
test_unit_name_from_path();
test_unit_name_from_path_instance();
test_unit_name_mangle();
test_unit_name_to_path();
TEST_REQ_RUNNING_SYSTEMD(rc = test_unit_printf());
test_unit_instance_is_valid();
test_unit_prefix_is_valid();
test_unit_name_change_suffix();
test_unit_name_build();
test_slice_name_is_valid();
test_build_subslice();
test_build_parent_slice();
test_unit_name_to_instance();
test_unit_name_escape();
test_unit_name_template();
test_unit_name_path_unescape();
test_unit_name_to_prefix();
test_unit_name_from_dbus_path();
test_unit_name_prefix_equal();
return rc;
}
/* no outro */);

View File

@ -23,12 +23,10 @@ static void test_deserialize_exec_command_one(Manager *m, const char *key, const
* always rejected with "Current command vanished from the unit file", and we don't leak anything. */
}
static void test_deserialize_exec_command(void) {
TEST(deserialize_exec_command) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
log_info("/* %s */", __func__);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
@ -50,19 +48,15 @@ static void test_deserialize_exec_command(void) {
test_deserialize_exec_command_one(m, "control-command", "ExecWhat 11 /a/b c d e", -EINVAL);
}
int main(int argc, char *argv[]) {
DEFINE_CUSTOM_TEST_MAIN(
LOG_DEBUG,
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int r;
({
if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
test_setup_logging(LOG_DEBUG);
assert_se(runtime_dir = setup_fake_runtime_dir());
}),
r = enter_cgroup_subroot(NULL);
if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
assert_se(runtime_dir = setup_fake_runtime_dir());
test_deserialize_exec_command();
return EXIT_SUCCESS;
}
/* no outro */);

View File

@ -85,7 +85,7 @@ static int inotify_handler(sd_event_source *s,
l = read(fd, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 0;
return log_warning_errno(errno, "Lost access to inotify: %m");

View File

@ -1349,7 +1349,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda
l = read(fd, &buffer, sizeof(buffer));
if (l < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (ERRNO_IS_TRANSIENT(errno))
return 1;
return log_error_errno(errno, "Failed to read inotify fd: %m");

View File

@ -17,6 +17,8 @@ PrivateKey=
PrivateKeyFile=
FwMark=
FirewallMark=
RouteTable=
RouteMetric=
[MACVTAP]
Mode=
SourceMACAddress=
@ -67,6 +69,8 @@ PresharedKeyFile=
PersistentKeepalive=
PublicKey=
AllowedIPs=
RouteTable=
RouteMetric=
[Tunnel]
FooOverUDP=
IPv6FlowLabel=

View File

@ -11,6 +11,8 @@ ListenPort=4500
# The key below should be overridden by PrivateKeyFile=
PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=
PrivateKeyFile=/run/systemd/network/25-wireguard-private-key.txt
RouteTable=1234
RouteMetric=123
# peer 1
[WireGuardPeer]

View File

@ -6,95 +6,3 @@ Name=wg98
Address=192.168.123.123/24
Address=fd8d:4d6d:3ccb:0500::1/64
IPv6AcceptRA=no
# nat64 via 1
[Route]
Destination = fd8d:4d6d:3ccb:0c79:2339:edce::/96
# nat64 via 2
[Route]
Destination = fd8d:4d6d:3ccb:a072:80da:de4f::/96
# nat64 via 3
[Route]
Destination = fd8d:4d6d:3ccb:f349:c4f0:10c1::/96
# nat64 via 4
[Route]
Destination = fd8d:4d6d:3ccb:b684:4f81:2e3e::/96
# nat64 via 5
[Route]
Destination = fd8d:4d6d:3ccb:c624:6bf7:4c09::/96
# nat64 via 6
[Route]
Destination = fd8d:4d6d:3ccb:9c11:d820:2e96::/96
# nat64 via 7
[Route]
Destination = fd8d:4d6d:3ccb:bad5:495d:8e9c::/96
# nat64 via 8
[Route]
Destination = fd8d:4d6d:3ccb:1e54:1415:35d0::/96
# nat64 via 9
[Route]
Destination = fd8d:4d6d:3ccb:1dbf:ca8a:32d3::/96
# nat64 via 10
[Route]
Destination = fd8d:4d6d:3ccb:dcdd:d33b:90c9::/96
# nat64 via 11
[Route]
Destination = fd8d:4d6d:3ccb:6f2e:6888:c6fd::/96
# nat64 via 12
[Route]
Destination = fd8d:4d6d:3ccb:d4f9:05dc:9296::/96
# nat64 via 13
[Route]
Destination = fd8d:4d6d:3ccb:b39c:9cdc:755a::/96
# nat64 via 14
[Route]
Destination = fd8d:4d6d:3ccb:bfe5:c3c3:5d77::/96
# nat64 via 15
[Route]
Destination = fd8d:4d6d:3ccb:900c:d437:ec27::/96
# nat64 via 16
[Route]
Destination = fd8d:4d6d:3ccb:270d:b5dd:4a3f::/96
# nat64 via 17
[Route]
Destination = fd8d:4d6d:3ccb:e2e1:ae15:103f::/96
# nat64 via 18
[Route]
Destination = fd8d:4d6d:3ccb:5660:679d:3532::/96
# nat64 via 19
[Route]
Destination = fd8d:4d6d:3ccb:6825:573f:30f3::/96
# nat64 via 20
[Route]
Destination = fd8d:4d6d:3ccb:a94b:cd6a:a32d::/96
# nat64 via 21
[Route]
Destination = fd8d:4d6d:3ccb:8d4d:0bab:7280::/96
# nat64 via 22
[Route]
Destination = fd8d:4d6d:3ccb:a3f3:df38:19b0::/96
# nat64 via 23
[Route]
Destination = fd8d:4d6d:3ccb:9742:9931:5217::/96

View File

@ -6,6 +6,9 @@ Kind=wireguard
[WireGuard]
ListenPort=51820
FwMark=1234
# settings below are ignored.
RouteTable=off
RouteMetric=456
[WireGuardPeer]
PublicKey=RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=
@ -14,3 +17,5 @@ AllowedIPs=fd31:bf08:57cb::/48,192.168.26.0/24
Endpoint=192.168.27.3:51820
PresharedKey=IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=
PersistentKeepalive=20
RouteTable=1234
RouteMetric=123

View File

@ -1383,6 +1383,63 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
print(output)
self.assertIn('inet6 fd8d:4d6d:3ccb:500::1/64 scope global', output)
output = check_output('ip -4 route show dev wg99 table 1234')
print(output)
self.assertIn('192.168.26.0/24 proto static metric 123', output)
output = check_output('ip -6 route show dev wg99 table 1234')
print(output)
self.assertIn('fd31:bf08:57cb::/48 proto static metric 123 pref medium', output)
output = check_output('ip -6 route show dev wg98 table 1234')
print(output)
self.assertIn('fd8d:4d6d:3ccb:500:c79:2339:edce:ece1 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:1dbf:ca8a:32d3:dd81 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:1e54:1415:35d0:a47c proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:270d:b5dd:4a3f:8909 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:5660:679d:3532:94d8 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:6825:573f:30f3:9472 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:6f2e:6888:c6fd:dfb9 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:8d4d:bab:7280:a09a proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:900c:d437:ec27:8822 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:9742:9931:5217:18d5 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:9c11:d820:2e96:9be0 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:a072:80da:de4f:add1 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:a3f3:df38:19b0:721 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:a94b:cd6a:a32d:90e6 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:b39c:9cdc:755a:ead3 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:b684:4f81:2e3e:132e proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:bad5:495d:8e9c:3427 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:bfe5:c3c3:5d77:fcb proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:c624:6bf7:4c09:3b59 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:d4f9:5dc:9296:a1a proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:dcdd:d33b:90c9:6088 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:e2e1:ae15:103f:f376 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:500:f349:c4f0:10c1:6b4 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:c79:2339:edce::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:1dbf:ca8a:32d3::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:1e54:1415:35d0::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:270d:b5dd:4a3f::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:5660:679d:3532::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:6825:573f:30f3::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:6f2e:6888:c6fd::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:8d4d:bab:7280::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:900c:d437:ec27::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:9742:9931:5217::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:9c11:d820:2e96::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:a072:80da:de4f::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:a3f3:df38:19b0::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:a94b:cd6a:a32d::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:b39c:9cdc:755a::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:b684:4f81:2e3e::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:bad5:495d:8e9c::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:bfe5:c3c3:5d77::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:c624:6bf7:4c09::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:d4f9:5dc:9296::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:dcdd:d33b:90c9::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:e2e1:ae15:103f::/96 proto static metric 123 pref medium', output)
self.assertIn('fd8d:4d6d:3ccb:f349:c4f0:10c1::/96 proto static metric 123 pref medium', output)
if shutil.which('wg'):
call('wg')

View File

@ -92,6 +92,11 @@ elif [ "${machine}" = "arm" ]; then
verity_guid=7386cdf2-203c-47a9-a498-f2ecce45a2d6
signature_guid=42b0455f-eb11-491d-98d3-56145ba9d037
architecture="arm"
elif [ "${machine}" = "loongarch64" ]; then
root_guid=77055800-792c-4f94-b39a-98c91b762bb6
verity_guid=f3393b22-e9af-4613-a948-9d3bfbd0c535
signature_guid=5afb67eb-ecc8-4f85-ae8e-ac1e7c50e7d0
architecture="loongarch64"
elif [ "${machine}" = "ia64" ]; then
root_guid=993d8d3d-f80e-4225-855a-9daf8ed7ea97
verity_guid=86ed10d5-b607-45bb-8957-d350f23d0571