mirror of
https://github.com/systemd/systemd.git
synced 2026-08-09 01:20:53 +00:00
sysctl: add --verify option to verify written values (#43258)
This commit is contained in:
@@ -62,7 +62,7 @@
|
||||
|
||||
<refsect1><title>Options</title>
|
||||
<variablelist>
|
||||
<varlistentry id='prefix'>
|
||||
<varlistentry>
|
||||
<term><option>--prefix=</option></term>
|
||||
<listitem>
|
||||
<para>Only apply rules with the specified prefix.</para>
|
||||
@@ -70,8 +70,8 @@
|
||||
<xi:include href="version-info.xml" xpointer="v230"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id='strict'>
|
||||
<term><option>--strict=</option></term>
|
||||
<varlistentry>
|
||||
<term><option>--strict</option></term>
|
||||
<listitem>
|
||||
<para>Always return non-zero exit code on failure (including invalid sysctl variable
|
||||
name and insufficient permissions), unless the sysctl variable name is prefixed with a "-"
|
||||
@@ -81,6 +81,15 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--verify</option></term>
|
||||
<listitem>
|
||||
<para>Verify sysctl values after write.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v262"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--inline</option></term>
|
||||
<listitem><para>Treat each positional argument as a separate configuration line instead of a file
|
||||
|
||||
@@ -114,6 +114,43 @@ int sysctl_writef(const char *property, const char *format, ...) {
|
||||
return sysctl_write(property, v);
|
||||
}
|
||||
|
||||
int sysctl_write_verify(const char *property, const char *value) {
|
||||
int r;
|
||||
|
||||
assert(property);
|
||||
assert(value);
|
||||
|
||||
/* Some sysctl settings accept invalid values on write, but refuses on read. E.g. coredump pattern,
|
||||
* be1e0283021ec73c2eb92839db9a471a068709d9 (v6.17) and 7d7c1fb85cba5627bbe741fb7539c709435e3848
|
||||
* (v6.16.8), which is fixed by a779e27f24aeb679969ddd1fdd7f636e22ddbc1e (v6.18) and
|
||||
* 304aa560385720baf3660fe8500f6dd425b63ea9 (v6.17.5). Let's first save the original value, and
|
||||
* restore to the saved value if the new value is refused. */
|
||||
|
||||
_cleanup_free_ char *original = NULL;
|
||||
r = sysctl_read(property, &original);
|
||||
if (r >= 0 && streq(original, value))
|
||||
return 0; /* Already set. */
|
||||
|
||||
r = sysctl_write(property, value);
|
||||
if (r >= 0) {
|
||||
_cleanup_free_ char *current = NULL;
|
||||
r = sysctl_read(property, ¤t);
|
||||
if (r >= 0) {
|
||||
if (streq(current, value))
|
||||
return 0; /* Yay! */
|
||||
|
||||
/* At least for coredump pattern, this does not happen, but let's handle this as the
|
||||
* same as we wrote something invalid. */
|
||||
r = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (original)
|
||||
(void) sysctl_write(property, original);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char* af_to_sysctl_dir(int af) {
|
||||
if (af == AF_MPLS)
|
||||
return "mpls";
|
||||
|
||||
@@ -12,6 +12,7 @@ int sysctl_writef(const char *property, const char *format, ...) _printf_(2, 3);
|
||||
static inline int sysctl_write(const char *property, const char *value) {
|
||||
return sysctl_write_full(property, value, NULL);
|
||||
}
|
||||
int sysctl_write_verify(const char *property, const char *value);
|
||||
|
||||
int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret);
|
||||
int sysctl_read_ip_property_int(int af, const char *ifname, const char *property, int *ret);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
static char **arg_prefixes = NULL;
|
||||
static CatFlags arg_cat_flags = CAT_CONFIG_OFF;
|
||||
static bool arg_strict = false;
|
||||
static bool arg_verify = false;
|
||||
static bool arg_inline = false;
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
|
||||
@@ -89,7 +90,10 @@ static SysctlOption* sysctl_option_new(
|
||||
static int sysctl_write_or_warn(const char *key, const char *value, bool ignore_failure, bool ignore_enoent) {
|
||||
int r;
|
||||
|
||||
r = sysctl_write(key, value);
|
||||
if (arg_verify)
|
||||
r = sysctl_write_verify(key, value);
|
||||
else
|
||||
r = sysctl_write(key, value);
|
||||
if (r < 0) {
|
||||
/* Proceed without failing if ignore_failure is true.
|
||||
* If the sysctl is not available in the kernel or we are running with reduced privileges and
|
||||
@@ -409,6 +413,11 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) {
|
||||
arg_strict = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("verify", NULL,
|
||||
"Verify sysctl values after write"):
|
||||
arg_verify = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("inline", NULL,
|
||||
"Treat arguments as configuration lines"):
|
||||
arg_inline = true;
|
||||
@@ -425,18 +434,18 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) {
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_ordered_hashmap_free_ OrderedHashmap *sysctl_options = NULL;
|
||||
int r;
|
||||
|
||||
log_setup();
|
||||
|
||||
char **args = NULL;
|
||||
r = parse_argv(argc, argv, &args);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
log_setup();
|
||||
|
||||
umask(0022);
|
||||
|
||||
_cleanup_ordered_hashmap_free_ OrderedHashmap *sysctl_options = NULL;
|
||||
if (!strv_isempty(args)) {
|
||||
unsigned pos = 0;
|
||||
|
||||
|
||||
@@ -78,3 +78,16 @@ 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"
|
||||
|
||||
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 --verify - <<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"
|
||||
|
||||
Reference in New Issue
Block a user