1
0
mirror of https://github.com/systemd/systemd synced 2026-03-26 16:54:53 +01:00

Compare commits

..

No commits in common. "67317e214e7b8aed3aa16eed74f23eb11ca5148c" and "26b2085d54ebbfca8637362eafcb4a8e3faf832f" have entirely different histories.

25 changed files with 126 additions and 901 deletions

View File

@ -293,10 +293,8 @@
<para>Controls enrollment of secure boot keys found on the ESP if the system is in setup mode: <para>Controls enrollment of secure boot keys found on the ESP if the system is in setup mode:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><option>if-safe</option></term> <term><option>off</option></term>
<listitem><para>This is the default. Same behavior as <option>manual</option>, but will try to automatically <listitem><para>No action is taken.</para>
enroll the key named <literal>auto</literal> if it is considered to be safe. Currently, this is only
the case if the system is running inside a virtual machine.</para>
<xi:include href="version-info.xml" xpointer="v253"/></listitem> <xi:include href="version-info.xml" xpointer="v253"/></listitem>
</varlistentry> </varlistentry>
@ -310,8 +308,10 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>off</option></term> <term><option>if-safe</option></term>
<listitem><para>No action is taken.</para> <listitem><para>Same behavior as <option>manual</option>, but will try to automatically
enroll the key <literal>auto</literal> if it is considered to be safe. Currently, this is only
the case if the system is running inside a virtual machine.</para>
<xi:include href="version-info.xml" xpointer="v253"/></listitem> <xi:include href="version-info.xml" xpointer="v253"/></listitem>
</varlistentry> </varlistentry>

View File

@ -392,9 +392,8 @@
<para>Enrollment of Secure Boot variables can be performed manually or automatically if files are available <para>Enrollment of Secure Boot variables can be performed manually or automatically if files are available
under <filename>/loader/keys/<replaceable>NAME</replaceable>/{db,dbx,KEK,PK}.auth</filename>, <replaceable>NAME</replaceable> under <filename>/loader/keys/<replaceable>NAME</replaceable>/{db,dbx,KEK,PK}.auth</filename>, <replaceable>NAME</replaceable>
being the display name for the set of variables in the menu. If one of the sets is named <filename>auto</filename> being the display name for the set of variables in the menu. If one of the sets is named <filename>auto</filename>
then it might be enrolled automatically depending on the execution environment and the value of the <literal>secure-boot-enroll</literal> option. then it might be enrolled automatically depending on whether <literal>secure-boot-enroll</literal> is set
See to force or not.</para>
<citerefentry><refentrytitle>loader.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -2,24 +2,24 @@
# #
# Czech translation for systemd. # Czech translation for systemd.
# #
# Daniel Rusek <mail@asciiwolf.com>, 2022, 2023, 2025. # Daniel Rusek <mail@asciiwolf.com>, 2022, 2023.
# Pavel Borecki <pavel.borecki@gmail.com>, 2023, 2024, 2025. # Pavel Borecki <pavel.borecki@gmail.com>, 2023, 2024.
# Jan Kalabza <jan.kalabza@gmail.com>, 2025. # Jan Kalabza <jan.kalabza@gmail.com>, 2025.
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-26 01:17+0000\n" "POT-Creation-Date: 2025-11-26 01:17+0000\n"
"PO-Revision-Date: 2025-12-05 13:08+0000\n" "PO-Revision-Date: 2025-02-10 02:01+0000\n"
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n" "Last-Translator: Jan Kalabza <jan.kalabza@gmail.com>\n"
"Language-Team: Czech <https://translate.fedoraproject.org/projects/systemd/" "Language-Team: Czech <https://translate.fedoraproject.org/projects/systemd/"
"main/cs/>\n" "main/cs/>\n"
"Language: cs\n" "Language: cs\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "|| n%100>=20) ? 1 : 2);\n"
"X-Generator: Weblate 5.14.3\n" "X-Generator: Weblate 5.9.2\n"
#: src/core/org.freedesktop.systemd1.policy.in:22 #: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system" msgid "Send passphrase back to system"
@ -120,7 +120,7 @@ msgstr "Aktualizujte svůj domovský adresář"
#: src/home/org.freedesktop.home1.policy:54 #: src/home/org.freedesktop.home1.policy:54
msgid "Authentication is required to update your home area." msgid "Authentication is required to update your home area."
msgstr "Pro aktualizaci domovské adresáře je vyžadováno ověření." msgstr "Pro aktualizaci domovské adresáře je nutné ověření."
#: src/home/org.freedesktop.home1.policy:63 #: src/home/org.freedesktop.home1.policy:63
msgid "Resize a home area" msgid "Resize a home area"
@ -146,16 +146,17 @@ msgstr "Aktivovat domovskou složku"
#: src/home/org.freedesktop.home1.policy:84 #: src/home/org.freedesktop.home1.policy:84
msgid "Authentication is required to activate a user's home area." msgid "Authentication is required to activate a user's home area."
msgstr "K aktivaci domovského adresáře uživatele je vyžadováno ověření." msgstr "K aktivaci domovského adresáře uživatele je nutné ověření."
#: src/home/org.freedesktop.home1.policy:93 #: src/home/org.freedesktop.home1.policy:93
msgid "Manage Home Directory Signing Keys" msgid "Manage Home Directory Signing Keys"
msgstr "Spravovat klíče pro podepisování domovské složky" msgstr ""
#: src/home/org.freedesktop.home1.policy:94 #: src/home/org.freedesktop.home1.policy:94
#, fuzzy
msgid "Authentication is required to manage signing keys for home directories." msgid "Authentication is required to manage signing keys for home directories."
msgstr "" msgstr ""
"Pro správu klíčů pro podepisování domovských složek je vyžadováno ověření." "Pro správu systémových služeb nebo dalších jednotek je vyžadováno ověření."
#: src/home/pam_systemd_home.c:333 #: src/home/pam_systemd_home.c:333
#, c-format #, c-format
@ -881,15 +882,16 @@ msgstr ""
"K vytvoření místního virtuálního počítače nebo kontejneru je nutné ověření." "K vytvoření místního virtuálního počítače nebo kontejneru je nutné ověření."
#: src/machine/org.freedesktop.machine1.policy:106 #: src/machine/org.freedesktop.machine1.policy:106
#, fuzzy
msgid "Register a local virtual machine or container" msgid "Register a local virtual machine or container"
msgstr "Zaregistrovat lokální virtuální stroj nebo kontejner" msgstr "Vytvoření místního virtuálního počítače nebo kontejneru"
#: src/machine/org.freedesktop.machine1.policy:107 #: src/machine/org.freedesktop.machine1.policy:107
#, fuzzy
msgid "" msgid ""
"Authentication is required to register a local virtual machine or container." "Authentication is required to register a local virtual machine or container."
msgstr "" msgstr ""
"K zaregistrování lokálního virtuálního stroje nebo kontejneru je nutné " "K vytvoření místního virtuálního počítače nebo kontejneru je nutné ověření."
"ověření."
#: src/machine/org.freedesktop.machine1.policy:116 #: src/machine/org.freedesktop.machine1.policy:116
msgid "Manage local virtual machine and container images" msgid "Manage local virtual machine and container images"
@ -1113,11 +1115,12 @@ msgstr "Pro přihlášení k odběru výsledků dotazu je vyžadováno ověřen
#: src/resolve/org.freedesktop.resolve1.policy:154 #: src/resolve/org.freedesktop.resolve1.policy:154
msgid "Subscribe to DNS configuration" msgid "Subscribe to DNS configuration"
msgstr "Přihlásit se k odběru nastavení DNS" msgstr ""
#: src/resolve/org.freedesktop.resolve1.policy:155 #: src/resolve/org.freedesktop.resolve1.policy:155
#, fuzzy
msgid "Authentication is required to subscribe to DNS configuration." msgid "Authentication is required to subscribe to DNS configuration."
msgstr "Pro přihlášení k odběru nastavení DNS je vyžadováno ověření." msgstr "Pro přihlášení k odběru výsledků dotazu je vyžadováno ověření."
#: src/resolve/org.freedesktop.resolve1.policy:165 #: src/resolve/org.freedesktop.resolve1.policy:165
msgid "Dump cache" msgid "Dump cache"
@ -1256,12 +1259,11 @@ msgid ""
msgstr "Pro odeslání UNIX signálu procesům „$(unit)” je vyžadováno ověření." msgstr "Pro odeslání UNIX signálu procesům „$(unit)” je vyžadováno ověření."
#: src/core/dbus-unit.c:620 #: src/core/dbus-unit.c:620
#, fuzzy
msgid "" msgid ""
"Authentication is required to send a UNIX signal to the processes of " "Authentication is required to send a UNIX signal to the processes of "
"subgroup of '$(unit)'." "subgroup of '$(unit)'."
msgstr "" msgstr "Pro odeslání UNIX signálu procesům „$(unit)” je vyžadováno ověření."
"Pro odeslání UNIX signálu procesům nebo podskupině „$(unit)” je vyžadováno "
"ověření."
#: src/core/dbus-unit.c:648 #: src/core/dbus-unit.c:648
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'." msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."

View File

@ -59,13 +59,9 @@
#define DEFAULT_RLIMIT_MEMLOCK (1024ULL*1024ULL*8ULL) #define DEFAULT_RLIMIT_MEMLOCK (1024ULL*1024ULL*8ULL)
/* Path where PID1 listens for varlink subscriptions from systemd-oomd to notify of changes in ManagedOOM settings. */ /* Path where PID1 listens for varlink subscriptions from systemd-oomd to notify of changes in ManagedOOM settings. */
#define VARLINK_PATH_MANAGED_OOM_SYSTEM "/run/systemd/io.systemd.ManagedOOM" #define VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM "/run/systemd/io.systemd.ManagedOOM"
/* Path where systemd-oomd listens for varlink connections from user managers to report changes in ManagedOOM settings. */ /* Path where systemd-oomd listens for varlink connections from user managers to report changes in ManagedOOM settings. */
#define VARLINK_PATH_MANAGED_OOM_USER "/run/systemd/oom/io.systemd.ManagedOOM" #define VARLINK_ADDR_PATH_MANAGED_OOM_USER "/run/systemd/oom/io.systemd.ManagedOOM"
/* Path where systemd-machined listens to userdb varlink queries */
#define VARLINK_PATH_MACHINED_USERDB "/run/systemd/userdb/io.systemd.Machine"
/* Path where systemd-machined listens to resolve.hook varlink queries */
#define VARLINK_PATH_MACHINED_RESOLVE_HOOK "/run/systemd/resolve.hook/io.systemd.Machine"
/* Recommended baseline - see README for details */ /* Recommended baseline - see README for details */
#define KERNEL_BASELINE_VERSION "5.7" #define KERNEL_BASELINE_VERSION "5.7"

View File

@ -2997,8 +2997,9 @@ static void config_load_all_entries(
config_add_system_entries(config); config_add_system_entries(config);
/* Using the rules defined by the `secure-boot-enroll` variable, find secure boot signing keys /* Find secure boot signing keys and autoload them if configured. Otherwise, create menu entries so
* and perform operations like autoloading them or create menu entries if configured. */ * that the user can load them manually. If the secure-boot-enroll variable is set to no (the
* default), we do not even search for keys on the ESP */
(void) secure_boot_discover_keys(config, root_dir); (void) secure_boot_discover_keys(config, root_dir);
if (config->n_entries == 0) if (config->n_entries == 0)

View File

@ -169,7 +169,7 @@ static int managed_oom_vl_reply(sd_varlink *link, sd_json_variant *parameters, c
m->managed_oom_varlink = sd_varlink_unref(link); m->managed_oom_varlink = sd_varlink_unref(link);
log_debug("Reconnecting to %s", VARLINK_PATH_MANAGED_OOM_USER); log_debug("Reconnecting to %s", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
r = manager_varlink_managed_oom_connect(m); r = manager_varlink_managed_oom_connect(m);
if (r <= 0) if (r <= 0)
@ -194,7 +194,7 @@ static int manager_varlink_managed_oom_connect(Manager *m) {
if (MANAGER_IS_TEST_RUN(m)) if (MANAGER_IS_TEST_RUN(m))
return 0; return 0;
r = sd_varlink_connect_address(&link, VARLINK_PATH_MANAGED_OOM_USER); r = sd_varlink_connect_address(&link, VARLINK_ADDR_PATH_MANAGED_OOM_USER);
if (r == -ENOENT) if (r == -ENOENT)
return 0; return 0;
if (ERRNO_IS_NEG_DISCONNECT(r)) { if (ERRNO_IS_NEG_DISCONNECT(r)) {
@ -202,7 +202,7 @@ static int manager_varlink_managed_oom_connect(Manager *m) {
return 0; return 0;
} }
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to connect to '%s': %m", VARLINK_PATH_MANAGED_OOM_USER); return log_error_errno(r, "Failed to connect to '%s': %m", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
sd_varlink_set_userdata(link, m); sd_varlink_set_userdata(link, m);
@ -435,7 +435,7 @@ static int manager_varlink_init_system(Manager *m) {
if (!MANAGER_IS_TEST_RUN(m)) { if (!MANAGER_IS_TEST_RUN(m)) {
FOREACH_STRING(address, FOREACH_STRING(address,
"/run/systemd/userdb/io.systemd.DynamicUser", "/run/systemd/userdb/io.systemd.DynamicUser",
VARLINK_PATH_MANAGED_OOM_SYSTEM, VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM,
"/run/systemd/io.systemd.Manager") { "/run/systemd/io.systemd.Manager") {
/* We might have got sockets through deserialization. Do not bind to them twice. */ /* We might have got sockets through deserialization. Do not bind to them twice. */
if (!fresh && varlink_server_contains_socket(m->varlink_server, address)) if (!fresh && varlink_server_contains_socket(m->varlink_server, address))

View File

@ -1,29 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/* getopt() is provided both in getopt.h and unistd.h. Hence, we need to tentatively undefine it. */
#undef getopt
#include_next <getopt.h>
/* musl's getopt() always behaves POSIXLY_CORRECT mode, and stops parsing arguments when a non-option string
* found. Let's always use getopt_long(). */
int getopt_fix(int argc, char * const *argv, const char *optstring);
#define getopt(argc, argv, optstring) getopt_fix(argc, argv, optstring)
/* musl's getopt_long() behaves something different in handling optional arguments.
* ========
* $ journalctl _PID=1 _COMM=systemd --since 19:19:01 -n all --follow
* Failed to add match 'all': Invalid argument
* ========
* Here, we introduce getopt_long_fix() that reorders the passed arguments to make getopt_long() provided by
* musl works as what we expect. */
int getopt_long_fix(
int argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
#define getopt_long(argc, argv, optstring, longopts, longindex) \
getopt_long_fix(argc, argv, optstring, longopts, longindex)

View File

@ -1,12 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/* getopt() is provided both in getopt.h and unistd.h. Hence, we need to tentatively undefine it. */
#undef getopt
#include_next <unistd.h>
/* musl's getopt() always behaves POSIXLY_CORRECT mode, and stops parsing arguments when a non-option string
* found. Let's always use getopt_long(). */
int getopt_fix(int argc, char * const *argv, const char *optstring);
#define getopt(argc, argv, optstring) getopt_fix(argc, argv, optstring)

View File

@ -362,9 +362,7 @@ static int on_first_event(sd_event_source *s, void *userdata) {
return log_error_errno(r, "Failed to get cursor: %m"); return log_error_errno(r, "Failed to get cursor: %m");
} }
/* Setup and initial processing are done, we're ready to wait for more data. */
(void) sd_notify(/* unset_environment= */ false, "READY=1"); (void) sd_notify(/* unset_environment= */ false, "READY=1");
return 0; return 0;
} }
@ -474,9 +472,11 @@ static int setup_event(Context *c, int fd) {
else if (r < 0) else if (r < 0)
return log_error_errno(r, "Failed to add io event source for stdout: %m"); return log_error_errno(r, "Failed to add io event source for stdout: %m");
r = sd_event_add_defer(e, NULL, on_first_event, c); if (arg_lines != 0 || arg_since_set) {
if (r < 0) r = sd_event_add_defer(e, NULL, on_first_event, c);
return log_error_errno(r, "Failed to add defer event source: %m"); if (r < 0)
return log_error_errno(r, "Failed to add defer event source: %m");
}
c->event = TAKE_PTR(e); c->event = TAKE_PTR(e);
return 0; return 0;
@ -583,7 +583,6 @@ int action_show(char **matches) {
return 0; return 0;
} }
/* Setup is done, we'll start processing data. */
(void) sd_notify(/* unset_environment= */ false, "READY=1"); (void) sd_notify(/* unset_environment= */ false, "READY=1");
r = show(&c); r = show(&c);

View File

@ -1,100 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include <stdbool.h>
#include <string.h>
static int first_non_opt = 0, last_non_opt = 0;
static bool non_opt_found = false, dash_dash = false;
static void shift(char * const *argv, int start, int end) {
char **av = (char**) argv;
char *saved = av[end];
for (int i = end; i > start; i--)
av[i] = av[i - 1];
av[start] = saved;
}
static void exchange(int argc, char * const *argv) {
/* input:
*
* first_non_opt last_non_opt optind
* | | |
* v v v
* aaaaa bbbbb ccccc --prev-opt prev-opt-arg ddddd --next-opt
*
* output:
* first_non_opt last_non_opt optind
* | | |
* v v v
* --prev-opt prev-opt-arg aaaaa bbbbb ccccc ddddd --next-opt
*/
/* First, move previous arguments. */
int c = optind - 1 - last_non_opt;
if (c > 0) {
for (int i = 0; i < c; i++)
shift(argv, first_non_opt, optind - 1);
first_non_opt += c;
last_non_opt += c;
}
/* Then, skip entries that do not start with '-'. */
while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) {
if (!non_opt_found) {
first_non_opt = optind;
non_opt_found = true;
}
last_non_opt = optind;
optind++;
}
}
int getopt_long_fix(
int argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex) {
int r;
if (optind == 0 || first_non_opt == 0 || last_non_opt == 0) {
/* initialize musl's internal variables. */
(void) (getopt_long)(/* argc= */ -1, /* argv= */ NULL, /* optstring= */ NULL, /* longopts= */ NULL, /* longindex= */ NULL);
first_non_opt = last_non_opt = 1;
non_opt_found = dash_dash = false;
}
if (first_non_opt >= argc || last_non_opt >= argc || optind > argc || dash_dash)
return -1;
/* Do not shuffle arguments when optstring starts with '+' or '-'. */
if (!optstring || optstring[0] == '+' || optstring[0] == '-')
return (getopt_long)(argc, argv, optstring, longopts, longindex);
exchange(argc, argv);
if (optind < argc && strcmp(argv[optind], "--") == 0) {
if (first_non_opt < optind)
shift(argv, first_non_opt, optind);
first_non_opt++;
optind++;
dash_dash = true;
if (non_opt_found)
optind = first_non_opt;
return -1;
}
r = (getopt_long)(argc, argv, optstring, longopts, longindex);
if (r < 0 && non_opt_found)
optind = first_non_opt;
return r;
}
int getopt_fix(int argc, char * const *argv, const char *optstring) {
return getopt_long_fix(argc, argv, optstring, /* longopts= */ NULL, /* longindex= */ NULL);
}

View File

@ -5,7 +5,6 @@ if get_option('libc') != 'musl'
endif endif
libc_wrapper_sources += files( libc_wrapper_sources += files(
'getopt.c',
'printf.c', 'printf.c',
'stdio.c', 'stdio.c',
'stdlib.c', 'stdlib.c',

View File

@ -505,14 +505,13 @@ static int pid_notify_with_fds_internal(
if (r == -EPROTO) if (r == -EPROTO)
r = socket_address_parse_vsock(&address, e); r = socket_address_parse_vsock(&address, e);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Address NOTIFY_SOCKET='%s' is neither UNIX nor VSOCK, refusing: %m", e); return r;
msghdr.msg_namelen = address.size; msghdr.msg_namelen = address.size;
/* If we didn't get an address (which is a normal pattern when specifying VSOCK tuples) error out, /* If we didn't get an address (which is a normal pattern when specifying VSOCK tuples) error out,
* we always require a specific CID. */ * we always require a specific CID. */
if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY) if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), return -EINVAL;
"VSOCK address in NOTIFY_SOCKET='%s' doesn't have CID, refusing.", e);
type = address.type == 0 ? SOCK_DGRAM : address.type; type = address.type == 0 ? SOCK_DGRAM : address.type;
@ -611,8 +610,7 @@ static int pid_notify_with_fds_internal(
} else { } else {
/* Unless we're using SOCK_STREAM, we expect to write all the contents immediately. */ /* Unless we're using SOCK_STREAM, we expect to write all the contents immediately. */
if (type != SOCK_STREAM && (size_t) n < iovec_total_size(msghdr.msg_iov, msghdr.msg_iovlen)) if (type != SOCK_STREAM && (size_t) n < iovec_total_size(msghdr.msg_iov, msghdr.msg_iovlen))
return log_debug_errno(SYNTHETIC_ERRNO(EIO), return -EIO;
"Incomplete notify message sent to '%s': %m", e);
/* Make sure we only send fds and ucred once, even if we're using SOCK_STREAM. */ /* Make sure we only send fds and ucred once, even if we're using SOCK_STREAM. */
msghdr.msg_control = NULL; msghdr.msg_control = NULL;
@ -633,7 +631,6 @@ static int pid_notify_with_fds_internal(
return log_debug_errno(SYNTHETIC_ERRNO(EPROTO), "Unexpectedly received data on notify socket."); return log_debug_errno(SYNTHETIC_ERRNO(EPROTO), "Unexpectedly received data on notify socket.");
} }
log_debug("Notify message sent to '%s': \"%s\"", e, state);
return 1; return 1;
} }

View File

@ -55,11 +55,6 @@ typedef struct sd_netlink_slot {
}; };
} sd_netlink_slot; } sd_netlink_slot;
typedef struct NetlinkIgnoredSerial {
uint32_t serial;
usec_t timeout_usec; /* timestamp in CLOCK_MONOTONIC */
} NetlinkIgnoredSerial;
typedef struct sd_netlink { typedef struct sd_netlink {
unsigned n_ref; unsigned n_ref;
@ -83,7 +78,6 @@ typedef struct sd_netlink {
bool processing:1; bool processing:1;
uint32_t serial; uint32_t serial;
Hashmap *ignored_serials;
struct Prioq *reply_callbacks_prioq; struct Prioq *reply_callbacks_prioq;
Hashmap *reply_callbacks; Hashmap *reply_callbacks;
@ -187,7 +181,8 @@ int sd_nfnl_call_batch(
sd_netlink *nfnl, sd_netlink *nfnl,
sd_netlink_message **messages, sd_netlink_message **messages,
size_t n_messages, size_t n_messages,
uint64_t usec); uint64_t usec,
sd_netlink_message ***ret_messages);
int sd_nfnl_message_new( int sd_nfnl_message_new(
sd_netlink *nfnl, sd_netlink *nfnl,
sd_netlink_message **ret, sd_netlink_message **ret,

View File

@ -7,6 +7,7 @@
#include "sd-netlink.h" #include "sd-netlink.h"
#include "alloc-util.h" #include "alloc-util.h"
#include "errno-util.h"
#include "iovec-util.h" #include "iovec-util.h"
#include "netlink-internal.h" #include "netlink-internal.h"
#include "netlink-util.h" #include "netlink-util.h"
@ -118,7 +119,7 @@ int sd_nfnl_send_batch(
return -ENOMEM; return -ENOMEM;
if (ret_serials) { if (ret_serials) {
serials = new(uint32_t, n_messages + 2); serials = new(uint32_t, n_messages);
if (!serials) if (!serials)
return -ENOMEM; return -ENOMEM;
} }
@ -132,9 +133,6 @@ int sd_nfnl_send_batch(
return r; return r;
netlink_seal_message(nfnl, batch_begin); netlink_seal_message(nfnl, batch_begin);
if (serials)
serials[c] = message_get_serial(batch_begin);
iovs[c++] = IOVEC_MAKE(batch_begin->hdr, batch_begin->hdr->nlmsg_len); iovs[c++] = IOVEC_MAKE(batch_begin->hdr, batch_begin->hdr->nlmsg_len);
for (size_t i = 0; i < n_messages; i++) { for (size_t i = 0; i < n_messages; i++) {
@ -149,7 +147,7 @@ int sd_nfnl_send_batch(
netlink_seal_message(nfnl, messages[i]); netlink_seal_message(nfnl, messages[i]);
if (serials) if (serials)
serials[c] = message_get_serial(messages[i]); serials[i] = message_get_serial(messages[i]);
/* It seems that the kernel accepts an arbitrary number. Let's set the lower 16 bits of the /* It seems that the kernel accepts an arbitrary number. Let's set the lower 16 bits of the
* serial of the first message. */ * serial of the first message. */
@ -163,9 +161,6 @@ int sd_nfnl_send_batch(
return r; return r;
netlink_seal_message(nfnl, batch_end); netlink_seal_message(nfnl, batch_end);
if (serials)
serials[c] = message_get_serial(batch_end);
iovs[c++] = IOVEC_MAKE(batch_end->hdr, batch_end->hdr->nlmsg_len); iovs[c++] = IOVEC_MAKE(batch_end->hdr, batch_end->hdr->nlmsg_len);
assert(c == n_messages + 2); assert(c == n_messages + 2);
@ -183,8 +178,10 @@ int sd_nfnl_call_batch(
sd_netlink *nfnl, sd_netlink *nfnl,
sd_netlink_message **messages, sd_netlink_message **messages,
size_t n_messages, size_t n_messages,
uint64_t usec) { uint64_t usec,
sd_netlink_message ***ret_messages) {
_cleanup_free_ sd_netlink_message **replies = NULL;
_cleanup_free_ uint32_t *serials = NULL; _cleanup_free_ uint32_t *serials = NULL;
int r; int r;
@ -193,40 +190,26 @@ int sd_nfnl_call_batch(
assert_return(messages, -EINVAL); assert_return(messages, -EINVAL);
assert_return(n_messages > 0, -EINVAL); assert_return(n_messages > 0, -EINVAL);
if (ret_messages) {
replies = new0(sd_netlink_message*, n_messages);
if (!replies)
return -ENOMEM;
}
r = sd_nfnl_send_batch(nfnl, messages, n_messages, &serials); r = sd_nfnl_send_batch(nfnl, messages, n_messages, &serials);
if (r < 0) if (r < 0)
return r; return r;
for (size_t i = 1; i <= n_messages; i++) { for (size_t i = 0; i < n_messages; i++)
/* If we have received an error, kernel may not send replies for later messages. Let's ignore RET_GATHER(r,
* remaining replies. */ sd_netlink_read(nfnl, serials[i], usec, ret_messages ? replies + i : NULL));
if (r < 0) { if (r < 0)
(void) sd_netlink_ignore_serial(nfnl, serials[i], usec); return r;
continue;
}
r = sd_netlink_read(nfnl, serials[i], usec, /* ret= */ NULL); if (ret_messages)
if (r != -ETIMEDOUT) *ret_messages = TAKE_PTR(replies);
continue;
/* The kernel returns some errors, e.g. unprivileged, to the BATCH_BEGIN. Hence, if we have return 0;
* not received any replies for the batch body, try to read an error in the reply for the
* batch begin. Note, since v6.10 (bf2ac490d28c21a349e9eef81edc45320fca4a3c), we can expect
* that the kernel always replies the batch begin and end. When we bump the kernel baseline,
* we can read the reply for the batch begin at first. */
int k = sd_netlink_read(nfnl, serials[0], usec, /* ret= */ NULL);
if (k < 0)
r = k;
serials[0] = 0; /* indicates that we have read the reply. */
}
/* Ignore replies for batch begin and end if we have not read them. */
if (serials[0] != 0)
(void) sd_netlink_ignore_serial(nfnl, serials[0], usec);
(void) sd_netlink_ignore_serial(nfnl, serials[n_messages + 1], usec);
return r;
} }
int sd_nfnl_nft_message_new_basechain( int sd_nfnl_nft_message_new_basechain(

View File

@ -222,16 +222,6 @@ static int netlink_queue_received_message(sd_netlink *nl, sd_netlink_message *m)
assert(nl); assert(nl);
assert(m); assert(m);
serial = message_get_serial(m);
if (serial != 0) {
NetlinkIgnoredSerial *s = hashmap_remove(nl->ignored_serials, UINT32_TO_PTR(serial));
if (s) {
/* We are not interested in the message anymore. */
free(s);
return 0;
}
}
if (ordered_set_size(nl->rqueue) >= NETLINK_RQUEUE_MAX) if (ordered_set_size(nl->rqueue) >= NETLINK_RQUEUE_MAX)
return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS), return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS),
"sd-netlink: exhausted the read queue size (%d)", NETLINK_RQUEUE_MAX); "sd-netlink: exhausted the read queue size (%d)", NETLINK_RQUEUE_MAX);
@ -245,6 +235,7 @@ static int netlink_queue_received_message(sd_netlink *nl, sd_netlink_message *m)
if (sd_netlink_message_is_broadcast(m)) if (sd_netlink_message_is_broadcast(m))
return 0; return 0;
serial = message_get_serial(m);
if (serial == 0) if (serial == 0)
return 0; return 0;

View File

@ -126,8 +126,6 @@ static sd_netlink *netlink_free(sd_netlink *nl) {
assert(nl); assert(nl);
hashmap_free(nl->ignored_serials);
ordered_set_free(nl->rqueue); ordered_set_free(nl->rqueue);
hashmap_free(nl->rqueue_by_serial); hashmap_free(nl->rqueue_by_serial);
hashmap_free(nl->rqueue_partial_by_serial); hashmap_free(nl->rqueue_partial_by_serial);
@ -154,96 +152,6 @@ static sd_netlink *netlink_free(sd_netlink *nl) {
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_netlink, sd_netlink, netlink_free); DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_netlink, sd_netlink, netlink_free);
static usec_t netlink_now(sd_netlink *nl, clock_t clock) {
assert(nl);
usec_t now_usec;
if (nl->event && sd_event_now(nl->event, clock, &now_usec) > 0)
return now_usec;
return now(clock);
}
static usec_t timespan_to_timestamp(sd_netlink *nl, usec_t usec) {
static bool default_timeout_set = false;
static usec_t default_timeout;
int r;
assert(nl);
if (usec == 0) {
if (!default_timeout_set) {
const char *e;
default_timeout_set = true;
default_timeout = NETLINK_DEFAULT_TIMEOUT_USEC;
e = secure_getenv("SYSTEMD_NETLINK_DEFAULT_TIMEOUT");
if (e) {
r = parse_sec(e, &default_timeout);
if (r < 0)
log_debug_errno(r, "sd-netlink: Failed to parse $SYSTEMD_NETLINK_DEFAULT_TIMEOUT environment variable, ignoring: %m");
}
}
usec = default_timeout;
}
return usec_add(netlink_now(nl, CLOCK_MONOTONIC), usec);
}
static void netlink_trim_ignored_serials(sd_netlink *nl) {
NetlinkIgnoredSerial *s;
usec_t now_usec = 0;
assert(nl);
HASHMAP_FOREACH(s, nl->ignored_serials) {
if (s->timeout_usec == USEC_INFINITY)
continue;
if (now_usec == 0)
now_usec = netlink_now(nl, CLOCK_MONOTONIC);
if (s->timeout_usec < now_usec)
free(hashmap_remove(nl->ignored_serials, UINT32_TO_PTR(s->serial)));
}
}
int sd_netlink_ignore_serial(sd_netlink *nl, uint32_t serial, uint64_t timeout_usec) {
int r;
assert_return(nl, -EINVAL);
assert_return(!netlink_pid_changed(nl), -ECHILD);
assert_return(serial != 0, -EINVAL);
timeout_usec = timespan_to_timestamp(nl, timeout_usec);
NetlinkIgnoredSerial *existing = hashmap_get(nl->ignored_serials, UINT32_TO_PTR(serial));
if (existing) {
existing->timeout_usec = timeout_usec;
return 0;
}
netlink_trim_ignored_serials(nl);
_cleanup_free_ NetlinkIgnoredSerial *s = new(NetlinkIgnoredSerial, 1);
if (!s)
return -ENOMEM;
*s = (NetlinkIgnoredSerial) {
.serial = serial,
.timeout_usec = timeout_usec,
};
r = hashmap_ensure_put(&nl->ignored_serials, &trivial_hash_ops_value_free, UINT32_TO_PTR(s->serial), s);
if (r < 0)
return r;
TAKE_PTR(s);
return 0;
}
int sd_netlink_send( int sd_netlink_send(
sd_netlink *nl, sd_netlink *nl,
sd_netlink_message *message, sd_netlink_message *message,
@ -296,6 +204,7 @@ static int process_timeout(sd_netlink *nl) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
struct reply_callback *c; struct reply_callback *c;
sd_netlink_slot *slot; sd_netlink_slot *slot;
usec_t n;
int r; int r;
assert(nl); assert(nl);
@ -304,7 +213,8 @@ static int process_timeout(sd_netlink *nl) {
if (!c) if (!c)
return 0; return 0;
if (c->timeout > netlink_now(nl, CLOCK_MONOTONIC)) n = now(CLOCK_MONOTONIC);
if (c->timeout > n)
return 0; return 0;
r = message_new_synthetic_error(nl, -ETIMEDOUT, c->serial, &m); r = message_new_synthetic_error(nl, -ETIMEDOUT, c->serial, &m);
@ -427,8 +337,6 @@ static int process_running(sd_netlink *nl, sd_netlink_message **ret) {
assert(nl); assert(nl);
netlink_trim_ignored_serials(nl);
r = process_timeout(nl); r = process_timeout(nl);
if (r != 0) if (r != 0)
goto null_message; goto null_message;
@ -476,6 +384,32 @@ int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret) {
return r; return r;
} }
static usec_t timespan_to_timestamp(usec_t usec) {
static bool default_timeout_set = false;
static usec_t default_timeout;
int r;
if (usec == 0) {
if (!default_timeout_set) {
const char *e;
default_timeout_set = true;
default_timeout = NETLINK_DEFAULT_TIMEOUT_USEC;
e = secure_getenv("SYSTEMD_NETLINK_DEFAULT_TIMEOUT");
if (e) {
r = parse_sec(e, &default_timeout);
if (r < 0)
log_debug_errno(r, "sd-netlink: Failed to parse $SYSTEMD_NETLINK_DEFAULT_TIMEOUT environment variable, ignoring: %m");
}
}
usec = default_timeout;
}
return usec_add(now(CLOCK_MONOTONIC), usec);
}
static int netlink_poll(sd_netlink *nl, bool need_more, usec_t timeout_usec) { static int netlink_poll(sd_netlink *nl, bool need_more, usec_t timeout_usec) {
usec_t m = USEC_INFINITY; usec_t m = USEC_INFINITY;
int r, e; int r, e;
@ -500,7 +434,7 @@ static int netlink_poll(sd_netlink *nl, bool need_more, usec_t timeout_usec) {
if (r < 0) if (r < 0)
return r; return r;
m = usec_sub_unsigned(until, netlink_now(nl, CLOCK_MONOTONIC)); m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
} }
r = fd_wait_for_event(nl->fd, e, MIN(m, timeout_usec)); r = fd_wait_for_event(nl->fd, e, MIN(m, timeout_usec));
@ -574,7 +508,7 @@ int sd_netlink_call_async(
return r; return r;
slot->reply_callback.callback = callback; slot->reply_callback.callback = callback;
slot->reply_callback.timeout = timespan_to_timestamp(nl, usec); slot->reply_callback.timeout = timespan_to_timestamp(usec);
k = sd_netlink_send(nl, m, &slot->reply_callback.serial); k = sd_netlink_send(nl, m, &slot->reply_callback.serial);
if (k < 0) if (k < 0)
@ -615,7 +549,7 @@ int sd_netlink_read(
assert_return(nl, -EINVAL); assert_return(nl, -EINVAL);
assert_return(!netlink_pid_changed(nl), -ECHILD); assert_return(!netlink_pid_changed(nl), -ECHILD);
usec = timespan_to_timestamp(nl, timeout); usec = timespan_to_timestamp(timeout);
for (;;) { for (;;) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
@ -657,7 +591,7 @@ int sd_netlink_read(
if (usec != USEC_INFINITY) { if (usec != USEC_INFINITY) {
usec_t n; usec_t n;
n = netlink_now(nl, CLOCK_MONOTONIC); n = now(CLOCK_MONOTONIC);
if (n >= usec) if (n >= usec)
return -ETIMEDOUT; return -ETIMEDOUT;

View File

@ -6,7 +6,6 @@
#include "sd-varlink.h" #include "sd-varlink.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "constants.h"
#include "discover-image.h" #include "discover-image.h"
#include "errno-util.h" #include "errno-util.h"
#include "format-util.h" #include "format-util.h"
@ -746,8 +745,6 @@ static int manager_varlink_init_userdb(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m"); return log_error_errno(r, "Failed to allocate varlink server object: %m");
(void) sd_varlink_server_set_description(s, "varlink-userdb");
r = sd_varlink_server_add_interface(s, &vl_interface_io_systemd_UserDatabase); r = sd_varlink_server_add_interface(s, &vl_interface_io_systemd_UserDatabase);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to add UserDatabase interface to varlink server: %m"); return log_error_errno(r, "Failed to add UserDatabase interface to varlink server: %m");
@ -760,9 +757,9 @@ static int manager_varlink_init_userdb(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to register varlink methods: %m"); return log_error_errno(r, "Failed to register varlink methods: %m");
r = sd_varlink_server_listen_address(s, VARLINK_PATH_MACHINED_USERDB, 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755); r = sd_varlink_server_listen_address(s, "/run/systemd/userdb/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to varlink socket %s: %m", VARLINK_PATH_MACHINED_USERDB); return log_error_errno(r, "Failed to bind to varlink socket '/run/systemd/userdb/io.systemd.Machine': %m");
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL); r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
if (r < 0) if (r < 0)
@ -892,11 +889,9 @@ static int manager_varlink_init_resolve_hook(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind on resolve hook disconnection events: %m"); return log_error_errno(r, "Failed to bind on resolve hook disconnection events: %m");
r = sd_varlink_server_listen_address(s, VARLINK_PATH_MACHINED_RESOLVE_HOOK, r = sd_varlink_server_listen_address(s, "/run/systemd/resolve.hook/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to varlink socket %s: %m", return log_error_errno(r, "Failed to bind to varlink socket: %m");
VARLINK_PATH_MACHINED_RESOLVE_HOOK);
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL); r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
if (r < 0) if (r < 0)

View File

@ -334,9 +334,9 @@ static int acquire_managed_oom_connect(Manager *m) {
assert(m); assert(m);
assert(m->event); assert(m->event);
r = sd_varlink_connect_address(&link, VARLINK_PATH_MANAGED_OOM_SYSTEM); r = sd_varlink_connect_address(&link, VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to connect to %s: %m", VARLINK_PATH_MANAGED_OOM_SYSTEM); return log_error_errno(r, "Failed to connect to " VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM ": %m");
(void) sd_varlink_set_userdata(link, m); (void) sd_varlink_set_userdata(link, m);
(void) sd_varlink_set_description(link, "oomd"); (void) sd_varlink_set_description(link, "oomd");
@ -768,12 +768,11 @@ static int manager_varlink_init(Manager *m, int fd) {
return log_error_errno(r, "Failed to register varlink methods: %m"); return log_error_errno(r, "Failed to register varlink methods: %m");
if (fd < 0) if (fd < 0)
r = sd_varlink_server_listen_address(s, VARLINK_PATH_MANAGED_OOM_USER, 0666); r = sd_varlink_server_listen_address(s, VARLINK_ADDR_PATH_MANAGED_OOM_USER, 0666);
else else
r = sd_varlink_server_listen_fd(s, fd); r = sd_varlink_server_listen_fd(s, fd);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to varlink socket %s: %m", return log_error_errno(r, "Failed to bind to varlink socket '" VARLINK_ADDR_PATH_MANAGED_OOM_USER "': %m");
VARLINK_PATH_MANAGED_OOM_USER);
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL); r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
if (r < 0) if (r < 0)

View File

@ -807,7 +807,7 @@ static int fw_nftables_init_family(sd_netlink *nfnl, int family) {
return r; return r;
assert(msgcnt < ELEMENTSOF(messages)); assert(msgcnt < ELEMENTSOF(messages));
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS); r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
if (r < 0 && r != -EEXIST) if (r < 0 && r != -EEXIST)
return r; return r;
@ -919,7 +919,7 @@ int nft_set_element_modify_iprange(
if (r < 0) if (r < 0)
return r; return r;
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS); return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
} }
int nft_set_element_modify_ip( int nft_set_element_modify_ip(
@ -959,7 +959,7 @@ int nft_set_element_modify_ip(
if (r < 0) if (r < 0)
return r; return r;
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS); return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
} }
int nft_set_element_modify_any( int nft_set_element_modify_any(
@ -987,7 +987,7 @@ int nft_set_element_modify_any(
if (r < 0) if (r < 0)
return r; return r;
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS); return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
} }
static int af_to_nfproto(int af) { static int af_to_nfproto(int af) {
@ -1124,7 +1124,7 @@ static int fw_nftables_add_local_dnat_internal(
return r; return r;
assert(msgcnt < ELEMENTSOF(messages)); assert(msgcnt < ELEMENTSOF(messages));
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS); r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
if (r == -EOVERFLOW && af == AF_INET6) { if (r == -EOVERFLOW && af == AF_INET6) {
/* The current implementation of DNAT in systemd requires kernel's /* The current implementation of DNAT in systemd requires kernel's
* fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 (v5.8), and the older kernel returns * fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 (v5.8), and the older kernel returns

View File

@ -219,7 +219,7 @@ int journal_fork(RuntimeScope scope, char * const* units, PidRef *ret_pidref) {
"-q", "-q",
"--follow", "--follow",
"--no-pager", "--no-pager",
"--lines=0", "--lines=1",
"--synchronize-on-exit=yes"); "--synchronize-on-exit=yes");
if (!argv) if (!argv)
return log_oom_debug(); return log_oom_debug();

View File

@ -56,8 +56,6 @@ int sd_netlink_call_async(sd_netlink *nl, sd_netlink_slot **ret_slot, sd_netlink
int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeout, sd_netlink_message **ret); int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeout, sd_netlink_message **ret);
int sd_netlink_read(sd_netlink *nl, uint32_t serial, uint64_t timeout, sd_netlink_message **ret); int sd_netlink_read(sd_netlink *nl, uint32_t serial, uint64_t timeout, sd_netlink_message **ret);
int sd_netlink_ignore_serial(sd_netlink *nl, uint32_t serial, uint64_t timeout_usec);
int sd_netlink_get_events(sd_netlink *nl); int sd_netlink_get_events(sd_netlink *nl);
int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *ret); int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *ret);
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret); int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret);

View File

@ -769,32 +769,21 @@ int transfer_vacuum(
limit = instances_max - space; limit = instances_max - space;
if (t->target.type == RESOURCE_PARTITION && space != UINT64_MAX) { if (t->target.type == RESOURCE_PARTITION && space != UINT64_MAX) {
_cleanup_free_ char *patterns = NULL;
uint64_t rm, remain; uint64_t rm, remain;
patterns = strv_join(t->target.patterns, "|");
if (!patterns)
(void) log_oom_debug();
/* If we are looking at a partition table, we also have to take into account how many /* If we are looking at a partition table, we also have to take into account how many
* partition slots of the right type are available */ * partition slots of the right type are available */
if (t->target.n_empty + t->target.n_instances < 2) if (t->target.n_empty + t->target.n_instances < 2)
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC), return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
"Partition table has less than two partition slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s)%s%s%s, refusing.", "Partition table has less than two partition slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s), refusing.",
SD_ID128_FORMAT_VAL(t->target.partition_type.uuid), SD_ID128_FORMAT_VAL(t->target.partition_type.uuid),
gpt_partition_type_uuid_to_string(t->target.partition_type.uuid), gpt_partition_type_uuid_to_string(t->target.partition_type.uuid));
!isempty(patterns) ? " and matching the expected pattern '" : "",
strempty(patterns),
!isempty(patterns) ? "'" : "");
if (space > t->target.n_empty + t->target.n_instances) if (space > t->target.n_empty + t->target.n_instances)
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC), return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
"Partition table does not have enough partition slots of right type " SD_ID128_UUID_FORMAT_STR " (%s)%s%s%s for operation.", "Partition table does not have enough partition slots of right type " SD_ID128_UUID_FORMAT_STR " (%s) for operation.",
SD_ID128_FORMAT_VAL(t->target.partition_type.uuid), SD_ID128_FORMAT_VAL(t->target.partition_type.uuid),
gpt_partition_type_uuid_to_string(t->target.partition_type.uuid), gpt_partition_type_uuid_to_string(t->target.partition_type.uuid));
!isempty(patterns) ? " and matching the expected pattern '" : "",
strempty(patterns),
!isempty(patterns) ? "'" : "");
if (space == t->target.n_empty + t->target.n_instances) if (space == t->target.n_empty + t->target.n_instances)
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC), return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
"Asked to empty all partition table slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s), can't allow that. One instance must always remain.", "Asked to empty all partition table slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s), can't allow that. One instance must always remain.",

View File

@ -111,7 +111,6 @@ simple_tests += files(
'test-format-util.c', 'test-format-util.c',
'test-fs-util.c', 'test-fs-util.c',
'test-fstab-util.c', 'test-fstab-util.c',
'test-getopt.c',
'test-glob-util.c', 'test-glob-util.c',
'test-gpt.c', 'test-gpt.c',
'test-gunicode.c', 'test-gunicode.c',

View File

@ -1,5 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdlib.h>
#include <unistd.h>
#include "sd-netlink.h" #include "sd-netlink.h"
#include "firewall-util.h" #include "firewall-util.h"
@ -76,6 +79,9 @@ TEST(v4) {
static int intro(void) { static int intro(void) {
int r; int r;
if (getuid() != 0)
return log_tests_skipped("not root");
ASSERT_OK_ERRNO(setenv("SYSTEMD_FIREWALL_UTIL_NFT_TABLE_NAME", "io.systemd-test.nat", /* overwrite = */ true)); ASSERT_OK_ERRNO(setenv("SYSTEMD_FIREWALL_UTIL_NFT_TABLE_NAME", "io.systemd-test.nat", /* overwrite = */ true));
ASSERT_OK_ERRNO(setenv("SYSTEMD_FIREWALL_UTIL_DNAT_MAP_NAME", "test_map_port_ipport", /* overwrite = */ true)); ASSERT_OK_ERRNO(setenv("SYSTEMD_FIREWALL_UTIL_DNAT_MAP_NAME", "test_map_port_ipport", /* overwrite = */ true));

View File

@ -1,516 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include "strv.h"
#include "tests.h"
typedef struct Entry {
int opt;
const char *argument;
const char *nextarg;
} Entry;
static void test_getopt_long_one(
char **argv,
const char *optstring,
const struct option *longopts,
const Entry *entries,
char **remaining) {
_cleanup_free_ char *joined = strv_join(argv, ", ");
log_debug("/* %s(%s) */", __func__, joined);
_cleanup_free_ char *saved_argv0 = NULL;
ASSERT_NOT_NULL(saved_argv0 = strdup(argv[0]));
int c, argc = strv_length(argv);
size_t i = 0, n_entries = 0;
for (const Entry *e = entries; e && e->opt != 0; e++)
n_entries++;
optind = 0;
while ((c = getopt_long(argc, argv, optstring, longopts, NULL)) >= 0) {
if (c < 0x100)
log_debug("%c: %s", c, strna(optarg));
else
log_debug("0x%x: %s", (unsigned) c, strna(optarg));
ASSERT_LT(i, n_entries);
ASSERT_EQ(c, entries[i].opt);
ASSERT_STREQ(optarg, entries[i].argument);
if (entries[i].nextarg)
ASSERT_STREQ(argv[optind], entries[i].nextarg);
i++;
}
ASSERT_EQ(i, n_entries);
ASSERT_LE(optind, argc);
ASSERT_EQ(argc - optind, (int) strv_length(remaining));
for (int j = optind; j < argc; j++)
ASSERT_STREQ(argv[j], remaining[j - optind]);
ASSERT_STREQ(argv[0], saved_argv0);
}
TEST(getopt_long) {
enum {
ARG_VERSION = 0x100,
ARG_REQUIRED,
ARG_OPTIONAL,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version" , no_argument, NULL, ARG_VERSION },
{ "required1", required_argument, NULL, 'r' },
{ "required2", required_argument, NULL, ARG_REQUIRED },
{ "optional1", optional_argument, NULL, 'o' },
{ "optional2", optional_argument, NULL, ARG_OPTIONAL },
{},
};
test_getopt_long_one(STRV_MAKE("arg0"),
"hr:o::", options,
NULL,
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"--",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"--",
"string3",
"string4"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4",
"--"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"--help"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"-h"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"--help",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"-h",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"--help",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"-h",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4",
"--help"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4",
"-h"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"--required1", "reqarg1"),
"hr:o::", options,
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"-r", "reqarg1"),
"hr:o::", options,
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"-r", "reqarg1"),
"hr:o::", options,
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
STRV_MAKE("string1",
"string2"));
test_getopt_long_one(STRV_MAKE("arg0",
"--optional1=optarg1"),
"hr:o::", options,
(Entry[]) {
{ 'o', "optarg1" },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"--optional1", "string1"),
"hr:o::", options,
(Entry[]) {
{ 'o', NULL, "string1" },
{}
},
STRV_MAKE("string1"));
test_getopt_long_one(STRV_MAKE("arg0",
"-ooptarg1"),
"hr:o::", options,
(Entry[]) {
{ 'o', "optarg1" },
{}
}, NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"-o", "string1"),
"hr:o::", options,
(Entry[]) {
{ 'o', NULL, "string1" },
{}
},
STRV_MAKE("string1"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"--help",
"--version",
"string2",
"--required1", "reqarg1",
"--required2", "reqarg2",
"--required1=reqarg3",
"--required2=reqarg4",
"string3",
"--optional1", "string4",
"--optional2", "string5",
"--optional1=optarg1",
"--optional2=optarg2",
"-h",
"-r", "reqarg5",
"-rreqarg6",
"-ooptarg3",
"-o",
"string6",
"-o",
"-h",
"-o",
"--help",
"string7",
"-hooptarg4",
"-hrreqarg6",
"--",
"--help",
"--required1",
"--optional1"),
"hr:o::", options,
(Entry[]) {
{ 'h' },
{ ARG_VERSION },
{ 'r', "reqarg1" },
{ ARG_REQUIRED, "reqarg2" },
{ 'r', "reqarg3" },
{ ARG_REQUIRED, "reqarg4" },
{ 'o', NULL, "string4" },
{ ARG_OPTIONAL, NULL, "string5" },
{ 'o', "optarg1" },
{ ARG_OPTIONAL, "optarg2" },
{ 'h' },
{ 'r', "reqarg5" },
{ 'r', "reqarg6" },
{ 'o', "optarg3" },
{ 'o', NULL, "string6" },
{ 'o', NULL, "-h" },
{ 'h' },
{ 'o', NULL, "--help" },
{ 'h' },
{ 'h' },
{ 'o', "optarg4" },
{ 'h' },
{ 'r', "reqarg6" },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4",
"string5",
"string6",
"string7",
"--help",
"--required1",
"--optional1"));
}
static void test_getopt_one(
char **argv,
const char *optstring,
const Entry *entries,
char **remaining) {
_cleanup_free_ char *joined = strv_join(argv, ", ");
log_debug("/* %s(%s) */", __func__, joined);
_cleanup_free_ char *saved_argv0 = NULL;
ASSERT_NOT_NULL(saved_argv0 = strdup(argv[0]));
int c, argc = strv_length(argv);
size_t i = 0, n_entries = 0;
for (const Entry *e = entries; e && e->opt != 0; e++)
n_entries++;
optind = 0;
while ((c = getopt(argc, argv, optstring)) >= 0) {
log_debug("%c: %s", c, strna(optarg));
ASSERT_LT(i, n_entries);
ASSERT_EQ(c, entries[i].opt);
ASSERT_STREQ(optarg, entries[i].argument);
if (entries[i].nextarg)
ASSERT_STREQ(argv[optind], entries[i].nextarg);
i++;
}
ASSERT_EQ(i, n_entries);
ASSERT_LE(optind, argc);
ASSERT_EQ(argc - optind, (int) strv_length(remaining));
for (int j = optind; j < argc; j++)
ASSERT_STREQ(argv[j], remaining[j - optind]);
ASSERT_STREQ(argv[0], saved_argv0);
}
TEST(getopt) {
test_getopt_one(STRV_MAKE("arg0"),
"hr:o::",
NULL,
NULL);
test_getopt_one(STRV_MAKE("arg0",
"string1",
"string2"),
"hr:o::",
NULL,
STRV_MAKE("string1",
"string2"));
test_getopt_one(STRV_MAKE("arg0",
"-h"),
"hr:o::",
(Entry[]) {
{ 'h', NULL },
{}
},
NULL);
test_getopt_one(STRV_MAKE("arg0",
"-r", "reqarg1"),
"hr:o::",
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
NULL);
test_getopt_one(STRV_MAKE("arg0",
"string1",
"string2",
"-r", "reqarg1"),
"hr:o::",
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
STRV_MAKE("string1",
"string2"));
test_getopt_one(STRV_MAKE("arg0",
"-ooptarg1"),
"hr:o::",
(Entry[]) {
{ 'o', "optarg1" },
{}
},
NULL);
test_getopt_one(STRV_MAKE("arg0",
"-o", "string1"),
"hr:o::",
(Entry[]) {
{ 'o', NULL, "string1" },
{}
},
STRV_MAKE("string1"));
test_getopt_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"-h",
"-r", "reqarg5",
"-rreqarg6",
"-ooptarg3",
"-o",
"string6",
"-o",
"-h",
"-o",
"string7",
"-hooptarg4",
"-hrreqarg6"),
"hr:o::",
(Entry[]) {
{ 'h' },
{ 'r', "reqarg5" },
{ 'r', "reqarg6" },
{ 'o', "optarg3" },
{ 'o', NULL, "string6" },
{ 'o', NULL, "-h" },
{ 'h' },
{ 'o', NULL, "string7" },
{ 'h' },
{ 'o', "optarg4" },
{ 'h' },
{ 'r', "reqarg6" },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string6",
"string7"));
}
DEFINE_TEST_MAIN(LOG_DEBUG);