summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-02-03 05:25:31 +0100
committerLennart Poettering <lennart@poettering.net>2012-02-03 05:25:31 +0100
commitacb14d318b84bda00d1e666d7dab6794d5bbeb3f (patch)
treebb30240c680d5a92ca61189ba8b0a8ebf2672004
parentcd43ca73e19511f999c80995937e418c35c30ee8 (diff)
cgroup: when getting cgroup empty notifications, always search up the tree
-rw-r--r--TODO7
-rw-r--r--src/cgroup.c46
-rw-r--r--src/cgroup.h1
-rw-r--r--src/login/logind.c16
4 files changed, 57 insertions, 13 deletions
diff --git a/TODO b/TODO
index 74a36a1df..c2113f881 100644
--- a/TODO
+++ b/TODO
@@ -31,7 +31,7 @@ Features:
* write RPM spec macros for presets
-* write man pages for systemd-cgtop, systemd-cat
+* write man pages for systemd-cat
* journal: write man pages for API
@@ -73,8 +73,6 @@ Features:
* move to LGPL2+
-* logind: selinux is borked...
-
* logind: allow showing logout dialog from system
* document that %% can be used to write % in a string that is specifier extended
@@ -164,8 +162,6 @@ Features:
* GC unreferenced jobs (such as .device jobs)
-* cgroup_notify_empty(): recursively check groups up the tree, too
-
* when failing to start a service due to ratelimiting, try again later, if restart=always is set
* write blog stories about:
@@ -175,6 +171,7 @@ Features:
- remote access
- how to pass throw-away units to systemd, or dynamically change properties of existing units
- how to integrate cgconfig and suchlike with systemd
+ - resource control in systemd
* allow port=0 in .socket units
diff --git a/src/cgroup.c b/src/cgroup.c
index 9aff02e7b..182dd59ee 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -355,15 +355,55 @@ void manager_shutdown_cgroup(Manager *m, bool delete) {
m->cgroup_hierarchy = NULL;
}
+int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) {
+ CGroupBonding *b;
+ char *p;
+
+ assert(m);
+ assert(cgroup);
+ assert(bonding);
+
+ b = hashmap_get(m->cgroup_bondings, cgroup);
+ if (!b) {
+ *bonding = b;
+ return 1;
+ }
+
+ p = strdup(cgroup);
+ if (!p)
+ return -ENOMEM;
+
+ for (;;) {
+ char *e;
+
+ e = strrchr(p, '/');
+ if (!e || e == p) {
+ free(p);
+ *bonding = NULL;
+ return 0;
+ }
+
+ *e = 0;
+
+ b = hashmap_get(m->cgroup_bondings, p);
+ if (b) {
+ free(p);
+ *bonding = b;
+ return 1;
+ }
+ }
+}
+
int cgroup_notify_empty(Manager *m, const char *group) {
CGroupBonding *l, *b;
+ int r;
assert(m);
assert(group);
- l = hashmap_get(m->cgroup_bondings, group);
- if (!l)
- return 0;
+ r = cgroup_bonding_get(m, group, &l);
+ if (r <= 0)
+ return r;
LIST_FOREACH(by_path, b, l) {
int t;
diff --git a/src/cgroup.h b/src/cgroup.h
index db4feb916..5faa7dc0f 100644
--- a/src/cgroup.h
+++ b/src/cgroup.h
@@ -86,6 +86,7 @@ pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b);
int manager_setup_cgroup(Manager *m);
void manager_shutdown_cgroup(Manager *m, bool delete);
+int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding);
int cgroup_notify_empty(Manager *m, const char *group);
Unit* cgroup_unit_by_pid(Manager *m, pid_t pid);
diff --git a/src/login/logind.c b/src/login/logind.c
index 8997b4689..7fd6515ff 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -782,12 +782,19 @@ finish:
}
int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
+ Session *s;
char *p;
assert(m);
assert(cgroup);
assert(session);
+ s = hashmap_get(m->cgroups, cgroup);
+ if (s) {
+ *session = s;
+ return 1;
+ }
+
p = strdup(cgroup);
if (!p) {
log_error("Out of memory.");
@@ -795,24 +802,23 @@ int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **sess
}
for (;;) {
- Session *s;
char *e;
- if (isempty(p) || streq(p, "/")) {
+ e = strrchr(p, '/');
+ if (!e || e == p) {
free(p);
*session = NULL;
return 0;
}
+ *e = 0;
+
s = hashmap_get(m->cgroups, p);
if (s) {
free(p);
*session = s;
return 1;
}
-
- assert_se(e = strrchr(p, '/'));
- *e = 0;
}
}