summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Sekletár <msekleta@redhat.com>2020-04-29 17:40:22 +0200
committerMichal Sekletár <msekleta@redhat.com>2020-04-29 18:41:19 +0200
commit25a1f04c682260bb9b96e25bdf33665d6172db98 (patch)
tree9ea98ff81b8f11fb30bf204f0e563b7b4abb1164
parent08deac6e3e9119aeb966375f94695e4aa14ffb1c (diff)
downloadsystemd-25a1f04c682260bb9b96e25bdf33665d6172db98.tar.gz
basic/cgroup-util: introduce cg_get_keyed_attribute_full()
Callers of cg_get_keyed_attribute_full() can now specify via the flag whether the missing keyes in cgroup attribute file are OK or not. Also the wrappers for both strict and graceful version are provided.
-rw-r--r--src/basic/cgroup-util.c13
-rw-r--r--src/basic/cgroup-util.h24
-rw-r--r--src/test/test-cgroup-util.c20
3 files changed, 53 insertions, 4 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 33575e65ef..da4bd33d18 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -1684,12 +1684,13 @@ int cg_get_attribute_as_uint64(const char *controller, const char *path, const c
return 0;
}
-int cg_get_keyed_attribute(
+int cg_get_keyed_attribute_full(
const char *controller,
const char *path,
const char *attribute,
char **keys,
- char **ret_values) {
+ char **ret_values,
+ CGroupKeyMode mode) {
_cleanup_free_ char *filename = NULL, *contents = NULL;
const char *p;
@@ -1749,7 +1750,10 @@ int cg_get_keyed_attribute(
p += strspn(p, NEWLINE);
}
- r = -ENXIO;
+ if (mode & CG_KEY_MODE_GRACEFUL)
+ goto done;
+ else
+ r = -ENXIO;
fail:
for (i = 0; i < n; i++)
@@ -1759,6 +1763,9 @@ fail:
done:
memcpy(ret_values, v, sizeof(char*) * n);
+ if (mode & CG_KEY_MODE_GRACEFUL)
+ return n_done;
+
return 0;
}
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 237139fad0..6e05a8a5a1 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -180,9 +180,31 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path);
int cg_rmdir(const char *controller, const char *path);
+typedef enum {
+ CG_KEY_MODE_GRACEFUL = 1 << 0,
+} CGroupKeyMode;
+
int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
-int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char **keys, char **values);
+int cg_get_keyed_attribute_full(const char *controller, const char *path, const char *attribute, char **keys, char **values, CGroupKeyMode mode);
+
+static inline int cg_get_keyed_attribute(
+ const char *controller,
+ const char *path,
+ const char *attribute,
+ char **keys,
+ char **ret_values) {
+ return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, 0);
+}
+
+static inline int cg_get_keyed_attribute_graceful(
+ const char *controller,
+ const char *path,
+ const char *attribute,
+ char **keys,
+ char **ret_values) {
+ return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, CG_KEY_MODE_GRACEFUL);
+}
int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret);
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index daaffb5a06..5826d6ec28 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -384,22 +384,42 @@ static void test_cg_get_keyed_attribute(void) {
}
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == -ENXIO);
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == 0);
assert_se(val == NULL);
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 0);
+ free(val);
+
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 1);
log_info("cpu /init.scope cpu.stat [usage_usec] → \"%s\"", val);
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == -ENXIO);
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == 1);
+ assert(vals3[0] && !vals3[1]);
+ free(vals3[0]);
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == -ENXIO);
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == 1);
+ assert(vals3[0] && !vals3[1]);
+ free(vals3[0]);
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 0);
+ for (i = 0; i < 3; i++)
+ free(vals3[i]);
+
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat",
+ STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 3);
log_info("cpu /init.scope cpu.stat [usage_usec user_usec system_usec] → \"%s\", \"%s\", \"%s\"",
vals3[0], vals3[1], vals3[2]);
assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 0);
+ for (i = 0; i < 3; i++)
+ free(vals3a[i]);
+
+ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat",
+ STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 3);
log_info("cpu /init.scope cpu.stat [system_usec user_usec usage_usec] → \"%s\", \"%s\", \"%s\"",
vals3a[0], vals3a[1], vals3a[2]);