1
0
mirror of https://github.com/systemd/systemd synced 2025-11-21 09:44:44 +01:00

Compare commits

..

18 Commits

Author SHA1 Message Date
Lennart Poettering
9bb47f9ce9 bootspec: also process uki-url boot loader spec field
Let's also add support for "uki-url", which was added at the same time to
the spec as "uki".

Follow-up for: 4a94a1b83f8857b906bc7924b3f853768b5499b5
2025-10-06 16:12:27 +02:00
Lennart Poettering
e4201d0a0e
sysctl: support reading configuration from stdin and command line arguments (#39219)
This makes systemd-sysctl support following syntax, like
systemd-sysusers and systemd-tmpfiles:
```sh
$ /usr/lib/systemd/systemd-sysctl --inline 'foo.bar=42'
$ /usr/lib/systemd/systemd-sysctl - <<EOF
foo.bar=42
EOF
```
2025-10-06 16:12:11 +02:00
Antonio Alvarez Feijoo
13abd21c9f mute-console: remove unimplemented option
```
$ build/systemd-mute-console -q
Code should not be reached at src/mute-console/mute-console.c:103, function parse_argv(). Aborting. 💥
Aborted (core dumped)
```
2025-10-06 16:11:39 +02:00
Daan De Meyer
f0a1b3c183 copilot: Tell the AI to be thorough
At least when doing a local review, asking it to be thorough results
in a lot more comments on coding style violation so let's add such an
instruction to the global instructions.
2025-10-06 20:06:03 +09:00
Daan De Meyer
f228115a69 docs: Mention newline requirement for multi-line function decl 2025-10-06 20:06:03 +09:00
Mike Yuan
03bdf74dcf
timesync: several cleanups (#39220)
Prompted by the logs provided at
https://github.com/systemd/systemd/issues/36498#issuecomment-3369227155.
2025-10-06 12:16:47 +02:00
Yu Watanabe
2de03c8e8b test: add test cases for sysctl reading configuration from stdin or positional arguments 2025-10-06 04:55:25 +09:00
Yu Watanabe
3cc725ca6b timesync: assume link NTP servers are unchanged on error and no servers registered yet
This also silences annoying debug message when networkd is not running,
in which case sd_network_get_ntp() returns -ENOENT.
2025-10-06 04:49:53 +09:00
Yu Watanabe
a6b5e24746 timesync: drop redundant space 2025-10-06 04:49:53 +09:00
Yu Watanabe
ff7a3522df sd-bus: silence spurious debugging log message 2025-10-06 04:49:53 +09:00
Yu Watanabe
862b61a3a1 test: merge TEST-76-SYSCTL into TEST-87-AUX-UTILS-VM 2025-10-06 03:26:28 +09:00
Yu Watanabe
ef6aa2351e sysctl: add --inline option
This maybe useful to apply a simple configuration without creating conf
file.
2025-10-06 03:17:23 +09:00
Yu Watanabe
483de0e76b sysctl: port parse_file() over conf_file_read()
Then, systemd-sysctl can also support stdin and relative paths, like
systemd-sysusers and systemd-tmpfiles do.
2025-10-06 03:05:59 +09:00
Yu Watanabe
abb7a04361 sysctl: assorted coding style cleanups 2025-10-06 02:55:53 +09:00
Yu Watanabe
a81259051c sysctl: shorten code a bit 2025-10-06 02:41:15 +09:00
Yu Watanabe
b65ddc64e0 sysctl: propagate failures in parsing credential files
We already propagate failures in parsing conf files in usual places, or
given by command arguments. Let's make the behavior consistent.
2025-10-06 02:30:28 +09:00
Yu Watanabe
e134b7fdd2 sysctl: prettify help message 2025-10-06 02:30:28 +09:00
Yu Watanabe
95c71c8f6e sysctl: add missing help entry for --strict
Follow-up for e88748c17e58aad6818e64fd3071de011808165e.
2025-10-06 02:30:28 +09:00
13 changed files with 219 additions and 170 deletions

View File

@ -21,6 +21,7 @@ Include any other files from the [documentation](../docs) in the context as need
- Frame comments as questions
- Always consider you may be wrong
- Do not argue with contributors, assume they are right unless you are very confident in your deduction
- Be extremely thorough. Every single separate coding style violation should be reported
## Testing Expectations

View File

@ -37,7 +37,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later
int a, b, c;
```
(i.e. use double indentation — 16 spaces — for the parameter list.)
(i.e. use double indentation — 16 spaces — for the parameter list and leave a
newline between the function declaration and the first variable declaration.)
- Try to write this:

View File

@ -42,8 +42,12 @@
<para>When invoked with no arguments, <command>/usr/lib/systemd/systemd-sysctl</command> applies
all directives from configuration files listed in
<citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
If one or more filenames are passed on the command line, only the directives in these files are
applied.</para>
When invoked with positional arguments, the configuration specified by the command line arguments is
executed. If the string <literal>-</literal> is specified instead of a filename, the configuration is
read from standard input. If the argument is a file name (without any slashes), all configuration
directories are searched for a matching file and the file found that has the highest priority is
executed. If the argument is a path, that file is used directly without searching the configuration
directories for any other matching file.</para>
<para>In addition, <option>--prefix=</option> option may be used to limit which sysctl
settings are applied.</para>
@ -77,6 +81,14 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>--inline</option></term>
<listitem><para>Treat each positional argument as a separate configuration line instead of a file
name.</para>
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="cat-config" />
<xi:include href="standard-options.xml" xpointer="tldr" />
<xi:include href="standard-options.xml" xpointer="no-pager" />

View File

@ -886,16 +886,16 @@ static int bus_socket_inotify_setup(sd_bus *b) {
}
wd = inotify_add_watch(b->inotify_fd, prefix, IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO|IN_DONT_FOLLOW);
log_debug("Added inotify watch for %s on bus %s: %i", prefix, strna(b->description), wd);
if (wd < 0) {
if (IN_SET(errno, ENOENT, ELOOP))
break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */
r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", empty_to_root(prefix));
goto fail;
} else
} else {
log_debug("Added inotify watch %i for %s on bus %s.", wd, prefix, strna(b->description));
new_watches[n++] = wd;
}
/* Check if this is possibly a symlink. If so, let's follow it and watch it too. */
r = readlink_malloc(prefix, &destination);

View File

@ -72,7 +72,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "hq", options, NULL)) >= 0) {
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
switch (c) {

View File

@ -94,6 +94,7 @@ static void boot_entry_free(BootEntry *entry) {
free(entry->kernel);
free(entry->efi);
free(entry->uki);
free(entry->uki_url);
strv_free(entry->initrd);
free(entry->device_tree);
strv_free(entry->device_tree_overlay);
@ -406,6 +407,8 @@ static int boot_entry_load_type1(
r = parse_path_one(tmp.path, line, field, &tmp.efi, p);
else if (streq(field, "uki"))
r = parse_path_one(tmp.path, line, field, &tmp.uki, p);
else if (streq(field, "uki-url"))
r = free_and_strdup(&tmp.uki_url, p);
else if (streq(field, "profile"))
r = safe_atou_full(p, 10, &tmp.profile);
else if (streq(field, "initrd"))
@ -1905,6 +1908,8 @@ int show_boot_entry(
boot_entry_file_list("efi", e->root, e->efi, &status);
if (e->uki)
boot_entry_file_list("uki", e->root, e->uki, &status);
if (e->uki_url)
printf(" uki-url: %s\n", e->uki_url);
if (e->profile != UINT_MAX)
printf(" profile: %u\n", e->profile);
@ -1969,6 +1974,7 @@ int boot_entry_to_json(const BootConfig *c, size_t i, sd_json_variant **ret) {
SD_JSON_BUILD_PAIR_CONDITION(!!e->kernel, "linux", SD_JSON_BUILD_STRING(e->kernel)),
SD_JSON_BUILD_PAIR_CONDITION(!!e->efi, "efi", SD_JSON_BUILD_STRING(e->efi)),
SD_JSON_BUILD_PAIR_CONDITION(!!e->uki, "uki", SD_JSON_BUILD_STRING(e->uki)),
SD_JSON_BUILD_PAIR_CONDITION(!!e->uki_url, "ukiUrl", SD_JSON_BUILD_STRING(e->uki_url)),
SD_JSON_BUILD_PAIR_CONDITION(e->profile != UINT_MAX, "profile", SD_JSON_BUILD_UNSIGNED(e->profile)),
SD_JSON_BUILD_PAIR_CONDITION(!strv_isempty(e->initrd), "initrd", SD_JSON_BUILD_STRV(e->initrd)));
if (r < 0)

View File

@ -51,6 +51,7 @@ typedef struct BootEntry {
char *kernel; /* linux is #defined to 1, yikes! */
char *efi;
char *uki;
char *uki_url;
char **initrd;
char *device_tree;
char **device_tree_overlay;

View File

@ -26,6 +26,7 @@
static char **arg_prefixes = NULL;
static CatFlags arg_cat_flags = CAT_CONFIG_OFF;
static bool arg_strict = false;
static bool arg_inline = false;
static PagerFlags arg_pager_flags = 0;
STATIC_DESTRUCTOR_REGISTER(arg_prefixes, strv_freep);
@ -36,7 +37,7 @@ typedef struct Option {
bool ignore_failure;
} Option;
static Option *option_free(Option *o) {
static Option* option_free(Option *o) {
if (!o)
return NULL;
@ -47,7 +48,10 @@ static Option *option_free(Option *o) {
}
DEFINE_TRIVIAL_CLEANUP_FUNC(Option*, option_free);
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(option_hash_ops, char, string_hash_func, string_compare_func, Option, option_free);
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
option_hash_ops,
char, string_hash_func, string_compare_func,
Option, option_free);
static bool test_prefix(const char *p) {
if (strv_isempty(arg_prefixes))
@ -56,7 +60,7 @@ static bool test_prefix(const char *p) {
return path_startswith_strv(p, arg_prefixes);
}
static Option *option_new(
static Option* option_new(
const char *key,
const char *value,
bool ignore_failure) {
@ -155,14 +159,13 @@ static int apply_glob_option_with_prefix(OrderedHashmap *sysctl_options, Option
if (option->ignore_failure || ERRNO_IS_PRIVILEGE(r)) {
log_debug_errno(r, "Failed to resolve glob '%s', ignoring: %m", option->key);
return 0;
} else
return log_error_errno(r, "Couldn't resolve glob '%s': %m", option->key);
}
return log_error_errno(r, "Couldn't resolve glob '%s': %m", option->key);
}
STRV_FOREACH(s, paths) {
const char *key;
assert_se(key = path_startswith(*s, "/proc/sys"));
const char *key = ASSERT_SE_PTR(path_startswith(*s, "/proc/sys"));
if (ordered_hashmap_contains(sysctl_options, key)) {
log_debug("Not setting %s (explicit setting exists).", key);
@ -212,100 +215,79 @@ static int apply_all(OrderedHashmap *sysctl_options) {
return r;
}
static int parse_file(OrderedHashmap **sysctl_options, const char *path, bool ignore_enoent) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *pp = NULL;
unsigned c = 0;
static int parse_line(const char *fname, unsigned line, const char *buffer, bool *invalid_config, void *userdata) {
OrderedHashmap **sysctl_options = ASSERT_PTR(userdata);
_cleanup_free_ char *k = NULL, *v = NULL;
bool ignore_failure = false;
int r;
assert(path);
r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("sysctl.d"), &f, &pp);
if (r < 0) {
if (ignore_enoent && r == -ENOENT)
return 0;
return log_error_errno(r, "Failed to open file '%s', ignoring: %m", path);
}
log_debug("Parsing %s", pp);
for (;;) {
_cleanup_(option_freep) Option *new_option = NULL;
_cleanup_free_ char *l = NULL;
bool ignore_failure = false;
Option *existing;
char *value;
int k;
k = read_stripped_line(f, LONG_LINE_MAX, &l);
if (k == 0)
break;
if (k < 0)
return log_error_errno(k, "Failed to read file '%s', ignoring: %m", pp);
c++;
if (isempty(l))
continue;
if (strchr(COMMENTS, l[0]))
continue;
char *p = l;
value = strchr(p, '=');
if (value) {
if (p[0] == '-') {
ignore_failure = true;
p++;
}
*value = 0;
value++;
value = strstrip(value);
} else {
if (p[0] == '-')
/* We have a "negative match" option. Let's continue with value==NULL. */
p++;
else {
log_syntax(NULL, LOG_WARNING, pp, c, 0,
"Line is not an assignment, ignoring: %s", p);
if (r == 0)
r = -EINVAL;
continue;
}
const char *eq = strchr(buffer, '=');
if (eq) {
if (buffer[0] == '-') {
ignore_failure = true;
buffer++;
}
p = strstrip(p);
p = sysctl_normalize(p);
/* We can't filter out globs at this point, we'll need to do that later. */
if (!string_is_glob(p) &&
!test_prefix(p))
continue;
existing = ordered_hashmap_get(*sysctl_options, p);
if (existing) {
if (streq_ptr(value, existing->value)) {
existing->ignore_failure = existing->ignore_failure || ignore_failure;
continue;
}
log_debug("Overwriting earlier assignment of %s at '%s:%u'.", p, pp, c);
option_free(ordered_hashmap_remove(*sysctl_options, p));
}
new_option = option_new(p, value, ignore_failure);
if (!new_option)
k = strndup(buffer, eq - buffer);
if (!k)
return log_oom();
k = ordered_hashmap_ensure_put(sysctl_options, &option_hash_ops, new_option->key, new_option);
if (k < 0)
return log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", p);
v = strdup(eq + 1);
if (!v)
return log_oom();
TAKE_PTR(new_option);
} else {
if (buffer[0] == '-')
/* We have a "negative match" option. Let's continue with value==NULL. */
buffer++;
else
return log_syntax(NULL, LOG_WARNING, fname, line, SYNTHETIC_ERRNO(EINVAL),
"Line is not an assignment, ignoring: %s", buffer);
k = strdup(buffer);
if (!k)
return log_oom();
}
return r;
const char *key = sysctl_normalize(strstrip(k)), *value = strstrip(v);
/* We can't filter out globs at this point, we'll need to do that later. */
if (!string_is_glob(key) && !test_prefix(key))
return 0;
Option *existing = ordered_hashmap_get(*sysctl_options, key);
if (existing) {
if (streq_ptr(value, existing->value)) {
existing->ignore_failure = existing->ignore_failure || ignore_failure;
return 0;
}
log_syntax(NULL, LOG_DEBUG, fname, line, 0,
"Overwriting earlier assignment of '%s'.", key);
option_free(ordered_hashmap_remove(*sysctl_options, key));
}
_cleanup_(option_freep) Option *option = option_new(key, value, ignore_failure);
if (!option)
return log_oom();
r = ordered_hashmap_ensure_put(sysctl_options, &option_hash_ops, option->key, option);
if (r < 0)
return log_error_errno(r, "Failed to add sysctl variable '%s' to hashmap: %m", key);
TAKE_PTR(option);
return 0;
}
static int parse_file(OrderedHashmap **sysctl_options, const char *path, bool ignore_enoent) {
return conf_file_read(
/* root = */ NULL,
(const char**) CONF_PATHS_STRV("sysctl.d"),
path,
parse_line,
sysctl_options,
ignore_enoent,
/* invalid_config = */ NULL);
}
static int read_credential_lines(OrderedHashmap **sysctl_options) {
@ -323,8 +305,7 @@ static int read_credential_lines(OrderedHashmap **sysctl_options) {
if (!j)
return log_oom();
(void) parse_file(sysctl_options, j, /* ignore_enoent= */ true);
return 0;
return parse_file(sysctl_options, j, /* ignore_enoent= */ true);
}
static int cat_config(char **files) {
@ -341,16 +322,23 @@ static int help(void) {
if (r < 0)
return log_oom();
printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
"Applies kernel sysctl settings.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
printf("%1$s [OPTIONS...] [CONFIGURATION FILE...]\n"
"\n%2$sApplies kernel sysctl settings.%4$s\n"
"\n%3$sCommands:%4$s\n"
" --cat-config Show configuration files\n"
" --tldr Show non-comment parts of configuration\n"
" -h --help Show this help\n"
" --version Show package version\n"
"\n%3$sOptions:%4$s\n"
" --prefix=PATH Only apply rules with the specified prefix\n"
" --no-pager Do not pipe output into a pager\n"
"\nSee the %s for details.\n",
" --strict Fail on any kind of failures\n"
" --inline Treat arguments as configuration lines\n"
"\nSee the %5$s for details.\n",
program_invocation_short_name,
ansi_highlight(),
ansi_underline(),
ansi_normal(),
link);
return 0;
@ -365,6 +353,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_PREFIX,
ARG_NO_PAGER,
ARG_STRICT,
ARG_INLINE,
};
static const struct option options[] = {
@ -375,6 +364,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "prefix", required_argument, NULL, ARG_PREFIX },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "strict", no_argument, NULL, ARG_STRICT },
{ "inline", no_argument, NULL, ARG_INLINE },
{}
};
@ -430,6 +420,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_strict = true;
break;
case ARG_INLINE:
arg_inline = true;
break;
case '?':
return -EINVAL;
@ -457,11 +451,15 @@ static int run(int argc, char *argv[]) {
umask(0022);
if (argc > optind) {
r = 0;
for (int i = optind; i < argc; i++)
RET_GATHER(r, parse_file(&sysctl_options, argv[i], false));
unsigned pos = 0;
STRV_FOREACH(arg, strv_skip(argv, optind)) {
if (arg_inline)
/* Use (argument):n, where n==1 for the first positional arg */
RET_GATHER(r, parse_line("(argument)", ++pos, *arg, /* invalid_config = */ NULL, &sysctl_options));
else
RET_GATHER(r, parse_file(&sysctl_options, *arg, false));
}
} else {
_cleanup_strv_free_ char **files = NULL;
@ -478,9 +476,7 @@ static int run(int argc, char *argv[]) {
RET_GATHER(r, read_credential_lines(&sysctl_options));
}
RET_GATHER(r, apply_all(sysctl_options));
return r;
return RET_GATHER(r, apply_all(sysctl_options));
}
DEFINE_MAIN_FUNCTION(run);

View File

@ -911,7 +911,7 @@ void manager_disconnect(Manager *m) {
(void) sd_notify(false, "STATUS=Idle.");
}
void manager_flush_server_names(Manager *m, ServerType t) {
void manager_flush_server_names(Manager *m, ServerType t) {
assert(m);
if (t == SERVER_SYSTEM)
@ -966,19 +966,19 @@ Manager* manager_free(Manager *m) {
return mfree(m);
}
static int manager_network_read_link_servers(Manager *m) {
static bool manager_network_read_link_servers(Manager *m) {
_cleanup_strv_free_ char **ntp = NULL;
bool changed = false;
int r;
assert(m);
bool existing = m->link_servers;
r = sd_network_get_ntp(&ntp);
if (r < 0 && r != -ENODATA) {
if (r == -ENOMEM)
log_oom();
else
log_debug_errno(r, "Failed to get link NTP servers: %m");
if (r < 0) {
if (!IN_SET(r, -ENOENT, -ENODATA))
log_error_errno(r, "Failed to get link NTP servers: %m");
goto clear;
}
@ -1025,7 +1025,7 @@ static int manager_network_read_link_servers(Manager *m) {
clear:
manager_flush_server_names(m, SERVER_LINK);
return r;
return existing; /* return true if there were existing servers. */
}
static bool manager_is_connected(Manager *m) {
@ -1043,7 +1043,6 @@ static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t re
sd_network_monitor_flush(m->network_monitor);
/* When manager_network_read_link_servers() failed, we assume that the servers are changed. */
changed = manager_network_read_link_servers(m);
/* check if the machine is online */

View File

@ -1,7 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
integration_tests += [
integration_test_template + {
'name' : fs.name(meson.current_source_dir()),
},
]

View File

@ -90,7 +90,6 @@ foreach dirname : [
'TEST-73-LOCALE',
'TEST-74-AUX-UTILS',
'TEST-75-RESOLVED',
'TEST-76-SYSCTL',
'TEST-78-SIGQUEUE',
'TEST-79-MEMPRESS',
'TEST-80-NOTIFYACCESS',

View File

@ -1,39 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
export SYSTEMD_LOG_LEVEL=debug
echo "foo.bar=42" >/tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl /tmp/foo.conf
assert_rc 1 /usr/lib/systemd/systemd-sysctl --strict /tmp/foo.conf
echo "-foo.foo=42" >/tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl /tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl --strict /tmp/foo.conf
if ! systemd-detect-virt --quiet --container; then
ip link add hoge type dummy
udevadm wait --timeout=30 /sys/class/net/hoge
cat >/tmp/foo.conf <<EOF
net.ipv4.conf.*.drop_gratuitous_arp=1
net.ipv4.*.*.bootp_relay=1
net.ipv4.aaa.*.disable_policy=1
EOF
echo 0 >/proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp
echo 0 >/proc/sys/net/ipv4/conf/hoge/bootp_relay
echo 0 >/proc/sys/net/ipv4/conf/hoge/disable_policy
assert_rc 0 /usr/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/hoge /tmp/foo.conf
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/bootp_relay)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/disable_policy)" "0"
fi
touch /testok

View File

@ -0,0 +1,80 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
export SYSTEMD_LOG_LEVEL=debug
echo "foo.bar=42" >/tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl /tmp/foo.conf
assert_rc 1 /usr/lib/systemd/systemd-sysctl --strict /tmp/foo.conf
echo "-foo.foo=42" >/tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl /tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl --strict /tmp/foo.conf
assert_rc 0 /usr/lib/systemd/systemd-sysctl --inline "foo.bar=42"
assert_rc 1 /usr/lib/systemd/systemd-sysctl --inline --strict "foo.bar=42"
assert_rc 0 /usr/lib/systemd/systemd-sysctl --inline -- "-foo.bar=42"
assert_rc 0 /usr/lib/systemd/systemd-sysctl --inline --strict -- "-foo.bar=42"
/usr/lib/systemd/systemd-sysctl - <<EOF
foo.bar=42
EOF
(! /usr/lib/systemd/systemd-sysctl --strict - <<EOF
foo.bar=42
EOF
)
/usr/lib/systemd/systemd-sysctl - <<EOF
-foo.bar=42
EOF
/usr/lib/systemd/systemd-sysctl --strict - <<EOF
-foo.bar=42
EOF
ip link add hoge type dummy
trap 'ip link del hoge' EXIT
udevadm wait --timeout=30 /sys/class/net/hoge
cat >/tmp/foo.conf <<EOF
net.ipv4.conf.*.drop_gratuitous_arp=1
net.ipv4.*.*.bootp_relay=1
net.ipv4.aaa.*.disable_policy=1
EOF
echo 0 >/proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp
echo 0 >/proc/sys/net/ipv4/conf/hoge/bootp_relay
echo 0 >/proc/sys/net/ipv4/conf/hoge/disable_policy
assert_rc 0 /usr/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/hoge /tmp/foo.conf
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/bootp_relay)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/disable_policy)" "0"
echo 0 >/proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp
echo 0 >/proc/sys/net/ipv4/conf/hoge/bootp_relay
echo 0 >/proc/sys/net/ipv4/conf/hoge/disable_policy
assert_rc 0 /usr/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/hoge --inline \
'net.ipv4.conf.*.drop_gratuitous_arp=1' \
'net.ipv4.*.*.bootp_relay=1' \
'net.ipv4.aaa.*.disable_policy=1'
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/bootp_relay)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/disable_policy)" "0"
echo 0 >/proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp
echo 0 >/proc/sys/net/ipv4/conf/hoge/bootp_relay
echo 0 >/proc/sys/net/ipv4/conf/hoge/disable_policy
/usr/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/hoge - <<EOF
net.ipv4.conf.*.drop_gratuitous_arp=1
net.ipv4.*.*.bootp_relay=1
net.ipv4.aaa.*.disable_policy=1
EOF
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/drop_gratuitous_arp)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/bootp_relay)" "1"
assert_eq "$(cat /proc/sys/net/ipv4/conf/hoge/disable_policy)" "0"