summaryrefslogtreecommitdiffstats
path: root/linux/CGroupUtils.c
diff options
context:
space:
mode:
authorBenny Baumann <BenBE@geshi.org>2021-10-19 23:36:31 +0200
committerBenBE <BenBE@geshi.org>2021-11-28 20:19:10 +0100
commit9dc964bb42526d21e1221945ba96a0c87e58d040 (patch)
tree0d293ad30f62557a30e20e453869d7bcd9d772f4 /linux/CGroupUtils.c
parentea4282784de0a74fa97d9ca917f7f601c16aab64 (diff)
Compress cgroup names based on some heuristics
Diffstat (limited to 'linux/CGroupUtils.c')
-rw-r--r--linux/CGroupUtils.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/linux/CGroupUtils.c b/linux/CGroupUtils.c
new file mode 100644
index 00000000..dd91809a
--- /dev/null
+++ b/linux/CGroupUtils.c
@@ -0,0 +1,285 @@
+/*
+htop - CGroupUtils.h
+(C) 2021 htop dev team
+Released under the GNU GPLv2+, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include "linux/CGroupUtils.h"
+
+#include "XUtils.h"
+
+
+static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t bufsize) {
+ const char* str_slice_suffix = ".slice";
+ const char* str_system_slice = "system.slice";
+ const char* str_user_slice = "user.slice";
+ const char* str_machine_slice = "machine.slice";
+ const char* str_user_slice_prefix = "/user-";
+
+ const char* str_lxc_monitor_prefix = "lxc.monitor.";
+ const char* str_lxc_payload_prefix = "lxc.payload.";
+
+ const char* str_nspawn_scope_prefix = "machine-";
+ const char* str_nspawn_monitor_label = "/supervisor";
+
+ const char* str_service_suffix = ".service";
+ const char* str_scope_suffix = ".scope";
+
+ while(*cgroup) {
+ if ('/' == *cgroup) {
+ while ('/' == *cgroup)
+ cgroup++;
+
+ if (!bufsize)
+ return false;
+
+ *buf++ = '/';
+ bufsize--;
+
+ continue;
+ }
+
+ const char* labelStart = cgroup;
+ const char* nextSlash = strchrnul(labelStart, '/');
+ const size_t labelLen = nextSlash - labelStart;
+
+ if (String_startsWith(cgroup, str_system_slice)) {
+ cgroup += strlen(str_system_slice);
+
+ if (*cgroup && *cgroup != '/')
+ goto handle_default;
+
+ if (bufsize < 3)
+ return false;
+
+ *buf++ = '[';
+ *buf++ = 'S';
+ *buf++ = ']';
+ bufsize -= 3;
+
+ continue;
+ }
+
+ if (String_startsWith(cgroup, str_machine_slice)) {
+ cgroup += strlen(str_machine_slice);
+
+ if (*cgroup && *cgroup != '/')
+ goto handle_default;
+
+ if (bufsize < 3)
+ return false;
+
+ *buf++ = '[';
+ *buf++ = 'M';
+ *buf++ = ']';
+ bufsize -= 3;
+
+ continue;
+ }
+
+ if (String_startsWith(cgroup, str_user_slice)) {
+ cgroup += strlen(str_user_slice);
+
+ if (*cgroup && *cgroup != '/')
+ goto handle_default;
+
+ if (bufsize < 3)
+ return false;
+
+ *buf++ = '[';
+ *buf++ = 'U';
+ *buf++ = ']';
+ bufsize -= 3;
+
+ if (!String_startsWith(cgroup, str_user_slice_prefix))
+ continue;
+
+ const char* userSliceSlash = strchrnul(cgroup + strlen(str_user_slice_prefix), '/');
+ const char* sliceSpec = userSliceSlash - strlen(str_slice_suffix);
+
+ if (!String_startsWith(sliceSpec, str_slice_suffix))
+ continue;
+
+ const size_t sliceNameLen = sliceSpec - (cgroup + strlen(str_user_slice_prefix));
+
+ if (bufsize < sliceNameLen + 1)
+ return false;
+
+ buf[-1] = ':';
+
+ cgroup += strlen(str_user_slice_prefix);
+ while(cgroup < sliceSpec) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+ cgroup = userSliceSlash;
+
+ *buf++ = ']';
+ bufsize--;
+
+ continue;
+ }
+
+ if (labelLen > strlen(str_slice_suffix) && String_startsWith(nextSlash - strlen(str_slice_suffix), str_slice_suffix)) {
+ const size_t sliceNameLen = labelLen - strlen(str_slice_suffix);
+ if (bufsize < 2 + sliceNameLen)
+ return false;
+
+ *buf++ = '[';
+ bufsize--;
+
+ for(size_t i = sliceNameLen; i; i--) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+
+ *buf++ = ']';
+ bufsize--;
+
+ cgroup = nextSlash;
+
+ continue;
+ }
+
+ if (String_startsWith(cgroup, str_lxc_payload_prefix)) {
+ const size_t cgroupNameLen = labelLen - strlen(str_lxc_payload_prefix);
+ if (bufsize < 6 + cgroupNameLen)
+ return false;
+
+ *buf++ = '[';
+ *buf++ = 'l';
+ *buf++ = 'x';
+ *buf++ = 'c';
+ *buf++ = ':';
+ bufsize -= 5;
+
+ cgroup += strlen(str_lxc_payload_prefix);
+ while(cgroup < nextSlash) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+
+ *buf++ = ']';
+ bufsize--;
+
+ continue;
+ }
+
+ if (String_startsWith(cgroup, str_lxc_monitor_prefix)) {
+ const size_t cgroupNameLen = labelLen - strlen(str_lxc_monitor_prefix);
+ if (bufsize < 6 + cgroupNameLen)
+ return false;
+
+ *buf++ = '[';
+ *buf++ = 'L';
+ *buf++ = 'X';
+ *buf++ = 'C';
+ *buf++ = ':';
+ bufsize -= 5;
+
+ cgroup += strlen(str_lxc_monitor_prefix);
+ while(cgroup < nextSlash) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+
+ *buf++ = ']';
+ bufsize--;
+
+ continue;
+ }
+
+ if (labelLen > strlen(str_service_suffix) && String_startsWith(nextSlash - strlen(str_service_suffix), str_service_suffix)) {
+ const size_t serviceNameLen = labelLen - strlen(str_service_suffix);
+
+ if (String_startsWith(cgroup, "user@")) {
+ cgroup = nextSlash;
+
+ while(*cgroup == '/')
+ cgroup++;
+
+ continue;
+ }
+
+ if (bufsize < serviceNameLen)
+ return false;
+
+ for(size_t i = serviceNameLen; i; i--) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+
+ cgroup = nextSlash;
+
+ continue;
+ }
+
+ if (labelLen > strlen(str_scope_suffix) && String_startsWith(nextSlash - strlen(str_scope_suffix), str_scope_suffix)) {
+ const size_t scopeNameLen = labelLen - strlen(str_scope_suffix);
+
+ if (String_startsWith(cgroup, str_nspawn_scope_prefix)) {
+ const size_t machineScopeNameLen = scopeNameLen - strlen(str_nspawn_scope_prefix);
+ if (bufsize < 6 + machineScopeNameLen)
+ return false;
+
+ const bool is_monitor = String_startsWith(nextSlash, str_nspawn_monitor_label);
+
+ *buf++ = '[';
+ *buf++ = is_monitor ? 'S' : 's';
+ *buf++ = is_monitor ? 'N' : 'n';
+ *buf++ = is_monitor ? 'C' : 'c';
+ *buf++ = ':';
+ bufsize -= 5;
+
+ cgroup += strlen(str_nspawn_scope_prefix);
+ for(size_t i = machineScopeNameLen; i; i--) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+
+ *buf++ = ']';
+ bufsize--;
+
+ cgroup = nextSlash;
+
+ continue;
+ }
+
+ if (bufsize < 1 + scopeNameLen)
+ return false;
+
+ *buf++ = '!';
+ bufsize--;
+
+ for(size_t i = scopeNameLen; i; i--) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+
+ cgroup = nextSlash;
+
+ continue;
+ }
+
+handle_default:
+ // Default behavior: Copy the full label
+ cgroup = labelStart;
+
+ if (bufsize < (size_t)(nextSlash - cgroup))
+ return false;
+
+ while(cgroup < nextSlash) {
+ *buf++ = *cgroup++;
+ bufsize--;
+ }
+ }
+
+ return true;
+}
+
+bool CGroup_filterName(const char *cgroup, char* buf, size_t bufsize) {
+ memset(buf, 0, bufsize);
+
+ return CGroup_filterName_internal(cgroup, buf, bufsize - 1);
+}

© 2014-2024 Faster IT GmbH | imprint | privacy policy