The default resource partition is created in the domain start path if it
is not existing. Even when libvirtd is stopped after shutting down all
domains, the resource partition still exists.
The patch adds code to removes the default resource partition in the
cgroup removal path of the domain. If the default resource partition is
found to have no child cgroup, the default resource partition will be
removed.
Moreover, the code does not remove the user provided resource
partitions.
Signed-off-by: Nikunj A Dadhania <nikunj(a)linux.vnet.ibm.com>
---
src/util/vircgroup.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 0599ba5..4dc0702 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -42,6 +42,7 @@
#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
#include "vircgrouppriv.h"
+#include "dirname.h"
#include "virutil.h"
#include "viralloc.h"
#include "virerror.h"
@@ -3311,6 +3312,59 @@ virCgroupRemoveRecursively(char *grppath)
/**
+ * virCgroupRemoveEmptyParent:
+ *
+ * @group-path: The group path
+ *
+ * Cleanup the libvirt created partition directory if there are no
+ * child group existing. For the given @group-path, find the parent
+ * directory. For resource partition created by libvirt check
+ * existence of child cgroup. Remove the resource partition if no
+ * child cgroup exist.
+ *
+ * Returns: void
+ */
+static void
+virCgroupRemoveEmptyParent(char *grppath)
+{
+ char *parent = NULL, *partition = NULL;
+ struct dirent *ent;
+ DIR *grpdir;
+ int direrr;
+ int is_empty = 1;
+
+ if (!(parent = mdir_name(grppath)))
+ goto cleanup;
+
+ partition = strrchr(parent, '/');
+ if (STRNEQ(partition, "/machine") && STRNEQ(partition,
"/machine.slice"))
+ goto cleanup;
+
+ grpdir = opendir(parent);
+ if (grpdir == NULL)
+ goto cleanup;
+
+ while ((direrr = virDirRead(grpdir, &ent, NULL)) > 0) {
+ if (ent->d_name[0] == '.') continue;
+ if (ent->d_type == DT_DIR) {
+ is_empty = 0;
+ break;
+ }
+ }
+ closedir(grpdir);
+
+ if (is_empty) {
+ VIR_DEBUG("Removing empty parent cgroup %s", parent);
+ if (rmdir(parent) != 0)
+ VIR_ERROR(_("Unable to remove %s (%d)"), parent, errno);
+ }
+
+ cleanup:
+ VIR_FREE(parent);
+ return;
+}
+
+/**
* virCgroupRemove:
*
* @group: The group to be removed
@@ -3352,6 +3406,7 @@ virCgroupRemove(virCgroupPtr group)
VIR_DEBUG("Removing cgroup %s and all child cgroups", grppath);
rc = virCgroupRemoveRecursively(grppath);
+ virCgroupRemoveEmptyParent(grppath);
VIR_FREE(grppath);
}
VIR_DEBUG("Done removing cgroup %s", group->path);
--
2.4.3