From: Jim Fehlig Date: Fri, 10 May 2013 18:05:00 +0000 (-0600) Subject: Fix starting domains when kernel has no cgroups support X-Git-Tag: v1.0.5.3~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68d92eea16223d29627934a0169bff15795dda96;p=thirdparty%2Flibvirt.git Fix starting domains when kernel has no cgroups support Found that I was unable to start existing domains after updating to a kernel with no cgroups support # zgrep CGROUP /proc/config.gz # CONFIG_CGROUPS is not set # virsh start test error: Failed to start domain test error: Unable to initialize /machine cgroup: Cannot allocate memory virCgroupPartitionNeedsEscaping() correctly returns errno (ENOENT) when attempting to open /proc/cgroups on such a system, but it was being dropped in virCgroupSetPartitionSuffix(). Change virCgroupSetPartitionSuffix() to propagate errors returned by its callees. Also check for ENOENT in qemuInitCgroup() when determining if cgroups support is available. (cherry picked from commit bbe97ae968eba60b71e0066d49f9fc909966d9d6) --- diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 400a2b39b8..5745085c76 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -415,7 +415,8 @@ int qemuInitCgroup(virQEMUDriverPtr driver, if (rc != 0) { if (rc == -ENXIO || rc == -EPERM || - rc == -EACCES) { /* No cgroups mounts == success */ + rc == -EACCES || + rc == -ENOENT) { /* No cgroups mounts == success */ VIR_DEBUG("No cgroups present/configured/accessible, ignoring error"); goto done; } diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 028ef2c40e..4abe1b17c7 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1180,14 +1180,14 @@ static int virCgroupPartitionEscape(char **path) return 0; } -static char *virCgroupSetPartitionSuffix(const char *path) +static int virCgroupSetPartitionSuffix(const char *path, char **res) { char **tokens = virStringSplit(path, "/", 0); size_t i; - char *ret = NULL; + int ret = -1; if (!tokens) - return NULL; + return ret; for (i = 0 ; tokens[i] != NULL ; i++) { /* Whitelist the 3 top level fixed dirs @@ -1206,20 +1206,27 @@ static char *virCgroupSetPartitionSuffix(const char *path) !strchr(tokens[i], '.')) { if (VIR_REALLOC_N(tokens[i], strlen(tokens[i]) + strlen(".partition") + 1) < 0) { + ret = -ENOMEM; virReportOOMError(); goto cleanup; } strcat(tokens[i], ".partition"); } - if (virCgroupPartitionEscape(&(tokens[i])) < 0) { - virReportOOMError(); + ret = virCgroupPartitionEscape(&(tokens[i])); + if (ret < 0) { + if (ret == -ENOMEM) + virReportOOMError(); goto cleanup; } } - if (!(ret = virStringJoin((const char **)tokens, "/"))) + if (!(*res = virStringJoin((const char **)tokens, "/"))) { + ret = -ENOMEM; goto cleanup; + } + + ret = 0; cleanup: virStringFreeList(tokens); @@ -1254,9 +1261,9 @@ int virCgroupNewPartition(const char *path, /* XXX convert all cgroups APIs to use error report * APIs instead of returning errno */ - if (!(newpath = virCgroupSetPartitionSuffix(path))) { + rc = virCgroupSetPartitionSuffix(path, &newpath); + if (rc < 0) { virResetLastError(); - rc = -ENOMEM; goto cleanup; }