[gnome-system-monitor] Cgroup reform
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-system-monitor] Cgroup reform
- Date: Sat, 22 Oct 2016 17:26:48 +0000 (UTC)
commit 2c1c564401ad42f24a73a162210bba0e0623fb1f
Author: Artem Vorotnikov <artem vorotnikov me>
Date: Sun Oct 16 10:39:14 2016 +0300
Cgroup reform
https://bugzilla.gnome.org/show_bug.cgi?id=773016
src/cgroups.cpp | 201 +++++++++-------------------------------------------
src/cgroups.h | 6 +-
src/proctable.cpp | 4 +-
3 files changed, 39 insertions(+), 172 deletions(-)
---
diff --git a/src/cgroups.cpp b/src/cgroups.cpp
index 603e95f..b75b9fb 100644
--- a/src/cgroups.cpp
+++ b/src/cgroups.cpp
@@ -1,189 +1,58 @@
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-#include <config.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <cstring>
-
#include "cgroups.h"
-#include "application.h"
#include "util.h"
-gboolean
+bool
cgroups_enabled(void)
{
- static gboolean initialized = FALSE;
- static gboolean has_cgroups;
+ static bool initialized = false;
+ static bool has_cgroups;
- if (!initialized) {
- initialized = TRUE;
- has_cgroups = g_file_test("/proc/cgroups", G_FILE_TEST_EXISTS);
+ if (not initialized) {
+ initialized = true;
+ has_cgroups = Glib::file_test("/proc/cgroups", Glib::FileTest::FILE_TEST_EXISTS);
}
return has_cgroups;
}
-static void
-append_cgroup_name(char *line, gchar **current_cgroup_name)
-{
- gchar *controller, *path, *tmp, *path_plus_space;
- int paren_offset, off, tmp_size;
-
- controller = g_strstr_len(line, -1, ":") + 1;
- if (!controller)
- return;
+static std::pair<Glib::ustring, Glib::ustring>
+parse_cgroup_line(const Glib::ustring& line) {
+ auto split = std::vector<Glib::ustring>(Glib::Regex::split_simple(":", line));
+ if (split.size() < 3) { return std::make_pair("", ""); }
+ auto cgroups = split.at(2);
+ if (cgroups.empty() || cgroups == "/") { return std::make_pair("", ""); }
+ auto category = split.at(1);
+ if (category.find("name=") != category.npos) { return std::make_pair("", ""); }
- path = g_strstr_len(controller, -1, ":") + 1;
- if (!path)
- return;
-
- *(path - 1) = '\0';
- g_strdelimit(controller, ",", '/');
-
- if ((std::strcmp(path, "/") == 0) || (std::strncmp(controller, "name=", 5) == 0))
- return;
-
- if (*current_cgroup_name == NULL) {
- *current_cgroup_name = g_strdup_printf("%s (%s)", path, controller);
- return;
- }
-
- /* add a space to the end of the path string */
- path_plus_space = g_strdup_printf("%s ", path);
-
- if ((tmp = g_strstr_len(*current_cgroup_name, -1, path_plus_space))) {
- tmp_size = strlen(*current_cgroup_name) + strlen(controller) + 1;
- paren_offset = g_strstr_len(tmp + strlen(path), -1, ")") - *current_cgroup_name;
- *(*current_cgroup_name + paren_offset) = '\0';
- tmp = (gchar *)g_strnfill(tmp_size, '\0');
- off = g_strlcat(tmp, *current_cgroup_name, tmp_size);
- *(tmp + off) = '/';
- off++;
- off += g_strlcat(tmp + off, controller, tmp_size);
- *(tmp + off) = ')';
- off++;
- g_strlcat(tmp + off, *current_cgroup_name + paren_offset + 1, tmp_size);
- } else
- tmp = g_strdup_printf("%s, %s(%s)", *current_cgroup_name, path_plus_space, controller);
-
- g_free(path_plus_space);
- g_free(*current_cgroup_name);
- *current_cgroup_name = tmp;
+ return std::make_pair(category, cgroups);
}
-static int
-check_cgroup_changed(gchar *line, gchar *current_cgroup_set)
-{
- /* check if line is contained in current_cgroup_set */
- gchar *controller, *path, *tmp, *found, *close_paren, *open_paren;
- int ret = 0;
-
- controller = g_strstr_len(line, -1, ":") + 1;
- if (!controller)
- return 1;
-
- path = g_strstr_len(controller, -1, ":") + 1;
- if (!path)
- return 1;
-
- *(path - 1) = '\0';
+static Glib::ustring
+get_process_cgroup_string(unsigned int pid) {
+ if (not cgroups_enabled())
+ return "";
- if (std::strncmp(controller, "name=", 5) == 0)
- goto out;
-
- /* if there are multiple controllers just report string has changed */
- if (g_strstr_len(controller, -1, ",")) {
- ret = 1;
- goto out;
- }
-
- if (!current_cgroup_set) {
- if (std::strcmp(path, "/") != 0)
- ret = 1;
- goto out;
- }
+ /* read out of /proc/pid/cgroup */
+ auto path = Glib::ustring::compose("/proc/%1/cgroup", pid);
+ Glib::ustring text;
+ try { text = Glib::file_get_contents(path); } catch (...) { return ""; }
+ auto lines = std::vector<Glib::ustring>(Glib::Regex::split_simple("\n", text));
- /* special case for root cgroup */
- tmp = current_cgroup_set;
- if (std::strcmp(path, "/") == 0) {
- while ((found = g_strstr_len(tmp, -1, controller))) {
- close_paren = g_strstr_len(found, -1, ")");
- open_paren = g_strstr_len(found, -1, "(");
- if (close_paren) {
- if (!open_paren || (close_paren < open_paren)) {
- ret = 1;
- goto out;
- }
- }
- tmp = found + strlen(controller);
- }
- goto out;
+ Glib::ustring cgroup_string;
+ for (auto& line : lines) {
+ auto data = parse_cgroup_line(line);
+ if (data.first.empty() || data.second.empty()) { continue; }
+ if (!cgroup_string.empty()) { cgroup_string += ", "; }
+ cgroup_string += Glib::ustring::compose("%1 (%2)", data.second, data.first);
}
- tmp = current_cgroup_set;
- while ((found = g_strstr_len(tmp, -1, path))) {
- found = found + strlen(path);
- close_paren = g_strstr_len(found, -1, ")");
- if (*found == ' ') {
- if (g_strstr_len(found + 1, close_paren - found, controller))
- goto out;
- }
- tmp = close_paren + 1;
- }
- ret = 1;
-out:
- *(path - 1) = ':';
- return ret;
+ return cgroup_string;
}
-void
-get_process_cgroup_info(ProcInfo *info)
-{
- gchar *path;
- gchar *cgroup_name = NULL;
- int cgroups_changed = 0;
- gchar *text;
- char **lines;
- int i;
-
- if (!cgroups_enabled())
- return;
-
- /* read out of /proc/pid/cgroup */
- path = g_strdup_printf("/proc/%d/cgroup", info->pid);
- if (!path)
- return;
- if(!g_file_get_contents(path, &text, NULL, NULL))
- goto out;
- lines = g_strsplit(text, "\n", -1);
- g_free(text);
- if (!lines)
- goto out;
-
- for (i = 0; lines[i] != NULL; i++) {
- if (lines[i][0] == '\0')
- continue;
- if (check_cgroup_changed(lines[i], info->cgroup_name)) {
- cgroups_changed = 1;
- break;
- }
- }
-
- if (cgroups_changed) {
- for (i = 0; lines[i] != NULL; i++) {
- if (lines[i][0] == '\0')
- continue;
- append_cgroup_name(lines[i], &cgroup_name);
- }
- if (info->cgroup_name)
- g_free(info->cgroup_name);
- if (!cgroup_name)
- info->cgroup_name = g_strdup("");
- else
- info->cgroup_name = cgroup_name;
- }
+void get_process_cgroup_info(ProcInfo& info) {
+ auto cgroup_string = get_process_cgroup_string(info.pid);
- g_strfreev(lines);
-out:
- g_free(path);
+ g_free(info.cgroup_name);
+ info.cgroup_name = cgroup_string.empty() ? nullptr : g_strdup(cgroup_string.c_str());
}
diff --git a/src/cgroups.h b/src/cgroups.h
index ec0f4d7..7ddafea 100644
--- a/src/cgroups.h
+++ b/src/cgroups.h
@@ -2,11 +2,9 @@
#ifndef _GSM_CGROUPS_H_
#define _GSM_CGROUPS_H_
-#include <glib.h>
-
#include "application.h"
-void get_process_cgroup_info (ProcInfo *info);
-gboolean cgroups_enabled (void);
+void get_process_cgroup_info (ProcInfo& info);
+bool cgroups_enabled ();
#endif /* _GSM_CGROUPS_H_ */
diff --git a/src/proctable.cpp b/src/proctable.cpp
index 208a289..82c4f82 100644
--- a/src/proctable.cpp
+++ b/src/proctable.cpp
@@ -914,7 +914,7 @@ update_info (GsmApplication *app, ProcInfo *info)
g_assert(info->ppid != -1 || info->pid == 0);
/* get cgroup data */
- get_process_cgroup_info(info);
+ get_process_cgroup_info(*info);
procman::get_process_systemd_info(info);
}
@@ -964,7 +964,7 @@ ProcInfo::ProcInfo(pid_t pid)
get_process_selinux_context (info);
info->cgroup_name = NULL;
- get_process_cgroup_info(info);
+ get_process_cgroup_info(*info);
info->unit = info->session = info->seat = NULL;
get_process_systemd_info(info);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]