diff -Nru libvirt-1.2.12/debian/changelog libvirt-1.2.12/debian/changelog --- libvirt-1.2.12/debian/changelog 2015-07-08 17:53:27.000000000 +0000 +++ libvirt-1.2.12/debian/changelog 2015-08-21 22:16:53.000000000 +0000 @@ -1,3 +1,10 @@ +libvirt (1.2.12-0ubuntu14.2) vivid; urgency=medium + + * Drop the cgmanager patches - they break under systemd, and are no longer + needed in containers due to lxcfs. (LP: #1486296) + + -- Serge Hallyn Fri, 21 Aug 2015 15:16:17 -0700 + libvirt (1.2.12-0ubuntu14.1) vivid; urgency=medium [ Seyeong Kim ] diff -Nru libvirt-1.2.12/debian/patches/add-cgmanager-support.patch libvirt-1.2.12/debian/patches/add-cgmanager-support.patch --- libvirt-1.2.12/debian/patches/add-cgmanager-support.patch 2015-02-03 18:20:24.000000000 +0000 +++ libvirt-1.2.12/debian/patches/add-cgmanager-support.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,1580 +0,0 @@ -Description: Support cgmanager - Kvm vms and lxc containers work fine. - This version still has quite a bit of debug info, to be removed after - further testing. - The container startup process needed to be tweaked to have the container - enter its cgroup after configuring it. Previously it was entering it as - soon as it was created, then configuring it. We may be able to work around - this if the per-controller placement is actually being tracked correctly. - TODO: The vircgroup test is disabled with cgmanager support - TODO: Libvirt should try to move itself into the root cgroup (using - MovePidAbs("/", getpid) in case a user is starting it from inside a - non-init cgroup. That is not being done because I hit linker errors and - I deemed it non-essential for v1. - TODO: This patch is done intrusively in a "just make it work" manner, - though in my defense basically the same way as the systemd one. If the - feature is not rejected outright upstream, then refactoring the cgroup - support to support all three (systemd, native-fs, and cgmanager) plus any - others, would be worthwhile. -Author: Serge Hallyn -Forwarded: no -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1322677 - -Index: libvirt-1.2.12/configure.ac -=================================================================== ---- libvirt-1.2.12.orig/configure.ac 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/configure.ac 2015-02-03 13:17:30.909744204 -0500 -@@ -2264,6 +2264,20 @@ - AC_DEFINE([TEST_OOM], 1, [Whether malloc OOM checking is enabled]) - fi - -+AC_ARG_ENABLE([cgmanager], -+ [AC_HELP_STRING([--enable-cgmanager], [enable cgmanager support [default=auto]])], -+ [], [enable_cgmanager=auto]) -+if test "x$enable_cgmanager" = "xauto" ; then -+ AC_CHECK_LIB([cgmanager],[cgmanager_create],[enable_cgmanager=yes],[enable_cgmanager=no],[-lnih -lnih-dbus -ldbus-1]) -+fi -+AM_CONDITIONAL([ENABLE_CGMANAGER], [test "x$enable_cgmanager" = "xyes"]) -+ -+AM_COND_IF([ENABLE_CGMANAGER], -+ [PKG_CHECK_MODULES([CGMANAGER], [libcgmanager]) -+ PKG_CHECK_MODULES([NIH], [libnih >= 1.0.2]) -+ PKG_CHECK_MODULES([NIH_DBUS], [libnih-dbus >= 1.0.0]) -+ PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.2.16]) -+ ]) - - AC_ARG_ENABLE([test-locking], - [AS_HELP_STRING([--enable-test-locking], -@@ -2988,6 +3002,7 @@ - AC_MSG_NOTICE([ numad: $with_numad]) - AC_MSG_NOTICE([ XML Catalog: $XML_CATALOG_FILE]) - AC_MSG_NOTICE([ Init script: $with_init_script]) -+AC_MSG_NOTICE([ CGManager: $with_cgmanager]) - AC_MSG_NOTICE([Char device locks: $with_chrdev_lock_files]) - AC_MSG_NOTICE([ Default Editor: $DEFAULT_EDITOR]) - AC_MSG_NOTICE([]) -Index: libvirt-1.2.12/src/Makefile.am -=================================================================== ---- libvirt-1.2.12.orig/src/Makefile.am 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/src/Makefile.am 2015-02-03 13:20:01.669739480 -0500 -@@ -96,6 +96,7 @@ - util/virbitmap.c util/virbitmap.h \ - util/virbuffer.c util/virbuffer.h \ - util/vircgroup.c util/vircgroup.h util/vircgrouppriv.h \ -+ util/cgmanager.c util/cgmanager.h \ - util/virclosecallbacks.c util/virclosecallbacks.h \ - util/vircommand.c util/vircommand.h util/vircommandpriv.h \ - util/virconf.c util/virconf.h \ -@@ -1030,12 +1031,13 @@ - $(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) \ - $(DBUS_CFLAGS) $(LDEXP_LIBM) $(NUMACTL_CFLAGS) \ - $(SYSTEMD_DAEMON_CFLAGS) $(POLKIT_CFLAGS) \ -- -I$(srcdir)/conf -+ -I$(srcdir)/conf \ -+ $(CGMANAGER_CFLAGS) - libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \ - $(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \ - $(LIB_CLOCK_GETTIME) $(DBUS_LIBS) $(MSCOM_LIBS) $(LIBXML_LIBS) \ - $(SECDRIVER_LIBS) $(NUMACTL_LIBS) $(SYSTEMD_DAEMON_LIBS) \ -- $(POLKIT_LIBS) -+ $(CGMANAGER_LIBS) $(POLKIT_LIBS) - - - noinst_LTLIBRARIES += libvirt_conf.la -@@ -1072,6 +1074,9 @@ - libvirt_xenconfig_la_SOURCES = $(XENCONFIG_SOURCES) - endif WITH_XENCONFIG - -+if ENABLE_CGMANAGER -+AM_CFLAGS += -DHAVE_CGMANAGER -+endif - - noinst_LTLIBRARIES += libvirt_driver.la - libvirt_la_BUILT_LIBADD += libvirt_driver.la -Index: libvirt-1.2.12/src/util/cgmanager.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ libvirt-1.2.12/src/util/cgmanager.c 2015-02-03 13:17:30.909744204 -0500 -@@ -0,0 +1,337 @@ -+/* -+ * lxc: linux Container library -+ * -+ * (C) Copyright Canonical Ltd. 2013-2014 -+ * -+ * Authors: -+ * Serge Hallyn -+ * Stéphane Graber -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifdef HAVE_CGMANAGER -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "virutil.h" -+#include "viralloc.h" -+#include "virerror.h" -+#include "virlog.h" -+#include "cgmanager.h" -+ -+static NihDBusProxy *cgroup_manager = NULL; -+bool cgm_running = false; -+ -+VIR_LOG_INIT("util.cgmanager"); -+ -+#define CGMANAGER_DBUS_SOCK "unix:path=/sys/fs/cgroup/cgmanager/sock" -+bool cgm_dbus_connect(void) -+{ -+ DBusError dbus_error; -+ DBusConnection *connection; -+ dbus_error_init(&dbus_error); -+ -+ connection = dbus_connection_open_private(CGMANAGER_DBUS_SOCK, &dbus_error); -+ if (!connection) { -+ dbus_error_free(&dbus_error); -+ return false; -+ } -+ -+ dbus_connection_set_exit_on_disconnect(connection, FALSE); -+ dbus_error_free(&dbus_error); -+ cgroup_manager = nih_dbus_proxy_new(NULL, connection, -+ NULL /* p2p */, -+ "/org/linuxcontainers/cgmanager", NULL, NULL); -+ dbus_connection_unref(connection); -+ if (!cgroup_manager) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: Error opening proxy: %s", nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ // force fd passing negotiation -+ if (cgmanager_ping_sync(NULL, cgroup_manager, 0) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: Error pinging manager: %s", nerr->message); -+ nih_free(nerr); -+ nih_free(cgroup_manager); -+ cgroup_manager = NULL; -+ return false; -+ } -+ cgm_running = true; -+ return true; -+} -+ -+void cgm_dbus_disconnect(void) -+{ -+ if (cgroup_manager) { -+ dbus_connection_flush(cgroup_manager->connection); -+ dbus_connection_close(cgroup_manager->connection); -+ nih_free(cgroup_manager); -+ cgroup_manager = NULL; -+ } -+} -+ -+bool cgm_create(const char *controller, const char *cgroup_path, int32_t *existed) -+{ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if ( cgmanager_create_sync(NULL, cgroup_manager, controller, -+ cgroup_path, existed) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_create for controller=%s, cgroup_path=%s failed: %s", -+ controller, cgroup_path, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool cgm_remove(const char *controller, const char *cgroup_path, int recursive) -+{ -+ int existed; -+ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if ( cgmanager_remove_sync(NULL, cgroup_manager, controller, -+ cgroup_path, recursive, &existed) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_remove for controller=%s, cgroup_path=%s, recursive=%d failed: %s", -+ controller, cgroup_path, recursive, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ if (existed == -1) { -+ VIR_ERROR("cgmanager: cgm_remove failed: %s:%s did not exist", controller, cgroup_path); -+ return false; -+ } -+ return true; -+} -+ -+char *cgm_get(const char *controller, const char *cgroup_path, const char *key) -+{ -+ char *result = NULL; -+ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if (cgmanager_get_value_sync(NULL, cgroup_manager, controller, cgroup_path, key, &result) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_get for controller=%s, cgroup_path=%s failed: %s", -+ controller, cgroup_path, nerr->message); -+ nih_free(nerr); -+ free(result); -+ return NULL; -+ } -+ return result; -+} -+ -+bool cgm_set(const char *controller, const char *cgroup_path, const char *key, const char *val) -+{ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if (cgmanager_set_value_sync(NULL, cgroup_manager, controller, cgroup_path, key, val) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_set for controller=%s, cgroup_path=%s failed: %s", -+ controller, cgroup_path, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ return true; -+} -+ -+bool cgm_chmod(const char *controller, const char *cgroup_path, int mode) -+{ -+ nih_local char *path_dirname = NULL; -+ nih_local char *path_basename = NULL; -+ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ path_dirname = NIH_MUST(nih_strdup(NULL, cgroup_path)); -+ path_basename = NIH_MUST(nih_strdup(NULL, cgroup_path)); -+ -+ if (cgmanager_chmod_sync(NULL, cgroup_manager, controller, -+ dirname(path_dirname), basename(path_basename), mode) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_chmod for controller=%s, cgroup_path=%s, mode=%d failed: %s", -+ controller, cgroup_path, mode, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool cgm_chown(const char *controller, const char *cgroup_path, int uid, int gid) -+{ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if (cgmanager_chown_sync(NULL, cgroup_manager, controller, -+ cgroup_path, uid, gid) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_chown for controller=%s, cgroup_path=%s, uid=%d, gid=%d failed: %s", -+ controller, cgroup_path, uid, gid, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool cgm_list_children(const char *controller, const char *cgroup_path, char ***children) -+{ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if ( cgmanager_list_children_sync(NULL, cgroup_manager, controller, -+ cgroup_path, children) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_list_children for controller=%s, cgroup_path=%s failed: %s", -+ controller, cgroup_path, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+/* -+ * caller must nih_free(pids) when done -+ */ -+bool cgm_get_tasks(const char *controller, const char *cgroup_path, pid_t **pids, size_t *nrpids) -+{ -+ int ret; -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ ret = cgmanager_get_tasks_sync(NULL, cgroup_manager, controller, cgroup_path, pids, nrpids); -+ if (ret) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_get_tasks for controller=%s, cgroup_path=%s failed: %s", -+ controller, cgroup_path, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+ -+/* -+ * caller of cgm_get_pid_cgroup must nih_free(path) if we -+ * returned true -+ */ -+bool cgm_get_pid_cgroup(const char *controller, pid_t pid, char **cgpath) -+{ -+ *cgpath = NULL; -+ if ( cgmanager_get_pid_cgroup_sync(NULL, cgroup_manager, controller, -+ pid, cgpath) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+/* -+ * caller of cgm_get_pid_cgroup_abs must nih_free(path) if we -+ * returned true -+ */ -+bool cgm_get_pid_cgroup_abs(const char *controller, pid_t pid, char **cgpath) -+{ -+ *cgpath = NULL; -+ if ( cgmanager_get_pid_cgroup_abs_sync(NULL, cgroup_manager, controller, -+ pid, cgpath) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool cgm_controller_exists(const char *controller) -+{ -+ char *cgroup_name = NULL; -+ -+ if ( cgmanager_get_pid_cgroup_sync(NULL, cgroup_manager, controller, -+ getpid(), &cgroup_name) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ nih_free(nerr); -+ return false; -+ } -+ -+ nih_free(cgroup_name); -+ return true; -+} -+ -+bool cgm_enter(const char *controller, const char *cgroup_path, pid_t pid) -+{ -+ if (cgroup_path[0] == '/') -+ cgroup_path++; -+ -+ if (cgmanager_move_pid_sync(NULL, cgroup_manager, controller, -+ cgroup_path, pid) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_ERROR("cgmanager: cgm_enter for controller=%s, cgroup_path=%s, pid=%d failed: %s", -+ controller, cgroup_path, pid, nerr->message); -+ nih_free(nerr); -+ return false; -+ } -+ return true; -+} -+ -+bool cgm_escape(const char *controller) -+{ -+ if (cgmanager_move_pid_sync(NULL, cgroup_manager, controller, "/", -+ getpid()) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ VIR_DEBUG("cgmanager: Failed escaping to root cgroup for controller %s: %s", -+ controller, nerr->message); -+ nih_free(nerr); -+ } -+ return true; -+} -+#endif -Index: libvirt-1.2.12/src/util/cgmanager.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ libvirt-1.2.12/src/util/cgmanager.h 2015-02-03 13:17:30.913744204 -0500 -@@ -0,0 +1,51 @@ -+/* -+ * lxc: linux Container library -+ * -+ * (C) Copyright Canonical Ltd. 2013-2014 -+ * -+ * Authors: -+ * Serge Hallyn -+ * Stéphane Graber -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifdef HAVE_CGMANAGER -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern bool cgm_running; -+ -+bool cgm_dbus_connect(void); -+void cgm_dbus_disconnect(void); -+bool cgm_create(const char *controller, const char *cgroup_path, int32_t *existed); -+bool cgm_remove(const char *controller, const char *cgroup_path, int recursive); -+char *cgm_get(const char *controller, const char *path, const char *key); -+bool cgm_set(const char *controller, const char *cgroup_path, const char *key, const char *val); -+bool cgm_chmod(const char *controller, const char *cgroup_path, int mode); -+bool cgm_chown(const char *controller, const char *cgroup_path, int uid, int gid); -+bool cgm_list_children(const char *controller, const char *cgroup_path, char ***children); -+bool cgm_get_tasks(const char *controller, const char *cgroup_path, pid_t **pids, size_t *nrpids); -+bool cgm_get_pid_cgroup(const char *controller, pid_t pid, char **cgpath); -+bool cgm_get_pid_cgroup_abs(const char *controller, pid_t pid, char **cgpath); -+bool cgm_controller_exists(const char *controller); -+bool cgm_enter(const char *controller, const char *cgroup_path, pid_t pid); -+bool cgm_escape(const char *controller); -+#endif -Index: libvirt-1.2.12/src/util/vircgroup.c -=================================================================== ---- libvirt-1.2.12.orig/src/util/vircgroup.c 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/src/util/vircgroup.c 2015-02-03 13:17:30.913744204 -0500 -@@ -52,6 +52,7 @@ - #include "virstring.h" - #include "virsystemd.h" - #include "virtypedparam.h" -+#include "cgmanager.h" - - #include "nodeinfo.h" - -@@ -130,6 +131,13 @@ - struct mntent entry; - char buf[CGROUP_MAX_VAL]; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ cgm_dbus_disconnect(); -+ return true; -+ } -+#endif -+ - if (!virFileExists("/proc/cgroups")) - return false; - -@@ -267,6 +275,12 @@ - if (virCgroupPartitionEscape(&scopename) < 0) - goto cleanup; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_running) -+ goto good; -+ VIR_ERROR("cgm was NOT running"); -+#endif -+ - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { - char *tmp; - -@@ -304,6 +318,7 @@ - } - } - -+good: - valid = true; - - cleanup: -@@ -333,6 +348,54 @@ - return 0; - } - -+#ifdef HAVE_CGMANAGER -+static void cg_add_cgroup(virCgroupPtr group, const char *g) -+{ -+ int i = virCgroupControllerTypeFromString(g); -+ if (i < 0) -+ return; -+ if (VIR_STRDUP(group->controllers[i].mountPoint, "/") < 0) { -+ VIR_WARN("Out of memory copying \"/\". Proceeding without cgroup controll %s.", g); -+ return; -+ } -+ group->controllers[i].linkPoint = NULL; -+} -+ -+static bool cg_get_cgroups(virCgroupPtr group) -+{ -+ FILE *fin = NULL; -+ char *line = NULL; -+ size_t len = 0; -+ -+ if (!cgm_dbus_connect()) { -+ return false; -+ } -+ /* check to see if name=systemd is mounted */ -+ if (cgm_controller_exists("name=systemd")) -+ cg_add_cgroup(group, "name=systemd"); -+ cgm_dbus_disconnect(); -+ fin = fopen("/proc/cgroups", "r"); -+ if (fin == NULL) { -+ virReportSystemError(errno, "%s", -+ _("Unable to open /proc/cgroups")); -+ return false; -+ } -+ while (getline(&line, &len, fin) > 0) { -+ char *p; -+ if (line[0] == '#') -+ continue; -+ p = strchr(line, '\t'); -+ if (p) -+ *p = '\0'; -+ cg_add_cgroup(group, line); -+ } -+ VIR_FREE(line); -+ VIR_FORCE_FCLOSE(fin); -+ return true; -+} -+#else -+#define cg_get_cgroups(x) (false) -+#endif - - /* - * Process /proc/mounts figuring out what controllers are -@@ -346,6 +409,9 @@ - struct mntent entry; - char buf[CGROUP_MAX_VAL]; - -+ if (cg_get_cgroups(group)) -+ return 0; -+ - mounts = fopen("/proc/mounts", "r"); - if (mounts == NULL) { - virReportSystemError(errno, "%s", -@@ -473,6 +539,55 @@ - } - - -+#ifdef HAVE_CGMANAGER -+static bool -+cg_detect_placement(virCgroupPtr group, -+ pid_t pid, -+ const char *path) -+{ -+ int i; -+ bool ret = false; -+ -+ VIR_DEBUG("cgm: Detecting placement for pid %lld path %s", -+ (unsigned long long)pid, path); -+ if (!cgm_dbus_connect()) -+ return false; -+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -+ const char *typestr = virCgroupControllerTypeToString(i); -+ char *selfpath; -+ if (!group->controllers[i].mountPoint) -+ continue; -+ if (!cgm_get_pid_cgroup(typestr, pid == -1 ? getpid() : pid, &selfpath)) { -+ VIR_WARN("Failed to get cgroup path for %s", typestr); -+ goto out; -+ } -+ if (virAsprintf(&group->controllers[i].placement, -+ "%s%s%s", selfpath, -+ (STREQ(selfpath, "/") || -+ STREQ(path, "") ? "" : "/"), -+ path) < 0) { -+ VIR_WARN("Failed to save cgroup path"); -+ nih_free(selfpath); -+ goto out; -+ } -+ nih_free(selfpath); -+ } -+ ret = true; -+ -+ VIR_DEBUG("cgm: done detecting placement for pid %lld path %s", -+ (unsigned long long)pid, path); -+out: -+ cgm_dbus_disconnect(); -+ return ret; -+} -+#else -+static inline bool -+cg_detect_placement(virCgroupPtr group, -+ pid_t pid, -+ const char *path) -+{ return false; } -+#endif -+ - /* - * virCgroupDetectPlacement: - * @group: the group to process -@@ -495,7 +610,7 @@ - * - * It then appends @path to each detected path. - */ --static int -+int - virCgroupDetectPlacement(virCgroupPtr group, - pid_t pid, - const char *path) -@@ -506,6 +621,9 @@ - int ret = -1; - char *procfile; - -+ if (cg_detect_placement(group, pid, path)) -+ return 0; -+ - VIR_DEBUG("Detecting placement for pid %lld path %s", - (unsigned long long)pid, path); - if (pid == -1) { -@@ -635,6 +753,9 @@ - if (!((1 << j) & controllers)) - continue; - -+#ifdef HAVE_CGMANAGER -+ if (!cgm_running) -+#endif - if (STREQ_NULLABLE(group->controllers[i].mountPoint, - group->controllers[j].mountPoint)) { - virReportSystemError(EINVAL, -@@ -712,6 +833,14 @@ - char *keypath = NULL; - char *tmp = NULL; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ ret = cgm_set(virCgroupControllerTypeToString(controller), group->path, -+ key, value) ? 0 : -1; -+ cgm_dbus_disconnect(); -+ return ret; -+ } -+#endif - if (virCgroupPathOfController(group, controller, key, &keypath) < 0) - return -1; - -@@ -748,11 +877,26 @@ - - *value = NULL; - -+ VIR_DEBUG("Get value %s", keypath); -+ -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ char *strval = NULL; -+ strval = cgm_get(virCgroupControllerTypeToString(controller), group->path, key); -+ cgm_dbus_disconnect(); -+ if (!strval) { -+ VIR_ERROR("failed to get %s for %s", key, group->path); -+ goto cleanup; -+ } -+ if (VIR_STRDUP(*value, strval) >=0 ) -+ ret = 0; -+ nih_free(strval); -+ return ret; -+ } -+#endif - if (virCgroupPathOfController(group, controller, key, &keypath) < 0) - return -1; - -- VIR_DEBUG("Get value %s", keypath); -- - if ((rc = virFileReadAll(keypath, 1024*1024, value)) < 0) { - virReportSystemError(errno, - _("Unable to read from '%s'"), keypath); -@@ -783,6 +927,12 @@ - if (virAsprintf(&strval, "%llu", value) < 0) - return -1; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ ret = cgm_set(virCgroupControllerTypeToString(controller), group->path, key, strval) ? 0 : -1; -+ cgm_dbus_disconnect(); -+ } else -+#endif - ret = virCgroupSetValueStr(group, controller, key, strval); - - VIR_FREE(strval); -@@ -803,6 +953,12 @@ - if (virAsprintf(&strval, "%lld", value) < 0) - return -1; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ ret = cgm_set(virCgroupControllerTypeToString(controller), group->path, key, strval) ? 0 : -1; -+ cgm_dbus_disconnect(); -+ } else -+#endif - ret = virCgroupSetValueStr(group, controller, key, strval); - - VIR_FREE(strval); -@@ -820,6 +976,16 @@ - char *strval = NULL; - int ret = -1; - -+#ifdef HAVE_CGMANAGER -+ bool usecgm = false; -+ if (cgm_dbus_connect()) { -+ strval = cgm_get(virCgroupControllerTypeToString(controller), group->path, key); -+ cgm_dbus_disconnect(); -+ usecgm = true; -+ if (!strval) -+ goto cleanup; -+ } else -+#endif - if (virCgroupGetValueStr(group, controller, key, &strval) < 0) - goto cleanup; - -@@ -833,6 +999,11 @@ - ret = 0; - - cleanup: -+#ifdef HAVE_CGMANAGER -+ if (usecgm) -+ nih_free(strval); -+ else -+#endif - VIR_FREE(strval); - return ret; - } -@@ -874,6 +1045,12 @@ - "cpuset.mems", - }; - -+#ifdef HAVE_CGMANAGER -+ /* cgmanager will have set up inheritence for us */ -+ if (cgm_running) -+ return 0; -+#endif -+ - VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path); - for (i = 0; i < ARRAY_CARDINALITY(inherit_values); i++) { - char *value; -@@ -906,6 +1083,11 @@ - unsigned long long value; - const char *filename = "memory.use_hierarchy"; - -+#ifdef HAVE_CGMANAGER -+ /* cgmanager will have set up inheritence for us */ -+ if (cgm_running) -+ return 0; -+#endif - if (virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - filename, &value) < 0) -@@ -933,6 +1115,11 @@ - { - size_t i; - int ret = -1; -+#ifdef HAVE_CGMANAGER -+ bool usecgm = false; -+ if (cgm_dbus_connect()) -+ usecgm = true; -+#endif - - VIR_DEBUG("Make group %s", group->path); - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -@@ -951,6 +1138,15 @@ - continue; - } - -+#ifdef HAVE_CGMANAGER -+ if (usecgm) { -+ int32_t existed; -+ if (!cgm_create(virCgroupControllerTypeToString(i), -+ group->path, &existed)) -+ goto cleanup; -+ continue; -+ } -+#endif - if (virCgroupPathOfController(group, i, "", &path) < 0) - return -1; - -@@ -1015,6 +1211,10 @@ - ret = 0; - - cleanup: -+#ifdef HAVE_CGMANAGER -+ if (usecgm) -+ cgm_dbus_disconnect(); -+#endif - return ret; - } - -@@ -1096,6 +1296,19 @@ - if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) - continue; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ if (!cgm_enter(virCgroupControllerTypeToString(i), group->path, pid)) { -+ cgm_dbus_disconnect(); -+ VIR_ERROR("Failed to move %d to %s:%s", pid, -+ virCgroupControllerTypeToString(i), group->path); -+ goto cleanup; -+ } -+ cgm_dbus_disconnect(); -+ VIR_INFO("Moved %d to %s:%s", pid, -+ virCgroupControllerTypeToString(i), group->path); -+ } else -+#endif - if (virCgroupSetValueU64(group, i, "tasks", pid) < 0) - goto cleanup; - } -@@ -1131,6 +1344,20 @@ - return -1; - } - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ if (!cgm_enter(virCgroupControllerTypeToString(controller), group->path, pid)) { -+ cgm_dbus_disconnect(); -+ VIR_ERROR("Failed to move %d to %s:%s", pid, -+ virCgroupControllerTypeToString(controller), group->path); -+ return -1; -+ } -+ cgm_dbus_disconnect(); -+ VIR_INFO("Moved %d to %s:%s", pid, -+ virCgroupControllerTypeToString(controller), group->path); -+ return 0; -+ } else -+#endif - return virCgroupSetValueU64(group, controller, "tasks", - (unsigned long long)pid); - } -@@ -1195,8 +1422,15 @@ - int ret = -1; - char *content = NULL; - size_t i; -+#ifdef HAVE_CGMANAGER -+ bool usecgm = false; -+ -+ if (cgm_dbus_connect()) -+ usecgm = true; -+#endif - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -+ bool firstrun = true; - if (!src_group->controllers[i].mountPoint || - !dest_group->controllers[i].mountPoint) - continue; -@@ -1210,6 +1444,35 @@ - * aware that it needs to move. Therefore, we must iterate - * until content is empty. */ - while (1) { -+#ifdef HAVE_CGMANAGER -+ const char *typestr = virCgroupControllerTypeToString(i); -+ pid_t *pids = NULL; -+ size_t j, nrpids; -+ if (usecgm) { -+ if (!cgm_get_tasks(typestr, src_group->path, &pids, &nrpids)) { -+ if (firstrun) -+ goto cleanup; -+ else -+ break; -+ } -+ firstrun = false; -+ if (nrpids) { -+ for (j=0; jpath, pids[j])) { -+ VIR_ERROR("Failed to move pid %d from %s to %s", -+ pids[j], src_group->path, dest_group->path); -+ } -+ } -+ nih_free(pids); -+ VIR_INFO("Moved %d pids to %s:%s", (int) nrpids, typestr, -+ dest_group->path); -+ } else { -+ VIR_WARN("No pids found in %s:%s", typestr, src_group->path); -+ break; -+ } -+ continue; -+ } -+#endif - VIR_FREE(content); - if (virCgroupGetValueStr(src_group, i, "tasks", &content) < 0) - return -1; -@@ -1225,6 +1488,10 @@ - ret = 0; - cleanup: - VIR_FREE(content); -+#ifdef HAVE_CGMANAGER -+ if (usecgm) -+ cgm_dbus_disconnect(); -+#endif - return ret; - } - -@@ -1666,7 +1933,7 @@ - } - } - -- if (virCgroupAddTask(*group, pidleader) < 0) { -+ if (pidleader != -1 && virCgroupAddTask(*group, pidleader) < 0) { - virErrorPtr saved = virSaveLastError(); - virCgroupRemove(*group); - virCgroupFree(group); -@@ -1724,7 +1991,7 @@ - group) < 0) - goto cleanup; - -- if (virCgroupAddTask(*group, pidleader) < 0) { -+ if (pidleader != -1 && virCgroupAddTask(*group, pidleader) < 0) { - virErrorPtr saved = virSaveLastError(); - virCgroupRemove(*group); - virCgroupFree(group); -@@ -3349,6 +3616,12 @@ - int rc = 0; - size_t i; - char *grppath = NULL; -+#ifdef HAVE_CGMANAGER -+ bool usecgm = false; -+ -+ if (cgm_dbus_connect()) -+ usecgm = true; -+#endif - - VIR_DEBUG("Removing cgroup %s", group->path); - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -@@ -3365,6 +3638,14 @@ - if (STREQ(group->controllers[i].placement, "/")) - continue; - -+#ifdef HAVE_CGMANAGER -+ if (usecgm) { -+ if (!cgm_remove(virCgroupControllerTypeToString(i), -+ group->path, 1)) -+ VIR_WARN("Error removing %s:%s", virCgroupControllerTypeToString(i), group->path); -+ continue; -+ } -+#endif - if (virCgroupPathOfController(group, - i, - NULL, -@@ -3377,6 +3658,10 @@ - } - VIR_DEBUG("Done removing cgroup %s", group->path); - -+#ifdef HAVE_CGMANAGER -+ if (usecgm) -+ cgm_dbus_disconnect(); -+#endif - return rc; - } - -@@ -3481,6 +3766,181 @@ - return (void*)name; - } - -+#ifdef HAVE_CGMANAGER -+/* -+ * return -1 on error, else the controller index -+ */ -+static int cgm_get_controller_path(virCgroupPtr group, -+ int controller) -+{ -+ if (controller == -1) { -+ size_t i; -+ nih_local char *path = NULL; -+ -+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -+ /* Reject any controller in which our cgroup does -+ * not begin with the container name */ -+ VIR_DEBUG("(pid %d) Checking %d ctrl %s mntpt %s placement %s", (int) getpid(), -+ (int)i, virCgroupControllerTypeToString(i), -+ group->controllers[i].mountPoint ? group->controllers[i].mountPoint : "null", -+ group->controllers[i].placement ? group->controllers[i].placement : "null"); -+ if (group->controllers[i].mountPoint && -+ group->controllers[i].placement && -+ STRNEQ(group->controllers[i].placement, "/")) { -+ controller = i; -+ VIR_DEBUG("choosing controller %s", virCgroupControllerTypeToString(i)); -+ break; -+ } -+ -+ VIR_DEBUG("Skipping controller %s where I'm in cgroup %s", -+ virCgroupControllerTypeToString(i), -+ group->controllers[i].placement ? group->controllers[i].placement : "null"); -+ } -+ } -+ if (controller == -1) { -+ virReportSystemError(ENOSYS, "%s", -+ _("cgm_get_controller_path: No controllers are mounted")); -+ return -1; -+ } -+ -+ if (group->controllers[controller].mountPoint == NULL) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("cgm_get_controller_path: Controller '%s' is not mounted"), -+ virCgroupControllerTypeToString(controller)); -+ return -1; -+ } -+ -+ if (group->controllers[controller].placement == NULL) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Controller '%s' is not enabled for group"), -+ virCgroupControllerTypeToString(controller)); -+ return -1; -+ } -+ -+ return controller; -+} -+ -+static int cgm_kill(virCgroupPtr group, int signum, virHashTablePtr pidhash) -+{ -+ bool killedAny = false; -+ int i; -+ bool done = false; -+ const char *controller, *cgpath; -+ int ret = -1; -+ -+ if ((i = cgm_get_controller_path(group, -1)) < 0) { -+ VIR_ERROR("cgm_kill: Could not get controller path"); -+ return -1; -+ } -+ -+ controller = virCgroupControllerTypeToString(i); -+ cgpath = group->controllers[i].placement; -+ -+ /* PIDs may be forking as we kill them, so loop -+ * until there are no new PIDs found -+ */ -+ while (!done) { -+ size_t j, nrpids; -+ int32_t *pids = NULL; -+ unsigned long upid; -+ done = true; -+ -+ if (!cgm_get_tasks(controller, cgpath, &pids, &nrpids)) -+ goto done; -+ for (j = 0; j < nrpids; j++) { -+ upid = pids[j]; -+ if (virHashLookup(pidhash, (void*)upid)) -+ continue; -+ if (kill(pids[j], signum) < 0) { -+ if (errno != ESRCH) { -+ virReportSystemError(errno, -+ _("Failed to kill process %d"), -+ pids[j]); -+ nih_free(pids); -+ goto cleanup; -+ } -+ } else { -+ killedAny = true; -+ done = false; -+ } -+ ignore_value(virHashAddEntry(pidhash, (void*)upid, (void*)1)); -+ } -+ nih_free(pids); -+ } -+ -+ done: -+ ret = killedAny ? 1 : 0; -+ -+cleanup: -+ -+ VIR_DEBUG("cgm_kill: returning %d, killedAny %d", ret, killedAny); -+ return ret; -+} -+ -+static int cgm_kill_recursive(virCgroupPtr group, int signum, virHashTablePtr pidhash) -+{ -+ int i, j, ret; -+ bool killedAny = false; -+ const char *controller, *cgpath; -+ char **children; -+ virCgroupPtr subgroup = NULL; -+ -+ ret = cgm_kill(group, signum, pidhash); -+ if (ret < 0) -+ return ret; -+ if (ret) -+ killedAny = true; -+ -+ if ((i = cgm_get_controller_path(group, -1)) < 0) -+ return -1; -+ controller = virCgroupControllerTypeToString(i); -+ cgpath = group->controllers[i].placement; -+ if (!cgm_list_children(controller, cgpath, &children)) -+ return -1; -+ for (j = 0; children[j]; j++) { -+ if (virCgroupNew(-1, children[j], group, -1, &subgroup) < 0) -+ goto bad; -+ ret = cgm_kill_recursive(subgroup, signum, pidhash); -+ if (ret < 0) -+ goto bad; -+ if (ret > 0) -+ killedAny = true; -+ virCgroupFree(&subgroup); -+ } -+ -+ nih_free(children); -+ return killedAny ? 1 : 0; -+ -+bad: -+ virCgroupFree(&subgroup); -+ nih_free(children); -+ return -1; -+} -+ -+static int cgm_remove_children(virCgroupPtr group) -+{ -+ int i; -+ int ret = 0; -+ const char *controller, *cgpath; -+ -+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -+ if (!group->controllers[i].mountPoint) -+ continue; -+ if (!group->controllers[i].placement) -+ continue; -+ if (!STRNEQ(group->controllers[i].placement, "/")) -+ continue; -+ controller = virCgroupControllerTypeToString(i), -+ cgpath = group->controllers[i].placement; -+ if (!cgm_remove(controller, cgpath, 1)) { -+ VIR_ERROR("Failed to remove %s:%s", controller, cgpath); -+ ret = -1; -+ } -+ } -+ -+ return ret; -+} -+#endif - - /* - * Returns 1 if some PIDs are killed, 0 if none are killed, or -1 on error -@@ -3490,6 +3950,7 @@ - { - VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); - int ret; -+ - /* The 'tasks' file in cgroups can contain duplicated - * pids, so we use a hash to track which we've already - * killed. -@@ -3501,6 +3962,12 @@ - virCgroupPidCopy, - NULL); - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ ret = cgm_kill(group, signum, pids); -+ cgm_dbus_disconnect(); -+ } else -+#endif - ret = virCgroupKillInternal(group, signum, pids); - - virHashFree(pids); -@@ -3591,6 +4058,7 @@ - { - int ret; - VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); -+ - virHashTablePtr pids = virHashCreateFull(100, - NULL, - virCgroupPidCode, -@@ -3598,6 +4066,14 @@ - virCgroupPidCopy, - NULL); - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ ret = cgm_kill_recursive(group, signum, pids); -+ if (ret == 0) -+ ret = cgm_remove_children(group); -+ cgm_dbus_disconnect(); -+ } else -+#endif - ret = virCgroupKillRecursiveInternal(group, signum, pids, false); - - virHashFree(pids); -@@ -3756,6 +4232,50 @@ - "freezer.state", state); - } - -+#ifdef HAVE_CGMANAGER -+static bool cgm_bind_cgsocket(const char *oldroot) -+{ -+ int ret; -+ struct stat st; -+ char path[1024]; -+ -+ ret = snprintf(path, 1024, "%s/sys/fs/cgroup/cgmanager/sock", oldroot); -+ if (ret < 0 || ret >= 1024) -+ return false; -+ ret = stat(path, &st); -+ if (ret != 0) { -+ VIR_ERROR("%s/sys/fs/cgroup/cgmanager not found", oldroot); -+ return false; -+ } -+ -+ ret = stat("/sys/fs/cgroup/cgmanager", &st); -+ if (ret == 0) -+ goto do_bind; -+ ret = stat("/sys/fs/cgroup", &st); -+ if (ret != 0) -+ return false; -+ if (mount("cgroup", "/sys/fs/cgroup", "tmpfs", 0, "size=10000,mode=755") < 0) { -+ VIR_ERROR("Failed mounting tmpfs onto sys/fs/cgroup"); -+ return false; -+ } -+ if (virFileMakePath("/sys/fs/cgroup/cgmanager") < 0) { -+ if (mkdir("/sys/fs/cgroup/cgmanager", 0755) < 0) { -+ VIR_ERROR("mkdir by hand failed: %m"); -+ return false; -+ } -+ } -+ -+do_bind: -+ sprintf(path, "%s/sys/fs/cgroup/cgmanager", oldroot); -+ if (mount(path, "sys/fs/cgroup/cgmanager", "none", -+ MS_BIND, 0) < 0) { -+ VIR_ERROR("Failed bind-mounting the cgmanager socket"); -+ return false; -+ } -+ VIR_INFO("bind-mounted the cgmanager socket"); -+ return true; -+} -+#endif - - int - virCgroupIsolateMount(virCgroupPtr group, const char *oldroot, -@@ -3766,6 +4286,11 @@ - char *opts = NULL; - char *root = NULL; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_bind_cgsocket(oldroot)) -+ return 0; -+#endif -+ - if (!(root = virCgroupIdentifyRoot(group))) - return -1; - -@@ -3855,6 +4380,11 @@ - size_t i; - char *base = NULL, *entry = NULL; - DIR *dh = NULL; -+#ifdef HAVE_CGMANAGER -+ bool usecgm = false; -+ if (cgm_dbus_connect()) -+ usecgm = true; -+#endif - int direrr; - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { -@@ -3866,6 +4396,19 @@ - if (!cgroup->controllers[i].mountPoint) - continue; - -+#ifdef HAVE_CGMANAGER -+ if (usecgm) { -+ if (!cgm_chown(virCgroupControllerTypeToString(i), -+ cgroup->path, uid, gid)) { -+ VIR_ERROR("Failed to chown cgroup %s:%s to %d:%d", -+ virCgroupControllerTypeToString(i), cgroup->path, -+ uid, gid); -+ goto cleanup; -+ } -+ continue; -+ } -+#endif -+ - if (virAsprintf(&base, "%s%s", cgroup->controllers[i].mountPoint, - cgroup->controllers[i].placement) < 0) - goto cleanup; -@@ -3915,6 +4458,10 @@ - closedir(dh); - VIR_FREE(entry); - VIR_FREE(base); -+#ifdef HAVE_CGMANAGER -+ if (usecgm) -+ cgm_dbus_disconnect(); -+#endif - return ret; - } - -@@ -3935,6 +4482,19 @@ - if (!cgroup) - return false; - -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) { -+ char *str; -+ str = cgm_get(virCgroupControllerTypeToString(VIR_CGROUP_CONTROLLER_CPU), -+ cgroup->path, "cpu.cfs_period_us"); -+ cgm_dbus_disconnect(); -+ if (str) { -+ ret = true; -+ nih_free(str); -+ } -+ return ret; -+ } -+#endif - if (virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, - "cpu.cfs_period_us", &path) < 0) { - virResetLastError(); -@@ -3966,6 +4526,16 @@ - return ret; - } - -+void virCgroupEscape(void) { -+#ifdef HAVE_CGMANAGER -+ int i; -+ if (cgm_dbus_connect()) { -+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) -+ cgm_escape(virCgroupControllerTypeToString(i)); -+ cgm_dbus_disconnect(); -+ } -+#endif -+} - #else /* !VIR_CGROUP_SUPPORTED */ - - bool -@@ -4705,4 +5275,6 @@ - return -1; - } - -+void virCgroupEscape(void) { -+} - #endif /* !VIR_CGROUP_SUPPORTED */ -Index: libvirt-1.2.12/tests/Makefile.am -=================================================================== ---- libvirt-1.2.12.orig/tests/Makefile.am 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/tests/Makefile.am 2015-02-03 13:17:30.913744204 -0500 -@@ -979,8 +979,9 @@ - -rpath /evil/libtool/hack/to/force/shared/lib/creation - - vircgrouptest_SOURCES = \ -- vircgrouptest.c testutils.h testutils.c --vircgrouptest_LDADD = $(LDADDS) -+ vircgrouptest.c testutils.h testutils.c ../src/util/cgmanager.c -+vircgrouptest_LDADD = $(LDADDS) $(CGMANAGER_LIBS) -+vircgrouptest_CFLAGS = $(AM_CFLAGS) $(CGMANAGER_CFLAGS) -DHAVE_CGMANAGER - - vircgroupmock_la_SOURCES = \ - vircgroupmock.c -Index: libvirt-1.2.12/tests/vircgrouptest.c -=================================================================== ---- libvirt-1.2.12.orig/tests/vircgrouptest.c 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/tests/vircgrouptest.c 2015-02-03 13:17:30.913744204 -0500 -@@ -34,6 +34,7 @@ - # include "virfile.h" - # include "testutilslxc.h" - # include "nodeinfo.h" -+# include "cgmanager.h" - - # define VIR_FROM_THIS VIR_FROM_NONE - -@@ -781,6 +782,14 @@ - int ret = 0; - char *fakesysfsdir; - -+#ifdef HAVE_CGMANAGER -+ /* TODO make tests work with cgmanager */ -+ if (cgm_dbus_connect()) { -+ cgm_dbus_disconnect(); -+ return 0; -+ } -+#endif -+ - if (VIR_STRDUP_QUIET(fakesysfsdir, FAKESYSFSDIRTEMPLATE) < 0) { - fprintf(stderr, "Out of memory\n"); - abort(); -Index: libvirt-1.2.12/daemon/libvirtd.c -=================================================================== ---- libvirt-1.2.12.orig/daemon/libvirtd.c 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/daemon/libvirtd.c 2015-02-03 13:17:30.913744204 -0500 -@@ -49,6 +49,7 @@ - #include "viralloc.h" - #include "virconf.h" - #include "virnetlink.h" -+#include "vircgroup.h" - #include "virnetserver.h" - #include "remote.h" - #include "virhook.h" -@@ -1263,6 +1264,10 @@ - exit(EXIT_FAILURE); - } - -+ /* move ourselves to root cgroup if necessary */ -+ // XXX todo - figure out how to get the fn included -+ // virCgroupEscape(); -+ - if (daemonSetupLogging(config, privileged, verbose, godaemon) < 0) { - VIR_ERROR(_("Can't initialize logging")); - exit(EXIT_FAILURE); -Index: libvirt-1.2.12/daemon/Makefile.am -=================================================================== ---- libvirt-1.2.12.orig/daemon/Makefile.am 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/daemon/Makefile.am 2015-02-03 13:18:50.985741695 -0500 -@@ -105,14 +105,16 @@ - $(XDR_CFLAGS) \ - $(WARN_CFLAGS) $(PIE_CFLAGS) \ - $(COVERAGE_CFLAGS) \ -+ $(CGMANAGER_CFLAGS) \ - $(NULL) - libvirtd_conf_la_LDFLAGS = \ - $(RELRO_LDFLAGS) \ - $(PIE_LDFLAGS) \ - $(COVERAGE_LDFLAGS) \ - $(NO_INDIRECT_LDFLAGS) \ -+ $(NO_INDIRECT_LDFLAGS) \ - $(NULL) --libvirtd_conf_la_LIBADD = $(LIBXML_LIBS) -+libvirtd_conf_la_LIBADD = $(LIBXML_LIBS) $(CGMANAGER_LIBS) - - man8_MANS = libvirtd.8 - -@@ -143,7 +145,7 @@ - $(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \ - $(XDR_CFLAGS) $(DBUS_CFLAGS) $(LIBNL_CFLAGS) \ - $(WARN_CFLAGS) $(PIE_CFLAGS) \ -- $(COVERAGE_CFLAGS) \ -+ $(COVERAGE_CFLAGS) $(CGMANAGER_CFLAGS) \ - -DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" - - libvirtd_LDFLAGS = \ -@@ -158,6 +160,7 @@ - $(GNUTLS_LIBS) \ - $(SASL_LIBS) \ - $(DBUS_LIBS) \ -+ $(CGMANAGER_LIBS) \ - $(LIBNL_LIBS) - - if WITH_DTRACE_PROBES -Index: libvirt-1.2.12/src/util/vircgroup.h -=================================================================== ---- libvirt-1.2.12.orig/src/util/vircgroup.h 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/src/util/vircgroup.h 2015-02-03 13:17:30.913744204 -0500 -@@ -274,4 +274,9 @@ - - int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller); - -+void virCgroupEscape(void); -+int virCgroupDetectPlacement(virCgroupPtr group, -+ pid_t pid, -+ const char *path); -+ - #endif /* __VIR_CGROUP_H__ */ -Index: libvirt-1.2.12/src/lxc/lxc_cgroup.c -=================================================================== ---- libvirt-1.2.12.orig/src/lxc/lxc_cgroup.c 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/src/lxc/lxc_cgroup.c 2015-02-03 13:17:30.917744204 -0500 -@@ -484,7 +484,7 @@ - true, - def->uuid, - NULL, -- getpid(), -+ -1, - true, - 0, NULL, - def->resource->partition, -Index: libvirt-1.2.12/src/lxc/lxc_controller.c -=================================================================== ---- libvirt-1.2.12.orig/src/lxc/lxc_controller.c 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/src/lxc/lxc_controller.c 2015-02-03 13:17:30.917744204 -0500 -@@ -2184,6 +2184,9 @@ - if (virLXCControllerSetupResourceLimits(ctrl) < 0) - goto cleanup; - -+ if (virCgroupAddTask(ctrl->cgroup, getpid()) < 0) -+ goto cleanup; -+ - if (virLXCControllerSetupDevPTS(ctrl) < 0) - goto cleanup; - -Index: libvirt-1.2.12/src/lxc/lxc_process.c -=================================================================== ---- libvirt-1.2.12.orig/src/lxc/lxc_process.c 2015-02-03 13:17:30.917744204 -0500 -+++ libvirt-1.2.12/src/lxc/lxc_process.c 2015-02-03 13:17:30.917744204 -0500 -@@ -1274,20 +1274,6 @@ - goto cleanup; - } - -- if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid, -- vm->def->resource ? -- vm->def->resource->partition : -- NULL, -- -1, &priv->cgroup) < 0) -- goto error; -- -- if (!priv->cgroup) { -- virReportError(VIR_ERR_INTERNAL_ERROR, -- _("No valid cgroup for machine %s"), -- vm->def->name); -- goto error; -- } -- - priv->stopReason = VIR_DOMAIN_EVENT_STOPPED_FAILED; - priv->wantReboot = false; - vm->def->id = vm->pid; -@@ -1308,6 +1294,20 @@ - goto error; - } - -+ if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid, -+ vm->def->resource ? -+ vm->def->resource->partition : -+ NULL, -+ -1, &priv->cgroup) < 0) -+ goto error; -+ -+ if (!priv->cgroup) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("No valid cgroup for machine %s"), -+ vm->def->name); -+ goto error; -+ } -+ - if (autoDestroy && - virCloseCallbacksSet(driver->closeCallbacks, vm, - conn, lxcProcessAutoDestroy) < 0) diff -Nru libvirt-1.2.12/debian/patches/cgmanager-mutex libvirt-1.2.12/debian/patches/cgmanager-mutex --- libvirt-1.2.12/debian/patches/cgmanager-mutex 2014-12-18 19:27:45.000000000 +0000 +++ libvirt-1.2.12/debian/patches/cgmanager-mutex 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -Index: libvirt-1.2.8/src/util/cgmanager.c -=================================================================== ---- libvirt-1.2.8.orig/src/util/cgmanager.c -+++ libvirt-1.2.8/src/util/cgmanager.c -@@ -35,10 +35,12 @@ - #include "viralloc.h" - #include "virerror.h" - #include "virlog.h" -+#include "virthread.h" - #include "cgmanager.h" - - static NihDBusProxy *cgroup_manager = NULL; - bool cgm_running = false; -+static virMutex cgmanager_lock = VIR_MUTEX_INITIALIZER; - - VIR_LOG_INIT("util.cgmanager"); - -@@ -49,9 +51,12 @@ bool cgm_dbus_connect(void) - DBusConnection *connection; - dbus_error_init(&dbus_error); - -+ virMutexLock(&cgmanager_lock); -+ - connection = dbus_connection_open_private(CGMANAGER_DBUS_SOCK, &dbus_error); - if (!connection) { - dbus_error_free(&dbus_error); -+ virMutexUnlock(&cgmanager_lock); - return false; - } - -@@ -66,6 +71,7 @@ bool cgm_dbus_connect(void) - nerr = nih_error_get(); - VIR_ERROR("cgmanager: Error opening proxy: %s", nerr->message); - nih_free(nerr); -+ virMutexUnlock(&cgmanager_lock); - return false; - } - -@@ -77,6 +83,7 @@ bool cgm_dbus_connect(void) - nih_free(nerr); - nih_free(cgroup_manager); - cgroup_manager = NULL; -+ virMutexUnlock(&cgmanager_lock); - return false; - } - cgm_running = true; -@@ -90,6 +97,7 @@ void cgm_dbus_disconnect(void) - dbus_connection_close(cgroup_manager->connection); - nih_free(cgroup_manager); - cgroup_manager = NULL; -+ virMutexUnlock(&cgmanager_lock); - } - } - diff -Nru libvirt-1.2.12/debian/patches/cgm-ignore-machined-failure libvirt-1.2.12/debian/patches/cgm-ignore-machined-failure --- libvirt-1.2.12/debian/patches/cgm-ignore-machined-failure 2015-04-08 22:47:20.000000000 +0000 +++ libvirt-1.2.12/debian/patches/cgm-ignore-machined-failure 1970-01-01 00:00:00.000000000 +0000 @@ -1,530 +0,0 @@ -Description: Update cgmanager code to work under systemd - . Since systemd-machined is now running, we get actual errors, not just a dbus - method not available error. ignore it since we are using cgmanager. - . Keep track of comounted controllers so we avoid double-cgroup-enter. (This - isn't an issue for qemu where libvirt does the moving, but in lxc the task - moves itself - relative to its current cgroup). - . Use cgm_list_controllers rather than /proc/cgroups to get list of - controllers, it makes comount detection easier. - . Move libvirt to root cgroup so it can manipulate cgroups. - . ignore failure from virCgroupNewMachineSystemd. It used to fail with a - dbus method not available error bc systemd was not running. Now systemd is - running, but we still want to try the manual creation. - . cgm_remove - don't return failure if cgroup doesn't exist. It was probably - removed with its comount (i.e. cpu,cpuacct) -Author: Serge Hallyn - -Index: libvirt-1.2.12/src/util/vircgroup.c -=================================================================== ---- libvirt-1.2.12.orig/src/util/vircgroup.c -+++ libvirt-1.2.12/src/util/vircgroup.c -@@ -337,6 +337,12 @@ virCgroupCopyMounts(virCgroupPtr group, - if (!parent->controllers[i].mountPoint) - continue; - -+#ifdef HAVE_CGMANAGER -+ if (VIR_STRDUP(group->controllers[i].comount, -+ parent->controllers[i].comount) < 0) -+ return -1; -+#endif -+ - if (VIR_STRDUP(group->controllers[i].mountPoint, - parent->controllers[i].mountPoint) < 0) - return -1; -@@ -349,48 +355,50 @@ virCgroupCopyMounts(virCgroupPtr group, - } - - #ifdef HAVE_CGMANAGER --static void cg_add_cgroup(virCgroupPtr group, const char *g) -+static void do_add_cgroup(virCgroupPtr group, char *g, char *comount) - { - int i = virCgroupControllerTypeFromString(g); - if (i < 0) - return; -- if (VIR_STRDUP(group->controllers[i].mountPoint, "/") < 0) { -- VIR_WARN("Out of memory copying \"/\". Proceeding without cgroup controll %s.", g); -- return; -- } -+ if (VIR_STRDUP(group->controllers[i].mountPoint, "/") < 0) -+ VIR_ERROR("Out of memory copying \"/\". for cgroup mountpoint %s", g); - group->controllers[i].linkPoint = NULL; -+ if (comount && VIR_STRDUP(group->controllers[i].comount, comount) < 0) -+ VIR_ERROR("Out of memory copying cgroup comount %s for %s", comount, g); -+} -+ -+static void cg_add_cgroup(virCgroupPtr group, char *g) -+{ -+ char *first = NULL; -+ char *comma = strchr(g, ','); -+ while (comma) { -+ *comma = '\0'; -+ if (!first) -+ first = g; -+ do_add_cgroup(group, g, first); -+ g = comma+1; -+ comma = strchr(g, ','); -+ } -+ do_add_cgroup(group, g, first ? first : g); - } - - static bool cg_get_cgroups(virCgroupPtr group) - { -- FILE *fin = NULL; -- char *line = NULL; -- size_t len = 0; -+ char **list; - - if (!cgm_dbus_connect()) { - return false; - } -- /* check to see if name=systemd is mounted */ -- if (cgm_controller_exists("name=systemd")) -- cg_add_cgroup(group, "name=systemd"); -- cgm_dbus_disconnect(); -- fin = fopen("/proc/cgroups", "r"); -- if (fin == NULL) { -- virReportSystemError(errno, "%s", -- _("Unable to open /proc/cgroups")); -- return false; -+ if (!cgm_list_controllers(&list)) { -+ cgm_dbus_disconnect(); -+ return false; - } -- while (getline(&line, &len, fin) > 0) { -- char *p; -- if (line[0] == '#') -- continue; -- p = strchr(line, '\t'); -- if (p) -- *p = '\0'; -- cg_add_cgroup(group, line); -+ cgm_dbus_disconnect(); -+ -+ for (int i = 0; list[i]; i++) { -+ cg_add_cgroup(group, list[i]); - } -- VIR_FREE(line); -- VIR_FORCE_FCLOSE(fin); -+ nih_free(list); - return true; - } - #else -@@ -1083,11 +1091,6 @@ virCgroupSetMemoryUseHierarchy(virCgroup - unsigned long long value; - const char *filename = "memory.use_hierarchy"; - --#ifdef HAVE_CGMANAGER -- /* cgmanager will have set up inheritence for us */ -- if (cgm_running) -- return 0; --#endif - if (virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - filename, &value) < 0) -@@ -1142,7 +1145,7 @@ virCgroupMakeGroup(virCgroupPtr parent, - if (usecgm) { - int32_t existed; - if (!cgm_create(virCgroupControllerTypeToString(i), -- group->path, &existed)) -+ group->path, &existed) && existed != 1) - goto cleanup; - continue; - } -@@ -1272,6 +1275,24 @@ virCgroupNew(pid_t pid, - return -1; - } - -+static bool in_handled_controllers(char *list, char *which) -+{ -+ char *comma; -+ -+ if (!list) -+ return false; -+ comma = strchr(list, ','); -+ while (comma) { -+ if (strncmp(list, which, comma-list) == 0) -+ return true; -+ list = comma + 1; -+ comma = strchr(list, ','); -+ } -+ if (strcmp(list, which) == 0) -+ return true; -+ return false; -+} -+ - - /** - * virCgroupAddTask: -@@ -1286,6 +1307,9 @@ virCgroupAddTask(virCgroupPtr group, pid - { - int ret = -1; - size_t i; -+#ifdef HAVE_CGMANAGER -+ nih_local char *handled_controllers = NULL; -+#endif - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { - /* Skip over controllers not mounted */ -@@ -1297,6 +1321,8 @@ virCgroupAddTask(virCgroupPtr group, pid - continue; - - #ifdef HAVE_CGMANAGER -+ if (in_handled_controllers(handled_controllers, group->controllers[i].comount)) -+ continue; - if (cgm_dbus_connect()) { - if (!cgm_enter(virCgroupControllerTypeToString(i), group->path, pid)) { - cgm_dbus_disconnect(); -@@ -1307,6 +1333,10 @@ virCgroupAddTask(virCgroupPtr group, pid - cgm_dbus_disconnect(); - VIR_INFO("Moved %d to %s:%s", pid, - virCgroupControllerTypeToString(i), group->path); -+ if (group->controllers[i].comount) -+ NIH_MUST( nih_strcat_sprintf(&handled_controllers, NULL, "%s%s", -+ handled_controllers ? "," : "", -+ group->controllers[i].comount) ); - } else - #endif - if (virCgroupSetValueU64(group, i, "tasks", pid) < 0) -@@ -1318,7 +1348,6 @@ virCgroupAddTask(virCgroupPtr group, pid - return ret; - } - -- - /** - * virCgroupAddTaskController: - * -@@ -1423,6 +1452,7 @@ virCgroupMoveTask(virCgroupPtr src_group - char *content = NULL; - size_t i; - #ifdef HAVE_CGMANAGER -+ nih_local char *handled_controllers = NULL; - bool usecgm = false; - - if (cgm_dbus_connect()) -@@ -1431,6 +1461,14 @@ virCgroupMoveTask(virCgroupPtr src_group - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { - bool firstrun = true; -+#ifdef HAVE_CGMANAGER -+ const char *typestr = virCgroupControllerTypeToString(i); -+ if (in_handled_controllers(handled_controllers, typestr)) -+ continue; -+ NIH_MUST( nih_strcat_sprintf(&handled_controllers, NULL, "%s%s", -+ handled_controllers ? "," : "", -+ src_group->controllers[i].comount) ); -+#endif - if (!src_group->controllers[i].mountPoint || - !dest_group->controllers[i].mountPoint) - continue; -@@ -1445,7 +1483,6 @@ virCgroupMoveTask(virCgroupPtr src_group - * until content is empty. */ - while (1) { - #ifdef HAVE_CGMANAGER -- const char *typestr = virCgroupControllerTypeToString(i); - pid_t *pids = NULL; - size_t j, nrpids; - if (usecgm) { -@@ -1958,6 +1995,14 @@ int virCgroupTerminateMachine(const char - const char *drivername, - bool privileged) - { -+#ifdef HAVE_CGMANAGER -+ bool usecgm = false; -+ if (cgm_dbus_connect()) -+ usecgm = true; -+ cgm_dbus_disconnect(); -+ if (usecgm) -+ return 0; -+#endif - return virSystemdTerminateMachine(name, drivername, privileged); - } - -@@ -2025,9 +2070,17 @@ virCgroupNewMachine(const char *name, - virCgroupPtr *group) - { - int rv; -+ bool usecgm = false; -+#ifdef HAVE_CGMANAGER -+ if (cgm_dbus_connect()) -+ usecgm = true; -+ cgm_dbus_disconnect(); -+#endif - - *group = NULL; - -+ if (usecgm) -+ goto skip; - if ((rv = virCgroupNewMachineSystemd(name, - drivername, - privileged, -@@ -2045,6 +2098,7 @@ virCgroupNewMachine(const char *name, - if (rv == -1) - return -1; - -+skip: - return virCgroupNewMachineManual(name, - drivername, - pidleader, -@@ -2085,6 +2139,7 @@ virCgroupFree(virCgroupPtr *group) - VIR_FREE((*group)->controllers[i].mountPoint); - VIR_FREE((*group)->controllers[i].linkPoint); - VIR_FREE((*group)->controllers[i].placement); -+ VIR_FREE((*group)->controllers[i].comount); - } - - VIR_FREE((*group)->path); -@@ -3830,7 +3885,7 @@ static int cgm_kill(virCgroupPtr group, - - if ((i = cgm_get_controller_path(group, -1)) < 0) { - VIR_ERROR("cgm_kill: Could not get controller path"); -- return -1; -+ return 0; - } - - controller = virCgroupControllerTypeToString(i); -@@ -3865,7 +3920,8 @@ static int cgm_kill(virCgroupPtr group, - } - ignore_value(virHashAddEntry(pidhash, (void*)upid, (void*)1)); - } -- nih_free(pids); -+ if (nrpids) -+ nih_free(pids); - } - - done: -@@ -3873,7 +3929,7 @@ static int cgm_kill(virCgroupPtr group, - - cleanup: - -- VIR_DEBUG("cgm_kill: returning %d, killedAny %d", ret, killedAny); -+ VIR_ERROR("cgm_kill: returning %d, killedAny %d", ret, killedAny); - return ret; - } - -@@ -4526,16 +4582,6 @@ virCgroupHasEmptyTasks(virCgroupPtr cgro - return ret; - } - --void virCgroupEscape(void) { --#ifdef HAVE_CGMANAGER -- int i; -- if (cgm_dbus_connect()) { -- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) -- cgm_escape(virCgroupControllerTypeToString(i)); -- cgm_dbus_disconnect(); -- } --#endif --} - #else /* !VIR_CGROUP_SUPPORTED */ - - bool -@@ -5274,7 +5320,4 @@ virCgroupHasEmptyTasks(virCgroupPtr cgro - _("Control groups not supported on this platform")); - return -1; - } -- --void virCgroupEscape(void) { --} - #endif /* !VIR_CGROUP_SUPPORTED */ -Index: libvirt-1.2.12/daemon/Makefile.am -=================================================================== ---- libvirt-1.2.12.orig/daemon/Makefile.am -+++ libvirt-1.2.12/daemon/Makefile.am -@@ -40,6 +40,8 @@ DAEMON_SOURCES = \ - libvirtd.c libvirtd.h \ - remote.c remote.h \ - stream.c stream.h \ -+ $(top_srcdir)/src/util/cgmanager.c \ -+ $(top_srcdir)/src/util/cgmanager.h \ - $(DAEMON_GENERATED) - - LIBVIRTD_CONF_SOURCES = libvirtd-config.c libvirtd-config.h -@@ -148,6 +150,10 @@ libvirtd_CFLAGS = \ - $(COVERAGE_CFLAGS) $(CGMANAGER_CFLAGS) \ - -DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" - -+if ENABLE_CGMANAGER -+libvirtd_CFLAGS += -DHAVE_CGMANAGER -+endif -+ - libvirtd_LDFLAGS = \ - $(RELRO_LDFLAGS) \ - $(PIE_LDFLAGS) \ -Index: libvirt-1.2.12/daemon/libvirtd.c -=================================================================== ---- libvirt-1.2.12.orig/daemon/libvirtd.c -+++ libvirt-1.2.12/daemon/libvirtd.c -@@ -102,6 +102,7 @@ - # include "nwfilter/nwfilter_driver.h" - # endif - #endif -+#include "util/cgmanager.h" - - #include "configmake.h" - -@@ -1265,8 +1266,7 @@ int main(int argc, char **argv) { - } - - /* move ourselves to root cgroup if necessary */ -- // XXX todo - figure out how to get the fn included -- // virCgroupEscape(); -+ cgm_escape(); - - if (daemonSetupLogging(config, privileged, verbose, godaemon) < 0) { - VIR_ERROR(_("Can't initialize logging")); -Index: libvirt-1.2.12/src/util/cgmanager.c -=================================================================== ---- libvirt-1.2.12.orig/src/util/cgmanager.c -+++ libvirt-1.2.12/src/util/cgmanager.c -@@ -50,6 +50,7 @@ bool cgm_dbus_connect(void) - DBusError dbus_error; - DBusConnection *connection; - dbus_error_init(&dbus_error); -+ static int32_t api_version; - - virMutexLock(&cgmanager_lock); - -@@ -71,21 +72,29 @@ bool cgm_dbus_connect(void) - nerr = nih_error_get(); - VIR_ERROR("cgmanager: Error opening proxy: %s", nerr->message); - nih_free(nerr); -- virMutexUnlock(&cgmanager_lock); -+ virMutexUnlock(&cgmanager_lock); - return false; - } - -- // force fd passing negotiation -- if (cgmanager_ping_sync(NULL, cgroup_manager, 0) != 0) { -+ if (cgmanager_get_api_version_sync(NULL, cgroup_manager, &api_version) != 0) { - NihError *nerr; - nerr = nih_error_get(); -- VIR_ERROR("cgmanager: Error pinging manager: %s", nerr->message); -+ VIR_ERROR("cgmanager: Error getting cgmanager version: %s", nerr->message); - nih_free(nerr); - nih_free(cgroup_manager); - cgroup_manager = NULL; -- virMutexUnlock(&cgmanager_lock); -+ virMutexUnlock(&cgmanager_lock); -+ return false; -+ } -+ -+ if (api_version < 8) { -+ VIR_ERROR("cgmanager version is too old"); -+ nih_free(cgroup_manager); -+ cgroup_manager = NULL; -+ virMutexUnlock(&cgmanager_lock); - return false; - } -+ - cgm_running = true; - return true; - } -@@ -136,10 +145,6 @@ bool cgm_remove(const char *controller, - return false; - } - -- if (existed == -1) { -- VIR_ERROR("cgmanager: cgm_remove failed: %s:%s did not exist", controller, cgroup_path); -- return false; -- } - return true; - } - -@@ -251,10 +256,12 @@ bool cgm_get_tasks(const char *controlle - if (ret) { - NihError *nerr; - nerr = nih_error_get(); -- VIR_ERROR("cgmanager: cgm_get_tasks for controller=%s, cgroup_path=%s failed: %s", -+ if (*nrpids != 0) -+ VIR_ERROR("cgmanager: cgm_get_tasks for controller=%s, cgroup_path=%s failed: %s", - controller, cgroup_path, nerr->message); - nih_free(nerr); -- return false; -+ if (*nrpids != 0) -+ return false; - } - - return true; -@@ -313,6 +320,18 @@ bool cgm_controller_exists(const char *c - return true; - } - -+bool cgm_list_controllers(char ***output) -+{ -+ if ( cgmanager_list_controllers_sync(NULL, cgroup_manager, output) != 0) { -+ NihError *nerr; -+ nerr = nih_error_get(); -+ nih_free(nerr); -+ return false; -+ } -+ -+ return true; -+} -+ - bool cgm_enter(const char *controller, const char *cgroup_path, pid_t pid) - { - if (cgroup_path[0] == '/') -@@ -330,16 +349,21 @@ bool cgm_enter(const char *controller, c - return true; - } - --bool cgm_escape(const char *controller) -+void cgm_escape(void) - { -- if (cgmanager_move_pid_sync(NULL, cgroup_manager, controller, "/", -+ if (!cgm_dbus_connect()) { -+ VIR_ERROR("cgm_escape: failed to connect to cgmanager"); -+ return; -+ } -+ if (cgmanager_move_pid_abs_sync(NULL, cgroup_manager, "all", "/", - getpid()) != 0) { - NihError *nerr; - nerr = nih_error_get(); -- VIR_DEBUG("cgmanager: Failed escaping to root cgroup for controller %s: %s", -- controller, nerr->message); -+ VIR_DEBUG("cgmanager: Failed escaping to root cgroup for %s", -+ nerr->message); - nih_free(nerr); -- } -- return true; -+ } else -+ VIR_DEBUG("Escaped to root cgroup"); -+ cgm_dbus_disconnect(); - } - #endif -Index: libvirt-1.2.12/src/util/cgmanager.h -=================================================================== ---- libvirt-1.2.12.orig/src/util/cgmanager.h -+++ libvirt-1.2.12/src/util/cgmanager.h -@@ -47,5 +47,6 @@ bool cgm_get_pid_cgroup(const char *cont - bool cgm_get_pid_cgroup_abs(const char *controller, pid_t pid, char **cgpath); - bool cgm_controller_exists(const char *controller); - bool cgm_enter(const char *controller, const char *cgroup_path, pid_t pid); --bool cgm_escape(const char *controller); -+void cgm_escape(void); -+bool cgm_list_controllers(char ***output); - #endif -Index: libvirt-1.2.12/src/util/vircgrouppriv.h -=================================================================== ---- libvirt-1.2.12.orig/src/util/vircgrouppriv.h -+++ libvirt-1.2.12/src/util/vircgrouppriv.h -@@ -33,6 +33,7 @@ - - struct virCgroupController { - int type; -+ char *comount; - char *mountPoint; - /* If mountPoint holds several controllers co-mounted, - * then linkPoint is path of the symlink to the mountPoint -Index: libvirt-1.2.12/src/util/vircgroup.h -=================================================================== ---- libvirt-1.2.12.orig/src/util/vircgroup.h -+++ libvirt-1.2.12/src/util/vircgroup.h -@@ -274,7 +274,6 @@ int virCgroupSetOwner(virCgroupPtr cgrou - - int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller); - --void virCgroupEscape(void); - int virCgroupDetectPlacement(virCgroupPtr group, - pid_t pid, - const char *path); diff -Nru libvirt-1.2.12/debian/patches/cgroups-ignore-systemd-failure libvirt-1.2.12/debian/patches/cgroups-ignore-systemd-failure --- libvirt-1.2.12/debian/patches/cgroups-ignore-systemd-failure 2015-02-03 18:21:42.000000000 +0000 +++ libvirt-1.2.12/debian/patches/cgroups-ignore-systemd-failure 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -Description: cgroups: ignore systemd failure - The systemd-shim handles systemd dbus calls, but does not handle the - CreateMachine call sent by libvirt. So if the call to systemd fails, - assume that it failed because we do not have real systemd, and continue - on to try cgmanager and the fileystem. - The eventual correct fix for this is to have systemd-shim handle these - calls. -Author: Serge Hallyn -Forwarded: no - -Index: libvirt-1.2.12/src/util/virsystemd.c -=================================================================== ---- libvirt-1.2.12.orig/src/util/virsystemd.c 2015-02-03 13:20:39.161738305 -0500 -+++ libvirt-1.2.12/src/util/virsystemd.c 2015-02-03 13:21:40.073736396 -0500 -@@ -277,8 +277,10 @@ - 3, - "Slice", "s", slicename, - "After", "as", 1, "libvirtd.service", -- "Before", "as", 1, "libvirt-guests.service") < 0) -+ "Before", "as", 1, "libvirt-guests.service") < 0) { -+ ret = -2; - goto cleanup; -+ } - - if (error.level == VIR_ERR_ERROR) { - if (virDBusErrorIsUnknownMethod(&error)) { -Index: libvirt-1.2.12/tests/virsystemdtest.c -=================================================================== ---- libvirt-1.2.12.orig/tests/virsystemdtest.c 2015-02-03 13:20:39.161738305 -0500 -+++ libvirt-1.2.12/tests/virsystemdtest.c 2015-02-03 13:20:39.161738305 -0500 -@@ -454,6 +454,7 @@ - { - int ret = 0; - -+ return EXIT_AM_SKIP; - if (virtTestRun("Test create container ", testCreateContainer, NULL) < 0) - ret = -1; - if (virtTestRun("Test terminate container ", testTerminateContainer, NULL) < 0) diff -Nru libvirt-1.2.12/debian/patches/series libvirt-1.2.12/debian/patches/series --- libvirt-1.2.12/debian/patches/series 2015-07-08 17:52:58.000000000 +0000 +++ libvirt-1.2.12/debian/patches/series 2015-08-21 22:15:49.000000000 +0000 @@ -14,21 +14,17 @@ fix-ubuntu-xen-qemu-dm-path.patch ubuntu-libxl-qemu-nopath.patch ubuntu-skip-virstoragetest -add-cgmanager-support.patch -cgroups-ignore-systemd-failure 9030-create-socket-dir 9031-enable-lxc-apparmor 9032-lxc-allow-no-security-driver ubuntu-xend-probe.patch ubuntu_machine_type.patch 9034-complete-9p-support -cgmanager-mutex skip-vircgrouptest.patch disable-network-test.patch docs-remove-xpath.patch ubuntu-libxl-migrate-dm.patch 9037-virt-aa-helper-add-unix-channels-esp-for-qemu-guest-.patch -cgm-ignore-machined-failure 9038-qemu-fix-setting-of-VM-CPU-affinity-with-TCG fix_libvirtd_killed_by_sigsegv.patch PowerPC-Make-qemu-system-ppc64-the-default-emulator-.patch