mirror of
https://github.com/systemd/systemd
synced 2026-03-26 16:54:53 +01:00
Compare commits
17 Commits
26b2085d54
...
67317e214e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67317e214e | ||
|
|
bfaf63b509 | ||
|
|
4b9cb0c391 | ||
|
|
12391431c2 | ||
|
|
9454927c76 | ||
|
|
3c85d99c79 | ||
|
|
eb98ddd8b8 | ||
|
|
d9e894ef72 | ||
|
|
53f5aa3fd2 | ||
|
|
84990e08e5 | ||
|
|
691d63dbdd | ||
|
|
ea97ca9a06 | ||
|
|
991703009e | ||
|
|
32682ba02d | ||
|
|
21eb636aaa | ||
|
|
f943ab6efb | ||
|
|
ef90afd59e |
@ -293,8 +293,10 @@
|
||||
<para>Controls enrollment of secure boot keys found on the ESP if the system is in setup mode:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>off</option></term>
|
||||
<listitem><para>No action is taken.</para>
|
||||
<term><option>if-safe</option></term>
|
||||
<listitem><para>This is the default. Same behavior as <option>manual</option>, but will try to automatically
|
||||
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>
|
||||
</varlistentry>
|
||||
@ -308,10 +310,8 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>if-safe</option></term>
|
||||
<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>
|
||||
<term><option>off</option></term>
|
||||
<listitem><para>No action is taken.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@ -392,8 +392,9 @@
|
||||
<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>
|
||||
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 whether <literal>secure-boot-enroll</literal> is set
|
||||
to force or not.</para>
|
||||
then it might be enrolled automatically depending on the execution environment and the value of the <literal>secure-boot-enroll</literal> option.
|
||||
See
|
||||
<citerefentry><refentrytitle>loader.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
||||
40
po/cs.po
40
po/cs.po
@ -2,24 +2,24 @@
|
||||
#
|
||||
# Czech translation for systemd.
|
||||
#
|
||||
# Daniel Rusek <mail@asciiwolf.com>, 2022, 2023.
|
||||
# Pavel Borecki <pavel.borecki@gmail.com>, 2023, 2024.
|
||||
# Daniel Rusek <mail@asciiwolf.com>, 2022, 2023, 2025.
|
||||
# Pavel Borecki <pavel.borecki@gmail.com>, 2023, 2024, 2025.
|
||||
# Jan Kalabza <jan.kalabza@gmail.com>, 2025.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-26 01:17+0000\n"
|
||||
"PO-Revision-Date: 2025-02-10 02:01+0000\n"
|
||||
"Last-Translator: Jan Kalabza <jan.kalabza@gmail.com>\n"
|
||||
"PO-Revision-Date: 2025-12-05 13:08+0000\n"
|
||||
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
|
||||
"Language-Team: Czech <https://translate.fedoraproject.org/projects/systemd/"
|
||||
"main/cs/>\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 5.9.2\n"
|
||||
"Plural-Forms: nplurals=3; plural="
|
||||
"(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 5.14.3\n"
|
||||
|
||||
#: src/core/org.freedesktop.systemd1.policy.in:22
|
||||
msgid "Send passphrase back to system"
|
||||
@ -120,7 +120,7 @@ msgstr "Aktualizujte svůj domovský adresář"
|
||||
|
||||
#: src/home/org.freedesktop.home1.policy:54
|
||||
msgid "Authentication is required to update your home area."
|
||||
msgstr "Pro aktualizaci domovské adresáře je nutné ověření."
|
||||
msgstr "Pro aktualizaci domovské adresáře je vyžadováno ověření."
|
||||
|
||||
#: src/home/org.freedesktop.home1.policy:63
|
||||
msgid "Resize a home area"
|
||||
@ -146,17 +146,16 @@ msgstr "Aktivovat domovskou složku"
|
||||
|
||||
#: src/home/org.freedesktop.home1.policy:84
|
||||
msgid "Authentication is required to activate a user's home area."
|
||||
msgstr "K aktivaci domovského adresáře uživatele je nutné ověření."
|
||||
msgstr "K aktivaci domovského adresáře uživatele je vyžadováno ověření."
|
||||
|
||||
#: src/home/org.freedesktop.home1.policy:93
|
||||
msgid "Manage Home Directory Signing Keys"
|
||||
msgstr ""
|
||||
msgstr "Spravovat klíče pro podepisování domovské složky"
|
||||
|
||||
#: src/home/org.freedesktop.home1.policy:94
|
||||
#, fuzzy
|
||||
msgid "Authentication is required to manage signing keys for home directories."
|
||||
msgstr ""
|
||||
"Pro správu systémových služeb nebo dalších jednotek je vyžadováno ověření."
|
||||
"Pro správu klíčů pro podepisování domovských složek je vyžadováno ověření."
|
||||
|
||||
#: src/home/pam_systemd_home.c:333
|
||||
#, c-format
|
||||
@ -882,16 +881,15 @@ msgstr ""
|
||||
"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
|
||||
#, fuzzy
|
||||
msgid "Register a local virtual machine or container"
|
||||
msgstr "Vytvoření místního virtuálního počítače nebo kontejneru"
|
||||
msgstr "Zaregistrovat lokální virtuální stroj nebo kontejner"
|
||||
|
||||
#: src/machine/org.freedesktop.machine1.policy:107
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Authentication is required to register a local virtual machine or container."
|
||||
msgstr ""
|
||||
"K vytvoření místního virtuálního počítače nebo kontejneru je nutné ověření."
|
||||
"K zaregistrování lokálního virtuálního stroje nebo kontejneru je nutné "
|
||||
"ověření."
|
||||
|
||||
#: src/machine/org.freedesktop.machine1.policy:116
|
||||
msgid "Manage local virtual machine and container images"
|
||||
@ -1115,12 +1113,11 @@ msgstr "Pro přihlášení k odběru výsledků dotazu je vyžadováno ověřen
|
||||
|
||||
#: src/resolve/org.freedesktop.resolve1.policy:154
|
||||
msgid "Subscribe to DNS configuration"
|
||||
msgstr ""
|
||||
msgstr "Přihlásit se k odběru nastavení DNS"
|
||||
|
||||
#: src/resolve/org.freedesktop.resolve1.policy:155
|
||||
#, fuzzy
|
||||
msgid "Authentication is required to subscribe to DNS configuration."
|
||||
msgstr "Pro přihlášení k odběru výsledků dotazu je vyžadováno ověření."
|
||||
msgstr "Pro přihlášení k odběru nastavení DNS je vyžadováno ověření."
|
||||
|
||||
#: src/resolve/org.freedesktop.resolve1.policy:165
|
||||
msgid "Dump cache"
|
||||
@ -1259,11 +1256,12 @@ msgid ""
|
||||
msgstr "Pro odeslání UNIX signálu procesům „$(unit)” je vyžadováno ověření."
|
||||
|
||||
#: src/core/dbus-unit.c:620
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Authentication is required to send a UNIX signal to the processes of "
|
||||
"subgroup of '$(unit)'."
|
||||
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 nebo podskupině „$(unit)” je vyžadováno "
|
||||
"ověření."
|
||||
|
||||
#: src/core/dbus-unit.c:648
|
||||
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
|
||||
|
||||
@ -59,9 +59,13 @@
|
||||
#define DEFAULT_RLIMIT_MEMLOCK (1024ULL*1024ULL*8ULL)
|
||||
|
||||
/* Path where PID1 listens for varlink subscriptions from systemd-oomd to notify of changes in ManagedOOM settings. */
|
||||
#define VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM "/run/systemd/io.systemd.ManagedOOM"
|
||||
#define VARLINK_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. */
|
||||
#define VARLINK_ADDR_PATH_MANAGED_OOM_USER "/run/systemd/oom/io.systemd.ManagedOOM"
|
||||
#define VARLINK_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 */
|
||||
#define KERNEL_BASELINE_VERSION "5.7"
|
||||
|
||||
@ -2997,9 +2997,8 @@ static void config_load_all_entries(
|
||||
|
||||
config_add_system_entries(config);
|
||||
|
||||
/* Find secure boot signing keys and autoload them if configured. Otherwise, create menu entries so
|
||||
* 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 */
|
||||
/* Using the rules defined by the `secure-boot-enroll` variable, find secure boot signing keys
|
||||
* and perform operations like autoloading them or create menu entries if configured. */
|
||||
(void) secure_boot_discover_keys(config, root_dir);
|
||||
|
||||
if (config->n_entries == 0)
|
||||
|
||||
@ -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);
|
||||
|
||||
log_debug("Reconnecting to %s", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
|
||||
log_debug("Reconnecting to %s", VARLINK_PATH_MANAGED_OOM_USER);
|
||||
|
||||
r = manager_varlink_managed_oom_connect(m);
|
||||
if (r <= 0)
|
||||
@ -194,7 +194,7 @@ static int manager_varlink_managed_oom_connect(Manager *m) {
|
||||
if (MANAGER_IS_TEST_RUN(m))
|
||||
return 0;
|
||||
|
||||
r = sd_varlink_connect_address(&link, VARLINK_ADDR_PATH_MANAGED_OOM_USER);
|
||||
r = sd_varlink_connect_address(&link, VARLINK_PATH_MANAGED_OOM_USER);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (ERRNO_IS_NEG_DISCONNECT(r)) {
|
||||
@ -202,7 +202,7 @@ static int manager_varlink_managed_oom_connect(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to '%s': %m", VARLINK_ADDR_PATH_MANAGED_OOM_USER);
|
||||
return log_error_errno(r, "Failed to connect to '%s': %m", VARLINK_PATH_MANAGED_OOM_USER);
|
||||
|
||||
sd_varlink_set_userdata(link, m);
|
||||
|
||||
@ -435,7 +435,7 @@ static int manager_varlink_init_system(Manager *m) {
|
||||
if (!MANAGER_IS_TEST_RUN(m)) {
|
||||
FOREACH_STRING(address,
|
||||
"/run/systemd/userdb/io.systemd.DynamicUser",
|
||||
VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM,
|
||||
VARLINK_PATH_MANAGED_OOM_SYSTEM,
|
||||
"/run/systemd/io.systemd.Manager") {
|
||||
/* We might have got sockets through deserialization. Do not bind to them twice. */
|
||||
if (!fresh && varlink_server_contains_socket(m->varlink_server, address))
|
||||
|
||||
29
src/include/musl/getopt.h
Normal file
29
src/include/musl/getopt.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* 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)
|
||||
12
src/include/musl/unistd.h
Normal file
12
src/include/musl/unistd.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* 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)
|
||||
@ -362,7 +362,9 @@ static int on_first_event(sd_event_source *s, void *userdata) {
|
||||
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");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -472,11 +474,9 @@ static int setup_event(Context *c, int fd) {
|
||||
else if (r < 0)
|
||||
return log_error_errno(r, "Failed to add io event source for stdout: %m");
|
||||
|
||||
if (arg_lines != 0 || arg_since_set) {
|
||||
r = sd_event_add_defer(e, NULL, on_first_event, c);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add defer event source: %m");
|
||||
}
|
||||
r = sd_event_add_defer(e, NULL, on_first_event, c);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add defer event source: %m");
|
||||
|
||||
c->event = TAKE_PTR(e);
|
||||
return 0;
|
||||
@ -583,6 +583,7 @@ int action_show(char **matches) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Setup is done, we'll start processing data. */
|
||||
(void) sd_notify(/* unset_environment= */ false, "READY=1");
|
||||
|
||||
r = show(&c);
|
||||
|
||||
100
src/libc/musl/getopt.c
Normal file
100
src/libc/musl/getopt.c
Normal file
@ -0,0 +1,100 @@
|
||||
/* 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);
|
||||
}
|
||||
@ -5,6 +5,7 @@ if get_option('libc') != 'musl'
|
||||
endif
|
||||
|
||||
libc_wrapper_sources += files(
|
||||
'getopt.c',
|
||||
'printf.c',
|
||||
'stdio.c',
|
||||
'stdlib.c',
|
||||
|
||||
@ -505,13 +505,14 @@ static int pid_notify_with_fds_internal(
|
||||
if (r == -EPROTO)
|
||||
r = socket_address_parse_vsock(&address, e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_debug_errno(r, "Address NOTIFY_SOCKET='%s' is neither UNIX nor VSOCK, refusing: %m", e);
|
||||
msghdr.msg_namelen = address.size;
|
||||
|
||||
/* If we didn't get an address (which is a normal pattern when specifying VSOCK tuples) error out,
|
||||
* we always require a specific CID. */
|
||||
if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY)
|
||||
return -EINVAL;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"VSOCK address in NOTIFY_SOCKET='%s' doesn't have CID, refusing.", e);
|
||||
|
||||
type = address.type == 0 ? SOCK_DGRAM : address.type;
|
||||
|
||||
@ -610,7 +611,8 @@ static int pid_notify_with_fds_internal(
|
||||
} else {
|
||||
/* 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))
|
||||
return -EIO;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(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. */
|
||||
msghdr.msg_control = NULL;
|
||||
@ -631,6 +633,7 @@ static int pid_notify_with_fds_internal(
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -55,6 +55,11 @@ typedef struct 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 {
|
||||
unsigned n_ref;
|
||||
|
||||
@ -78,6 +83,7 @@ typedef struct sd_netlink {
|
||||
bool processing:1;
|
||||
|
||||
uint32_t serial;
|
||||
Hashmap *ignored_serials;
|
||||
|
||||
struct Prioq *reply_callbacks_prioq;
|
||||
Hashmap *reply_callbacks;
|
||||
@ -181,8 +187,7 @@ int sd_nfnl_call_batch(
|
||||
sd_netlink *nfnl,
|
||||
sd_netlink_message **messages,
|
||||
size_t n_messages,
|
||||
uint64_t usec,
|
||||
sd_netlink_message ***ret_messages);
|
||||
uint64_t usec);
|
||||
int sd_nfnl_message_new(
|
||||
sd_netlink *nfnl,
|
||||
sd_netlink_message **ret,
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "netlink-internal.h"
|
||||
#include "netlink-util.h"
|
||||
@ -119,7 +118,7 @@ int sd_nfnl_send_batch(
|
||||
return -ENOMEM;
|
||||
|
||||
if (ret_serials) {
|
||||
serials = new(uint32_t, n_messages);
|
||||
serials = new(uint32_t, n_messages + 2);
|
||||
if (!serials)
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -133,6 +132,9 @@ int sd_nfnl_send_batch(
|
||||
return r;
|
||||
|
||||
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);
|
||||
|
||||
for (size_t i = 0; i < n_messages; i++) {
|
||||
@ -147,7 +149,7 @@ int sd_nfnl_send_batch(
|
||||
|
||||
netlink_seal_message(nfnl, messages[i]);
|
||||
if (serials)
|
||||
serials[i] = message_get_serial(messages[i]);
|
||||
serials[c] = message_get_serial(messages[i]);
|
||||
|
||||
/* It seems that the kernel accepts an arbitrary number. Let's set the lower 16 bits of the
|
||||
* serial of the first message. */
|
||||
@ -161,6 +163,9 @@ int sd_nfnl_send_batch(
|
||||
return r;
|
||||
|
||||
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);
|
||||
|
||||
assert(c == n_messages + 2);
|
||||
@ -178,10 +183,8 @@ int sd_nfnl_call_batch(
|
||||
sd_netlink *nfnl,
|
||||
sd_netlink_message **messages,
|
||||
size_t n_messages,
|
||||
uint64_t usec,
|
||||
sd_netlink_message ***ret_messages) {
|
||||
uint64_t usec) {
|
||||
|
||||
_cleanup_free_ sd_netlink_message **replies = NULL;
|
||||
_cleanup_free_ uint32_t *serials = NULL;
|
||||
int r;
|
||||
|
||||
@ -190,26 +193,40 @@ int sd_nfnl_call_batch(
|
||||
assert_return(messages, -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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (size_t i = 0; i < n_messages; i++)
|
||||
RET_GATHER(r,
|
||||
sd_netlink_read(nfnl, serials[i], usec, ret_messages ? replies + i : NULL));
|
||||
if (r < 0)
|
||||
return r;
|
||||
for (size_t i = 1; i <= n_messages; i++) {
|
||||
/* If we have received an error, kernel may not send replies for later messages. Let's ignore
|
||||
* remaining replies. */
|
||||
if (r < 0) {
|
||||
(void) sd_netlink_ignore_serial(nfnl, serials[i], usec);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret_messages)
|
||||
*ret_messages = TAKE_PTR(replies);
|
||||
r = sd_netlink_read(nfnl, serials[i], usec, /* ret= */ NULL);
|
||||
if (r != -ETIMEDOUT)
|
||||
continue;
|
||||
|
||||
return 0;
|
||||
/* The kernel returns some errors, e.g. unprivileged, to the BATCH_BEGIN. Hence, if we have
|
||||
* 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(
|
||||
|
||||
@ -222,6 +222,16 @@ static int netlink_queue_received_message(sd_netlink *nl, sd_netlink_message *m)
|
||||
assert(nl);
|
||||
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)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS),
|
||||
"sd-netlink: exhausted the read queue size (%d)", NETLINK_RQUEUE_MAX);
|
||||
@ -235,7 +245,6 @@ static int netlink_queue_received_message(sd_netlink *nl, sd_netlink_message *m)
|
||||
if (sd_netlink_message_is_broadcast(m))
|
||||
return 0;
|
||||
|
||||
serial = message_get_serial(m);
|
||||
if (serial == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
@ -126,6 +126,8 @@ static sd_netlink *netlink_free(sd_netlink *nl) {
|
||||
|
||||
assert(nl);
|
||||
|
||||
hashmap_free(nl->ignored_serials);
|
||||
|
||||
ordered_set_free(nl->rqueue);
|
||||
hashmap_free(nl->rqueue_by_serial);
|
||||
hashmap_free(nl->rqueue_partial_by_serial);
|
||||
@ -152,6 +154,96 @@ static sd_netlink *netlink_free(sd_netlink *nl) {
|
||||
|
||||
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(
|
||||
sd_netlink *nl,
|
||||
sd_netlink_message *message,
|
||||
@ -204,7 +296,6 @@ static int process_timeout(sd_netlink *nl) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
struct reply_callback *c;
|
||||
sd_netlink_slot *slot;
|
||||
usec_t n;
|
||||
int r;
|
||||
|
||||
assert(nl);
|
||||
@ -213,8 +304,7 @@ static int process_timeout(sd_netlink *nl) {
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
n = now(CLOCK_MONOTONIC);
|
||||
if (c->timeout > n)
|
||||
if (c->timeout > netlink_now(nl, CLOCK_MONOTONIC))
|
||||
return 0;
|
||||
|
||||
r = message_new_synthetic_error(nl, -ETIMEDOUT, c->serial, &m);
|
||||
@ -337,6 +427,8 @@ static int process_running(sd_netlink *nl, sd_netlink_message **ret) {
|
||||
|
||||
assert(nl);
|
||||
|
||||
netlink_trim_ignored_serials(nl);
|
||||
|
||||
r = process_timeout(nl);
|
||||
if (r != 0)
|
||||
goto null_message;
|
||||
@ -384,32 +476,6 @@ int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret) {
|
||||
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) {
|
||||
usec_t m = USEC_INFINITY;
|
||||
int r, e;
|
||||
@ -434,7 +500,7 @@ static int netlink_poll(sd_netlink *nl, bool need_more, usec_t timeout_usec) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
|
||||
m = usec_sub_unsigned(until, netlink_now(nl, CLOCK_MONOTONIC));
|
||||
}
|
||||
|
||||
r = fd_wait_for_event(nl->fd, e, MIN(m, timeout_usec));
|
||||
@ -508,7 +574,7 @@ int sd_netlink_call_async(
|
||||
return r;
|
||||
|
||||
slot->reply_callback.callback = callback;
|
||||
slot->reply_callback.timeout = timespan_to_timestamp(usec);
|
||||
slot->reply_callback.timeout = timespan_to_timestamp(nl, usec);
|
||||
|
||||
k = sd_netlink_send(nl, m, &slot->reply_callback.serial);
|
||||
if (k < 0)
|
||||
@ -549,7 +615,7 @@ int sd_netlink_read(
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
usec = timespan_to_timestamp(timeout);
|
||||
usec = timespan_to_timestamp(nl, timeout);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
@ -591,7 +657,7 @@ int sd_netlink_read(
|
||||
if (usec != USEC_INFINITY) {
|
||||
usec_t n;
|
||||
|
||||
n = now(CLOCK_MONOTONIC);
|
||||
n = netlink_now(nl, CLOCK_MONOTONIC);
|
||||
if (n >= usec)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "constants.h"
|
||||
#include "discover-image.h"
|
||||
#include "errno-util.h"
|
||||
#include "format-util.h"
|
||||
@ -745,6 +746,8 @@ static int manager_varlink_init_userdb(Manager *m) {
|
||||
if (r < 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add UserDatabase interface to varlink server: %m");
|
||||
@ -757,9 +760,9 @@ static int manager_varlink_init_userdb(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register varlink methods: %m");
|
||||
|
||||
r = sd_varlink_server_listen_address(s, "/run/systemd/userdb/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
|
||||
r = sd_varlink_server_listen_address(s, VARLINK_PATH_MACHINED_USERDB, 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to varlink socket '/run/systemd/userdb/io.systemd.Machine': %m");
|
||||
return log_error_errno(r, "Failed to bind to varlink socket %s: %m", VARLINK_PATH_MACHINED_USERDB);
|
||||
|
||||
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
|
||||
if (r < 0)
|
||||
@ -889,9 +892,11 @@ static int manager_varlink_init_resolve_hook(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind on resolve hook disconnection events: %m");
|
||||
|
||||
r = sd_varlink_server_listen_address(s, "/run/systemd/resolve.hook/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
|
||||
r = sd_varlink_server_listen_address(s, VARLINK_PATH_MACHINED_RESOLVE_HOOK,
|
||||
0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to varlink socket: %m");
|
||||
return log_error_errno(r, "Failed to bind to varlink socket %s: %m",
|
||||
VARLINK_PATH_MACHINED_RESOLVE_HOOK);
|
||||
|
||||
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
|
||||
if (r < 0)
|
||||
|
||||
@ -334,9 +334,9 @@ static int acquire_managed_oom_connect(Manager *m) {
|
||||
assert(m);
|
||||
assert(m->event);
|
||||
|
||||
r = sd_varlink_connect_address(&link, VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM);
|
||||
r = sd_varlink_connect_address(&link, VARLINK_PATH_MANAGED_OOM_SYSTEM);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to " VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM ": %m");
|
||||
return log_error_errno(r, "Failed to connect to %s: %m", VARLINK_PATH_MANAGED_OOM_SYSTEM);
|
||||
|
||||
(void) sd_varlink_set_userdata(link, m);
|
||||
(void) sd_varlink_set_description(link, "oomd");
|
||||
@ -768,11 +768,12 @@ static int manager_varlink_init(Manager *m, int fd) {
|
||||
return log_error_errno(r, "Failed to register varlink methods: %m");
|
||||
|
||||
if (fd < 0)
|
||||
r = sd_varlink_server_listen_address(s, VARLINK_ADDR_PATH_MANAGED_OOM_USER, 0666);
|
||||
r = sd_varlink_server_listen_address(s, VARLINK_PATH_MANAGED_OOM_USER, 0666);
|
||||
else
|
||||
r = sd_varlink_server_listen_fd(s, fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to varlink socket '" VARLINK_ADDR_PATH_MANAGED_OOM_USER "': %m");
|
||||
return log_error_errno(r, "Failed to bind to varlink socket %s: %m",
|
||||
VARLINK_PATH_MANAGED_OOM_USER);
|
||||
|
||||
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
|
||||
if (r < 0)
|
||||
|
||||
@ -807,7 +807,7 @@ static int fw_nftables_init_family(sd_netlink *nfnl, int family) {
|
||||
return r;
|
||||
|
||||
assert(msgcnt < ELEMENTSOF(messages));
|
||||
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
|
||||
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return r;
|
||||
|
||||
@ -919,7 +919,7 @@ int nft_set_element_modify_iprange(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
|
||||
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS);
|
||||
}
|
||||
|
||||
int nft_set_element_modify_ip(
|
||||
@ -959,7 +959,7 @@ int nft_set_element_modify_ip(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
|
||||
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS);
|
||||
}
|
||||
|
||||
int nft_set_element_modify_any(
|
||||
@ -987,7 +987,7 @@ int nft_set_element_modify_any(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
|
||||
return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS);
|
||||
}
|
||||
|
||||
static int af_to_nfproto(int af) {
|
||||
@ -1124,7 +1124,7 @@ static int fw_nftables_add_local_dnat_internal(
|
||||
return r;
|
||||
|
||||
assert(msgcnt < ELEMENTSOF(messages));
|
||||
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
|
||||
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS);
|
||||
if (r == -EOVERFLOW && af == AF_INET6) {
|
||||
/* The current implementation of DNAT in systemd requires kernel's
|
||||
* fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 (v5.8), and the older kernel returns
|
||||
|
||||
@ -219,7 +219,7 @@ int journal_fork(RuntimeScope scope, char * const* units, PidRef *ret_pidref) {
|
||||
"-q",
|
||||
"--follow",
|
||||
"--no-pager",
|
||||
"--lines=1",
|
||||
"--lines=0",
|
||||
"--synchronize-on-exit=yes");
|
||||
if (!argv)
|
||||
return log_oom_debug();
|
||||
|
||||
@ -56,6 +56,8 @@ 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_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_timeout(sd_netlink *nl, uint64_t *ret);
|
||||
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret);
|
||||
|
||||
@ -769,21 +769,32 @@ int transfer_vacuum(
|
||||
limit = instances_max - space;
|
||||
|
||||
if (t->target.type == RESOURCE_PARTITION && space != UINT64_MAX) {
|
||||
_cleanup_free_ char *patterns = NULL;
|
||||
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
|
||||
* partition slots of the right type are available */
|
||||
|
||||
if (t->target.n_empty + t->target.n_instances < 2)
|
||||
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), refusing.",
|
||||
"Partition table has less than two partition slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s)%s%s%s, refusing.",
|
||||
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)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
|
||||
"Partition table does not have enough partition slots of right type " SD_ID128_UUID_FORMAT_STR " (%s) for operation.",
|
||||
"Partition table does not have enough partition slots of right type " SD_ID128_UUID_FORMAT_STR " (%s)%s%s%s for operation.",
|
||||
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)
|
||||
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.",
|
||||
|
||||
@ -111,6 +111,7 @@ simple_tests += files(
|
||||
'test-format-util.c',
|
||||
'test-fs-util.c',
|
||||
'test-fstab-util.c',
|
||||
'test-getopt.c',
|
||||
'test-glob-util.c',
|
||||
'test-gpt.c',
|
||||
'test-gunicode.c',
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "firewall-util.h"
|
||||
@ -79,9 +76,6 @@ TEST(v4) {
|
||||
static int intro(void) {
|
||||
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_DNAT_MAP_NAME", "test_map_port_ipport", /* overwrite = */ true));
|
||||
|
||||
|
||||
516
src/test/test-getopt.c
Normal file
516
src/test/test-getopt.c
Normal file
@ -0,0 +1,516 @@
|
||||
/* 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);
|
||||
Loading…
x
Reference in New Issue
Block a user