sysctl: improve performance for applying glob pattern
(cherry picked from commit 691299304a7430f5259f934f97434e0ac1cdec93)
This commit is contained in:
parent
23d376a117
commit
63e96e76b3
99
backport-path-util-introduce-path_glob_can_match.patch
Normal file
99
backport-path-util-introduce-path_glob_can_match.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From 3b703fe269a4a34f1b5ad1c3ce219c8c407e6fe1 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 17 Aug 2022 06:43:37 +0900
|
||||
Subject: [PATCH] path-util: introduce path_glob_can_match()
|
||||
|
||||
---
|
||||
src/basic/path-util.c | 61 +++++++++++++++++++++++++++++++++++++++++++
|
||||
src/basic/path-util.h | 2 ++
|
||||
2 files changed, 63 insertions(+)
|
||||
|
||||
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
|
||||
index 13d71ed..bec930f 100644
|
||||
--- a/src/basic/path-util.c
|
||||
+++ b/src/basic/path-util.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <errno.h>
|
||||
+#include <fnmatch.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -1395,3 +1396,63 @@ bool prefixed_path_strv_contains(char **l, const char *path) {
|
||||
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+int path_glob_can_match(const char *pattern, const char *prefix, char **ret) {
|
||||
+ assert(pattern);
|
||||
+ assert(prefix);
|
||||
+
|
||||
+ for (const char *a = pattern, *b = prefix;;) {
|
||||
+ _cleanup_free_ char *g = NULL, *h = NULL;
|
||||
+ const char *p, *q;
|
||||
+ int r, s;
|
||||
+
|
||||
+ r = path_find_first_component(&a, /* accept_dot_dot = */ false, &p);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ s = path_find_first_component(&b, /* accept_dot_dot = */ false, &q);
|
||||
+ if (s < 0)
|
||||
+ return s;
|
||||
+
|
||||
+ if (s == 0) {
|
||||
+ /* The pattern matches the prefix. */
|
||||
+ if (ret) {
|
||||
+ char *t;
|
||||
+
|
||||
+ t = path_join(prefix, p);
|
||||
+ if (!t)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *ret = t;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (r == 0)
|
||||
+ break;
|
||||
+
|
||||
+ if (r == s && strneq(p, q, r))
|
||||
+ continue; /* common component. Check next. */
|
||||
+
|
||||
+ g = strndup(p, r);
|
||||
+ if (!g)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (!string_is_glob(g))
|
||||
+ break;
|
||||
+
|
||||
+ /* We found a glob component. Check if the glob pattern matches the prefix component. */
|
||||
+
|
||||
+ h = strndup(q, s);
|
||||
+ if (!h)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (fnmatch(g, h, 0) != 0)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* The pattern does not match the prefix. */
|
||||
+ if (ret)
|
||||
+ *ret = NULL;
|
||||
+ return false;
|
||||
+}
|
||||
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
|
||||
index 26e7362..c374a77 100644
|
||||
--- a/src/basic/path-util.h
|
||||
+++ b/src/basic/path-util.h
|
||||
@@ -202,3 +202,5 @@ static inline const char *empty_to_root(const char *path) {
|
||||
|
||||
bool path_strv_contains(char **l, const char *path);
|
||||
bool prefixed_path_strv_contains(char **l, const char *path);
|
||||
+
|
||||
+int path_glob_can_match(const char *pattern, const char *prefix, char **ret);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
121
backport-sysctl-apply-prefix-before-calling-glob.patch
Normal file
121
backport-sysctl-apply-prefix-before-calling-glob.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 9ec8c82b8c836f7632ba0a075c296e6ddc53f643 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 17 Aug 2022 04:54:06 +0900
|
||||
Subject: [PATCH] sysctl: apply prefix before calling glob()
|
||||
|
||||
Otherwise, if there exist million of network interfaces,
|
||||
calling glob() for network properties takes much time.
|
||||
|
||||
Fixes #24031.
|
||||
---
|
||||
src/sysctl/sysctl.c | 61 +++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 53 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
|
||||
index fc13529..499ddde 100644
|
||||
--- a/src/sysctl/sysctl.c
|
||||
+++ b/src/sysctl/sysctl.c
|
||||
@@ -86,7 +86,7 @@ static Option *option_new(
|
||||
return TAKE_PTR(o);
|
||||
}
|
||||
|
||||
-static int sysctl_write_or_warn(const char *key, const char *value, bool ignore_failure) {
|
||||
+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);
|
||||
@@ -106,7 +106,7 @@ static int sysctl_write_or_warn(const char *key, const char *value, bool ignore_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int apply_glob_option(OrderedHashmap *sysctl_options, Option *option) {
|
||||
+static int apply_glob_option_with_prefix(OrderedHashmap *sysctl_options, Option *option, const char *prefix) {
|
||||
_cleanup_strv_free_ char **paths = NULL;
|
||||
_cleanup_free_ char *pattern = NULL;
|
||||
int r, k;
|
||||
@@ -115,7 +115,35 @@ static int apply_glob_option(OrderedHashmap *sysctl_options, Option *option) {
|
||||
assert(sysctl_options);
|
||||
assert(option);
|
||||
|
||||
- pattern = path_join("/proc/sys", option->key);
|
||||
+ if (prefix) {
|
||||
+ _cleanup_free_ char *key = NULL;
|
||||
+
|
||||
+ r = path_glob_can_match(option->key, prefix, &key);
|
||||
+ if (r < 0)
|
||||
+ return log_error_errno(r, "Failed to check if the glob '%s' matches prefix '%s': %m",
|
||||
+ option->key, prefix);
|
||||
+ if (r == 0) {
|
||||
+ log_debug("The glob '%s' does not match prefix '%s'.", option->key, prefix);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ log_debug("The glob '%s' is prefixed with '%s': '%s'", option->key, prefix, key);
|
||||
+
|
||||
+ if (!string_is_glob(key)) {
|
||||
+ /* The prefixed pattern is not glob anymore. Let's skip to call glob(). */
|
||||
+ if (ordered_hashmap_contains(sysctl_options, key)) {
|
||||
+ log_debug("Not setting %s (explicit setting exists).", key);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return sysctl_write_or_warn(key, option->value,
|
||||
+ /* ignore_failure = */ option->ignore_failure,
|
||||
+ /* ignore_enoent = */ true);
|
||||
+ }
|
||||
+
|
||||
+ pattern = path_join("/proc/sys", key);
|
||||
+ } else
|
||||
+ pattern = path_join("/proc/sys", option->key);
|
||||
if (!pattern)
|
||||
return log_oom();
|
||||
|
||||
@@ -137,15 +165,30 @@ static int apply_glob_option(OrderedHashmap *sysctl_options, Option *option) {
|
||||
|
||||
assert_se(key = path_startswith(*s, "/proc/sys"));
|
||||
|
||||
- if (!test_prefix(key))
|
||||
- continue;
|
||||
-
|
||||
if (ordered_hashmap_contains(sysctl_options, key)) {
|
||||
log_debug("Not setting %s (explicit setting exists).", key);
|
||||
continue;
|
||||
}
|
||||
|
||||
- k = sysctl_write_or_warn(key, option->value, option->ignore_failure);
|
||||
+ k = sysctl_write_or_warn(key, option->value,
|
||||
+ /* ignore_failure = */ option->ignore_failure,
|
||||
+ /* ignore_enoent = */ false);
|
||||
+ if (k < 0 && r >= 0)
|
||||
+ r = k;
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int apply_glob_option(OrderedHashmap *sysctl_options, Option *option) {
|
||||
+ int r = 0, k;
|
||||
+ char **i;
|
||||
+
|
||||
+ if (strv_isempty(arg_prefixes))
|
||||
+ return apply_glob_option_with_prefix(sysctl_options, option, NULL);
|
||||
+
|
||||
+ STRV_FOREACH(i, arg_prefixes) {
|
||||
+ k = apply_glob_option_with_prefix(sysctl_options, option, *i);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
@@ -167,7 +210,9 @@ static int apply_all(OrderedHashmap *sysctl_options) {
|
||||
if (string_is_glob(option->key))
|
||||
k = apply_glob_option(sysctl_options, option);
|
||||
else
|
||||
- k = sysctl_write_or_warn(option->key, option->value, option->ignore_failure);
|
||||
+ k = sysctl_write_or_warn(option->key, option->value,
|
||||
+ /* ignore_failure = */ option->ignore_failure,
|
||||
+ /* ignore_enoent = */ false);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
57
backport-sysctl-drop-proc-sys-in-prefix.patch
Normal file
57
backport-sysctl-drop-proc-sys-in-prefix.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From c01404fdf100b03dafa8a366d07f74f3c30d5330 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 17 Aug 2022 03:11:00 +0900
|
||||
Subject: [PATCH] sysctl: drop /proc/sys/ in prefix
|
||||
|
||||
---
|
||||
src/sysctl/sysctl.c | 20 ++++----------------
|
||||
1 file changed, 4 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
|
||||
index dda112f45..ae079b7a7 100644
|
||||
--- a/src/sysctl/sysctl.c
|
||||
+++ b/src/sysctl/sysctl.c
|
||||
@@ -56,18 +56,7 @@ static bool test_prefix(const char *p) {
|
||||
if (strv_isempty(arg_prefixes))
|
||||
return true;
|
||||
|
||||
- STRV_FOREACH(i, arg_prefixes) {
|
||||
- const char *t;
|
||||
-
|
||||
- t = path_startswith(*i, "/proc/sys/");
|
||||
- if (!t)
|
||||
- t = *i;
|
||||
-
|
||||
- if (path_startswith(p, t))
|
||||
- return true;
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
+ return path_startswith_strv(p, arg_prefixes);
|
||||
}
|
||||
|
||||
static Option *option_new(
|
||||
@@ -360,6 +349,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case ARG_PREFIX: {
|
||||
+ const char *s;
|
||||
char *p;
|
||||
|
||||
/* We used to require people to specify absolute paths
|
||||
@@ -368,10 +358,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
* sysctl name available. */
|
||||
sysctl_normalize(optarg);
|
||||
|
||||
- if (path_startswith(optarg, "/proc/sys"))
|
||||
- p = strdup(optarg);
|
||||
- else
|
||||
- p = path_join("/proc/sys", optarg);
|
||||
+ s = path_startswith(optarg, "/proc/sys");
|
||||
+ p = strdup(s ?: optarg);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
132
backport-sysctl-split-out-code-for-applying-glob-option.patch
Normal file
132
backport-sysctl-split-out-code-for-applying-glob-option.patch
Normal file
@ -0,0 +1,132 @@
|
||||
From 7177ac45723a2d716d34b66fb5d8691df5f2c6c8 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 17 Aug 2022 04:10:30 +0900
|
||||
Subject: [PATCH] sysctl: split out code for applying glob option
|
||||
|
||||
---
|
||||
src/sysctl/sysctl.c | 96 ++++++++++++++++++++++++---------------------
|
||||
1 file changed, 51 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
|
||||
index 642535b..df02771 100644
|
||||
--- a/src/sysctl/sysctl.c
|
||||
+++ b/src/sysctl/sysctl.c
|
||||
@@ -106,64 +106,70 @@ static int sysctl_write_or_warn(const char *key, const char *value, bool ignore_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int apply_all(OrderedHashmap *sysctl_options) {
|
||||
- Option *option;
|
||||
- int r = 0;
|
||||
+static int apply_glob_option(OrderedHashmap *sysctl_options, Option *option) {
|
||||
+ _cleanup_strv_free_ char **paths = NULL;
|
||||
+ _cleanup_free_ char *pattern = NULL;
|
||||
+ int r, k;
|
||||
+ char **s;
|
||||
|
||||
- ORDERED_HASHMAP_FOREACH(option, sysctl_options) {
|
||||
- int k;
|
||||
+ assert(sysctl_options);
|
||||
+ assert(option);
|
||||
|
||||
- /* Ignore "negative match" options, they are there only to exclude stuff from globs. */
|
||||
- if (!option->value)
|
||||
- continue;
|
||||
+ pattern = path_join("/proc/sys", option->key);
|
||||
+ if (!pattern)
|
||||
+ return log_oom();
|
||||
|
||||
- if (string_is_glob(option->key)) {
|
||||
- _cleanup_strv_free_ char **paths = NULL;
|
||||
- _cleanup_free_ char *pattern = NULL;
|
||||
- char **s;
|
||||
+ r = glob_extend(&paths, pattern, GLOB_NOCHECK);
|
||||
+ if (r < 0) {
|
||||
+ if (r == -ENOENT) {
|
||||
+ log_debug("No match for glob: %s", option->key);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ 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);
|
||||
+ }
|
||||
|
||||
- pattern = path_join("/proc/sys", option->key);
|
||||
- if (!pattern)
|
||||
- return log_oom();
|
||||
+ STRV_FOREACH(s, paths) {
|
||||
+ const char *key;
|
||||
|
||||
- k = glob_extend(&paths, pattern, GLOB_NOCHECK);
|
||||
- if (k < 0) {
|
||||
- if (option->ignore_failure || ERRNO_IS_PRIVILEGE(k))
|
||||
- log_debug_errno(k, "Failed to resolve glob '%s', ignoring: %m",
|
||||
- option->key);
|
||||
- else {
|
||||
- log_error_errno(k, "Couldn't resolve glob '%s': %m",
|
||||
- option->key);
|
||||
- if (r == 0)
|
||||
- r = k;
|
||||
- }
|
||||
+ assert_se(key = path_startswith(*s, "/proc/sys"));
|
||||
|
||||
- } else if (strv_isempty(paths))
|
||||
- log_debug("No match for glob: %s", option->key);
|
||||
+ if (!test_prefix(key))
|
||||
+ continue;
|
||||
|
||||
- STRV_FOREACH(s, paths) {
|
||||
- const char *key;
|
||||
+ if (ordered_hashmap_contains(sysctl_options, key)) {
|
||||
+ log_debug("Not setting %s (explicit setting exists).", key);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- assert_se(key = path_startswith(*s, "/proc/sys"));
|
||||
+ k = sysctl_write_or_warn(key, option->value, option->ignore_failure);
|
||||
+ if (k < 0 && r >= 0)
|
||||
+ r = k;
|
||||
+ }
|
||||
|
||||
- if (!test_prefix(key))
|
||||
- continue;
|
||||
+ return r;
|
||||
+}
|
||||
|
||||
- if (ordered_hashmap_contains(sysctl_options, key)) {
|
||||
- log_debug("Not setting %s (explicit setting exists).", key);
|
||||
- continue;
|
||||
- }
|
||||
+static int apply_all(OrderedHashmap *sysctl_options) {
|
||||
+ Option *option;
|
||||
+ int r = 0;
|
||||
|
||||
- k = sysctl_write_or_warn(key, option->value, option->ignore_failure);
|
||||
- if (r == 0)
|
||||
- r = k;
|
||||
- }
|
||||
+ ORDERED_HASHMAP_FOREACH(option, sysctl_options) {
|
||||
+ int k;
|
||||
|
||||
- } else {
|
||||
+ /* Ignore "negative match" options, they are there only to exclude stuff from globs. */
|
||||
+ if (!option->value)
|
||||
+ continue;
|
||||
+
|
||||
+ if (string_is_glob(option->key))
|
||||
+ k = apply_glob_option(sysctl_options, option);
|
||||
+ else
|
||||
k = sysctl_write_or_warn(option->key, option->value, option->ignore_failure);
|
||||
- if (r == 0)
|
||||
- r = k;
|
||||
- }
|
||||
+ if (k < 0 && r >= 0)
|
||||
+ r = k;
|
||||
}
|
||||
|
||||
return r;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
35
backport-sysctl-use-ordered_hashmap_ensure_put.patch
Normal file
35
backport-sysctl-use-ordered_hashmap_ensure_put.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 350ffa9749f2ce5d62e4b66cc7418e25e6829963 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 17 Aug 2022 14:29:26 +0900
|
||||
Subject: [PATCH] sysctl: use ordered_hashmap_ensure_put()
|
||||
|
||||
---
|
||||
src/sysctl/sysctl.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
|
||||
index de0e03ec9..dda112f45 100644
|
||||
--- a/src/sysctl/sysctl.c
|
||||
+++ b/src/sysctl/sysctl.c
|
||||
@@ -254,9 +254,6 @@ static int parse_file(OrderedHashmap **sysctl_options, const char *path, bool ig
|
||||
!test_prefix(p))
|
||||
continue;
|
||||
|
||||
- if (ordered_hashmap_ensure_allocated(sysctl_options, &option_hash_ops) < 0)
|
||||
- return log_oom();
|
||||
-
|
||||
existing = ordered_hashmap_get(*sysctl_options, p);
|
||||
if (existing) {
|
||||
if (streq_ptr(value, existing->value)) {
|
||||
@@ -272,7 +269,7 @@ static int parse_file(OrderedHashmap **sysctl_options, const char *path, bool ig
|
||||
if (!new_option)
|
||||
return log_oom();
|
||||
|
||||
- k = ordered_hashmap_put(*sysctl_options, new_option->key, new_option);
|
||||
+ 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);
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
10
systemd.spec
10
systemd.spec
@ -25,7 +25,7 @@
|
||||
Name: systemd
|
||||
Url: https://systemd.io/
|
||||
Version: 249
|
||||
Release: 100
|
||||
Release: 101
|
||||
License: MIT and LGPLv2+ and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
|
||||
@ -731,6 +731,11 @@ Patch6678: backport-manager-improve-message-about-Reload-Reexec-requests.pa
|
||||
Patch6679: backport-core-fix-null-in-output.patch
|
||||
Patch6680: backport-core-Bump-log-level-of-reexecute-request-to-notice.patch
|
||||
Patch6681: backport-core-Log-in-more-scenarios-about-which-process-initi.patch
|
||||
Patch6682: backport-sysctl-use-ordered_hashmap_ensure_put.patch
|
||||
Patch6683: backport-sysctl-drop-proc-sys-in-prefix.patch
|
||||
Patch6684: backport-sysctl-split-out-code-for-applying-glob-option.patch
|
||||
Patch6685: backport-path-util-introduce-path_glob_can_match.patch
|
||||
Patch6686: backport-sysctl-apply-prefix-before-calling-glob.patch
|
||||
|
||||
Patch9001: update-rtc-with-system-clock-when-shutdown.patch
|
||||
Patch9002: udev-add-actions-while-rename-netif-failed.patch
|
||||
@ -2247,6 +2252,9 @@ grep -q -E '^KEYMAP="?fi-latin[19]"?' /etc/vconsole.conf 2>/dev/null &&
|
||||
/usr/bin/systemd-cryptenroll
|
||||
|
||||
%changelog
|
||||
* Mon Feb 17 2025 zhangyao <zhangyao108@huawei.com> - 249-101
|
||||
- sysctl: improve performance for applying glob pattern
|
||||
|
||||
* Tue Dec 24 2024 xujing <xujing125@huawei.com> - 249-100
|
||||
- add DefaultEnableMemswLimit support
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user