chiark / gitweb /
Do not realloc strings, which are already in the hashmap as keys
authorHarald Hoyer <harald@redhat.com>
Wed, 28 Aug 2013 13:33:35 +0000 (15:33 +0200)
committerHarald Hoyer <harald@redhat.com>
Wed, 28 Aug 2013 14:02:57 +0000 (16:02 +0200)
This prevents corruption of the hashmap, because we would free() the
keys in the hashmap, if the unit is already in there, with the same
cgroup path.

src/core/cgroup.c
src/core/unit.c

index 5a1c3adacd19af3f8ff2c67ebcb98ea7ab2e53cd..3eeb47575424f3c853594d122df5e2fe74ee6273 100644 (file)
@@ -382,6 +382,7 @@ static CGroupControllerMask unit_get_siblings_mask(Unit *u) {
 static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
         char *path = NULL;
         int r;
+        bool is_in_hash = false;
 
         assert(u);
 
@@ -390,8 +391,14 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
                 return -ENOMEM;
 
         r = hashmap_put(u->manager->cgroup_unit, path, u);
-        if (r < 0)
+        if (r == 0)
+                is_in_hash = true;
+
+        if (r < 0) {
+                free(path);
+                log_error("cgroup %s exists already: %s", path, strerror(-r));
                 return r;
+        }
 
         /* First, create our own group */
         r = cg_create_with_mask(mask, path);
@@ -405,9 +412,12 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
                         log_error("Failed to migrate cgroup %s: %s", path, strerror(-r));
         }
 
-        /* And remember the new data */
-        free(u->cgroup_path);
-        u->cgroup_path = path;
+        if (!is_in_hash) {
+                /* And remember the new data */
+                free(u->cgroup_path);
+                u->cgroup_path = path;
+        }
+
         u->cgroup_realized = true;
         u->cgroup_mask = mask;
 
index 27119b0cd72880797ed770d762b6dc30dc827c36..ab313b9b91b6faa4e8bfdd53a82c9c3e331d2e23 100644 (file)
@@ -2329,7 +2329,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                         free(u->cgroup_path);
                         u->cgroup_path = s;
 
-                        hashmap_put(u->manager->cgroup_unit, s, u);
+                        assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
                         continue;
                 }