chiark / gitweb /
cgroup: don't accidentaly trim on reload
authorLennart Poettering <lennart@poettering.net>
Wed, 20 Apr 2011 01:53:12 +0000 (03:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 20 Apr 2011 01:53:12 +0000 (03:53 +0200)
https://bugzilla.redhat.com/show_bug.cgi?id=678555

src/cgroup.c
src/cgroup.h
src/manager.c
src/manager.h
src/service.c
src/unit.c

index ca19a4fd4768ef55910e64f5337e0184402d6ab3..0c6f20d4b75311bfa2b8b6e5944c26cb534db8b1 100644 (file)
@@ -63,7 +63,7 @@ int cgroup_bonding_realize_list(CGroupBonding *first) {
         return 0;
 }
 
-void cgroup_bonding_free(CGroupBonding *b) {
+void cgroup_bonding_free(CGroupBonding *b, bool remove_or_trim) {
         assert(b);
 
         if (b->unit) {
@@ -82,7 +82,7 @@ void cgroup_bonding_free(CGroupBonding *b) {
                 }
         }
 
-        if (b->realized && b->ours) {
+        if (b->realized && b->ours && remove_or_trim) {
 
                 if (cgroup_bonding_is_empty(b) > 0)
                         cg_delete(b->controller, b->path);
@@ -95,11 +95,11 @@ void cgroup_bonding_free(CGroupBonding *b) {
         free(b);
 }
 
-void cgroup_bonding_free_list(CGroupBonding *first) {
+void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim) {
         CGroupBonding *b, *n;
 
         LIST_FOREACH_SAFE(by_unit, b, n, first)
-                cgroup_bonding_free(b);
+                cgroup_bonding_free(b, remove_or_trim);
 }
 
 void cgroup_bonding_trim(CGroupBonding *b, bool delete_root) {
index a6ac90fb094bfecd7a5d0ba12ad1831aea244d3e..c6dff4313efd40ccc4adf0917cd8c89bde25ed0a 100644 (file)
@@ -53,8 +53,8 @@ struct CGroupBonding {
 int cgroup_bonding_realize(CGroupBonding *b);
 int cgroup_bonding_realize_list(CGroupBonding *first);
 
-void cgroup_bonding_free(CGroupBonding *b);
-void cgroup_bonding_free_list(CGroupBonding *first);
+void cgroup_bonding_free(CGroupBonding *b, bool remove_or_trim);
+void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim);
 
 int cgroup_bonding_install(CGroupBonding *b, pid_t pid);
 int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid);
index b59339b178c7187834fa7614c7c22f21ef32707a..9c817b0e416c30b8d9c5e7264bdb66da8187c67a 100644 (file)
@@ -2654,6 +2654,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
         assert(f);
         assert(fds);
 
+        m->n_serializing ++;
+
         fprintf(f, "current-job-id=%i\n", m->current_job_id);
         fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
 
@@ -2674,10 +2676,15 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
                 fputs(u->meta.id, f);
                 fputc('\n', f);
 
-                if ((r = unit_serialize(u, f, fds)) < 0)
+                if ((r = unit_serialize(u, f, fds)) < 0) {
+                        m->n_serializing --;
                         return r;
+                }
         }
 
+        assert(m->n_serializing > 0);
+        m->n_serializing --;
+
         if (ferror(f))
                 return -EIO;
 
@@ -2781,15 +2788,21 @@ int manager_reload(Manager *m) {
         if ((r = manager_open_serialization(m, &f)) < 0)
                 return r;
 
+        m->n_serializing ++;
+
         if (!(fds = fdset_new())) {
+                m->n_serializing --;
                 r = -ENOMEM;
                 goto finish;
         }
 
-        if ((r = manager_serialize(m, f, fds)) < 0)
+        if ((r = manager_serialize(m, f, fds)) < 0) {
+                m->n_serializing --;
                 goto finish;
+        }
 
         if (fseeko(f, 0, SEEK_SET) < 0) {
+                m->n_serializing --;
                 r = -errno;
                 goto finish;
         }
@@ -2798,6 +2811,9 @@ int manager_reload(Manager *m) {
         manager_clear_jobs_and_units(m);
         manager_undo_generators(m);
 
+        assert(m->n_serializing > 0);
+        m->n_serializing --;
+
         /* Find new unit paths */
         lookup_paths_free(&m->lookup_paths);
         if ((q = lookup_paths_init(&m->lookup_paths, m->running_as)) < 0)
index 4b405d61c1236cf7259be7778c9c59d019794bac..07b92c8e4e94f329af3c2f6cfef494e450e0ae6e 100644 (file)
@@ -223,6 +223,7 @@ struct Manager {
 
         ExecOutput default_std_output, default_std_error;
 
+        int n_serializing;
         int n_deserializing;
 
         unsigned n_installed_jobs;
index 7f8d005f00882f21bfcba666cc347b3b1ed8dc9d..0845d21bad1d9a18f3442cda37250778d8ab775d 100644 (file)
@@ -1470,7 +1470,7 @@ static void service_set_state(Service *s, ServiceState state) {
 
         /* For the inactive states unit_notify() will trim the cgroup,
          * but for exit we have to do that ourselves... */
-        if (state == SERVICE_EXITED)
+        if (state == SERVICE_EXITED && s->meta.manager->n_deserializing <= 0)
                 cgroup_bonding_trim_list(s->meta.cgroup_bondings, true);
 
         if (old_state != state)
index d7405b92ed80d18dd39b9e916a6fd87786e78a9d..aed25e4f215e34f437a8cf55db4b9270fc9e28a4 100644 (file)
@@ -368,7 +368,7 @@ void unit_free(Unit *u) {
                 u->meta.manager->n_in_gc_queue--;
         }
 
-        cgroup_bonding_free_list(u->meta.cgroup_bondings);
+        cgroup_bonding_free_list(u->meta.cgroup_bondings, u->meta.manager->n_serializing <= 0);
 
         free(u->meta.description);
         free(u->meta.fragment_path);