|
|
4cad4c |
From 5aefc153b25b42a80942e5c367ce143817551870 Mon Sep 17 00:00:00 2001
|
|
|
4cad4c |
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
|
|
|
4cad4c |
Date: Wed, 29 Apr 2020 17:40:22 +0200
|
|
|
4cad4c |
Subject: [PATCH] basic/cgroup-util: introduce cg_get_keyed_attribute_full()
|
|
|
4cad4c |
|
|
|
4cad4c |
Callers of cg_get_keyed_attribute_full() can now specify via the flag whether the
|
|
|
4cad4c |
missing keyes in cgroup attribute file are OK or not. Also the wrappers for both
|
|
|
4cad4c |
strict and graceful version are provided.
|
|
|
4cad4c |
|
|
|
4cad4c |
(cherry picked from commit 25a1f04c682260bb9b96e25bdf33665d6172db98)
|
|
|
4cad4c |
|
|
|
4cad4c |
Related: #1830861
|
|
|
4cad4c |
---
|
|
|
4cad4c |
src/basic/cgroup-util.c | 13 ++++++++++---
|
|
|
4cad4c |
src/basic/cgroup-util.h | 24 +++++++++++++++++++++++-
|
|
|
4cad4c |
src/test/test-cgroup-util.c | 20 ++++++++++++++++++++
|
|
|
4cad4c |
3 files changed, 53 insertions(+), 4 deletions(-)
|
|
|
4cad4c |
|
|
|
4cad4c |
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
|
|
|
4cad4c |
index 92bc1f2543..4c0b73850d 100644
|
|
|
4cad4c |
--- a/src/basic/cgroup-util.c
|
|
|
4cad4c |
+++ b/src/basic/cgroup-util.c
|
|
|
4cad4c |
@@ -2021,12 +2021,13 @@ int cg_get_attribute(const char *controller, const char *path, const char *attri
|
|
|
4cad4c |
return read_one_line_file(p, ret);
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
-int cg_get_keyed_attribute(
|
|
|
4cad4c |
+int cg_get_keyed_attribute_full(
|
|
|
4cad4c |
const char *controller,
|
|
|
4cad4c |
const char *path,
|
|
|
4cad4c |
const char *attribute,
|
|
|
4cad4c |
char **keys,
|
|
|
4cad4c |
- char **ret_values) {
|
|
|
4cad4c |
+ char **ret_values,
|
|
|
4cad4c |
+ CGroupKeyMode mode) {
|
|
|
4cad4c |
|
|
|
4cad4c |
_cleanup_free_ char *filename = NULL, *contents = NULL;
|
|
|
4cad4c |
const char *p;
|
|
|
4cad4c |
@@ -2086,7 +2087,10 @@ int cg_get_keyed_attribute(
|
|
|
4cad4c |
p += strspn(p, NEWLINE);
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
- r = -ENXIO;
|
|
|
4cad4c |
+ if (mode & CG_KEY_MODE_GRACEFUL)
|
|
|
4cad4c |
+ goto done;
|
|
|
4cad4c |
+ else
|
|
|
4cad4c |
+ r = -ENXIO;
|
|
|
4cad4c |
|
|
|
4cad4c |
fail:
|
|
|
4cad4c |
for (i = 0; i < n; i++)
|
|
|
4cad4c |
@@ -2096,6 +2100,9 @@ fail:
|
|
|
4cad4c |
|
|
|
4cad4c |
done:
|
|
|
4cad4c |
memcpy(ret_values, v, sizeof(char*) * n);
|
|
|
4cad4c |
+ if (mode & CG_KEY_MODE_GRACEFUL)
|
|
|
4cad4c |
+ return n_done;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
return 0;
|
|
|
4cad4c |
|
|
|
4cad4c |
}
|
|
|
4cad4c |
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
|
|
|
4cad4c |
index b414600dca..0673f4b4ce 100644
|
|
|
4cad4c |
--- a/src/basic/cgroup-util.h
|
|
|
4cad4c |
+++ b/src/basic/cgroup-util.h
|
|
|
4cad4c |
@@ -167,9 +167,31 @@ int cg_attach(const char *controller, const char *path, pid_t pid);
|
|
|
4cad4c |
int cg_attach_fallback(const char *controller, const char *path, pid_t pid);
|
|
|
4cad4c |
int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
|
|
|
4cad4c |
|
|
|
4cad4c |
+typedef enum {
|
|
|
4cad4c |
+ CG_KEY_MODE_GRACEFUL = 1 << 0,
|
|
|
4cad4c |
+} CGroupKeyMode;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
|
|
|
4cad4c |
int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
|
|
|
4cad4c |
-int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char **keys, char **values);
|
|
|
4cad4c |
+int cg_get_keyed_attribute_full(const char *controller, const char *path, const char *attribute, char **keys, char **values, CGroupKeyMode mode);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+static inline int cg_get_keyed_attribute(
|
|
|
4cad4c |
+ const char *controller,
|
|
|
4cad4c |
+ const char *path,
|
|
|
4cad4c |
+ const char *attribute,
|
|
|
4cad4c |
+ char **keys,
|
|
|
4cad4c |
+ char **ret_values) {
|
|
|
4cad4c |
+ return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, 0);
|
|
|
4cad4c |
+}
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+static inline int cg_get_keyed_attribute_graceful(
|
|
|
4cad4c |
+ const char *controller,
|
|
|
4cad4c |
+ const char *path,
|
|
|
4cad4c |
+ const char *attribute,
|
|
|
4cad4c |
+ char **keys,
|
|
|
4cad4c |
+ char **ret_values) {
|
|
|
4cad4c |
+ return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, CG_KEY_MODE_GRACEFUL);
|
|
|
4cad4c |
+}
|
|
|
4cad4c |
|
|
|
4cad4c |
int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid);
|
|
|
4cad4c |
|
|
|
4cad4c |
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
|
|
|
4cad4c |
index d49356315e..60d7bb19cb 100644
|
|
|
4cad4c |
--- a/src/test/test-cgroup-util.c
|
|
|
4cad4c |
+++ b/src/test/test-cgroup-util.c
|
|
|
4cad4c |
@@ -421,22 +421,42 @@ static void test_cg_get_keyed_attribute(void) {
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == -ENXIO);
|
|
|
4cad4c |
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == 0);
|
|
|
4cad4c |
assert_se(val == NULL);
|
|
|
4cad4c |
|
|
|
4cad4c |
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 0);
|
|
|
4cad4c |
+ free(val);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 1);
|
|
|
4cad4c |
log_info("cpu /init.scope cpu.stat [usage_usec] → \"%s\"", val);
|
|
|
4cad4c |
|
|
|
4cad4c |
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == -ENXIO);
|
|
|
4cad4c |
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == 1);
|
|
|
4cad4c |
+ assert(vals3[0] && !vals3[1]);
|
|
|
4cad4c |
+ free(vals3[0]);
|
|
|
4cad4c |
|
|
|
4cad4c |
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == -ENXIO);
|
|
|
4cad4c |
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == 1);
|
|
|
4cad4c |
+ assert(vals3[0] && !vals3[1]);
|
|
|
4cad4c |
+ free(vals3[0]);
|
|
|
4cad4c |
|
|
|
4cad4c |
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
|
|
|
4cad4c |
STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 0);
|
|
|
4cad4c |
+ for (i = 0; i < 3; i++)
|
|
|
4cad4c |
+ free(vals3[i]);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat",
|
|
|
4cad4c |
+ STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 3);
|
|
|
4cad4c |
log_info("cpu /init.scope cpu.stat [usage_usec user_usec system_usec] → \"%s\", \"%s\", \"%s\"",
|
|
|
4cad4c |
vals3[0], vals3[1], vals3[2]);
|
|
|
4cad4c |
|
|
|
4cad4c |
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
|
|
|
4cad4c |
STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 0);
|
|
|
4cad4c |
+ for (i = 0; i < 3; i++)
|
|
|
4cad4c |
+ free(vals3a[i]);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat",
|
|
|
4cad4c |
+ STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 3);
|
|
|
4cad4c |
log_info("cpu /init.scope cpu.stat [system_usec user_usec usage_usec] → \"%s\", \"%s\", \"%s\"",
|
|
|
4cad4c |
vals3a[0], vals3a[1], vals3a[2]);
|
|
|
4cad4c |
|