Enable support for systemd-machined in cgroups creation

Make the virCgroupNewMachine method try to use systemd-machined
first. If that fails, then fallback to using the traditional
cgroup setup code path.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2013-07-22 16:34:51 +01:00
parent 75304eaa1a
commit 2fe2470181
4 changed files with 179 additions and 20 deletions

View File

@ -1203,8 +1203,9 @@ int virLXCProcessStart(virConnectPtr conn,
goto cleanup;
}
if (virCgroupNewDetectMachine(vm->def->name, "lxc",
vm->pid, -1, &priv->cgroup) < 0)
if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid,
vm->def->resource->partition,
-1, &priv->cgroup) < 0)
goto error;
if (!priv->cgroup) {
@ -1411,8 +1412,9 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
goto error;
if (virCgroupNewDetectMachine(vm->def->name, "lxc",
vm->pid, -1, &priv->cgroup) < 0)
if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid,
vm->def->resource->partition,
-1, &priv->cgroup) < 0)
goto error;
if (!priv->cgroup) {

View File

@ -707,6 +707,7 @@ qemuConnectCgroup(virQEMUDriverPtr driver,
if (virCgroupNewDetectMachine(vm->def->name,
"qemu",
vm->pid,
vm->def->resource->partition,
cfg->cgroupControllers,
&priv->cgroup) < 0)
goto cleanup;

View File

@ -50,6 +50,7 @@
#include "virhash.h"
#include "virhashcode.h"
#include "virstring.h"
#include "virsystemd.h"
#define CGROUP_MAX_VAL 512
@ -102,11 +103,13 @@ static bool
virCgroupValidateMachineGroup(virCgroupPtr group,
const char *name,
const char *drivername,
const char *partition,
bool stripEmulatorSuffix)
{
size_t i;
bool valid = false;
char *partname;
char *scopename;
if (virAsprintf(&partname, "%s.libvirt-%s",
name, drivername) < 0)
@ -115,6 +118,15 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
if (virCgroupPartitionEscape(&partname) < 0)
goto cleanup;
if (!partition)
partition = "/machine";
if (!(scopename = virSystemdMakeScopeName(name, drivername, partition)))
goto cleanup;
if (virCgroupPartitionEscape(&scopename) < 0)
goto cleanup;
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
char *tmp;
@ -142,9 +154,10 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
tmp++;
if (STRNEQ(tmp, name) &&
STRNEQ(tmp, partname)) {
VIR_DEBUG("Name '%s' for controller '%s' does not match '%s' or '%s'",
tmp, virCgroupControllerTypeToString(i), name, partname);
STRNEQ(tmp, partname) &&
STRNEQ(tmp, scopename)) {
VIR_DEBUG("Name '%s' for controller '%s' does not match '%s', '%s' or '%s'",
tmp, virCgroupControllerTypeToString(i), name, partname, scopename);
goto cleanup;
}
}
@ -153,6 +166,7 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
cleanup:
VIR_FREE(partname);
VIR_FREE(scopename);
return valid;
}
#else
@ -1649,6 +1663,7 @@ int virCgroupNewDetect(pid_t pid ATTRIBUTE_UNUSED,
int virCgroupNewDetectMachine(const char *name,
const char *drivername,
pid_t pid,
const char *partition,
int controllers,
virCgroupPtr *group)
{
@ -1658,7 +1673,7 @@ int virCgroupNewDetectMachine(const char *name,
return -1;
}
if (!virCgroupValidateMachineGroup(*group, name, drivername, true)) {
if (!virCgroupValidateMachineGroup(*group, name, drivername, partition, true)) {
VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'",
name, drivername);
virCgroupFree(group);
@ -1668,22 +1683,124 @@ int virCgroupNewDetectMachine(const char *name,
return 0;
}
int virCgroupNewMachine(const char *name,
const char *drivername,
bool privileged ATTRIBUTE_UNUSED,
const unsigned char *uuid ATTRIBUTE_UNUSED,
const char *rootdir ATTRIBUTE_UNUSED,
pid_t pidleader ATTRIBUTE_UNUSED,
bool isContainer ATTRIBUTE_UNUSED,
const char *partition,
int controllers,
virCgroupPtr *group)
/*
* Returns 0 on success, -1 on fatal error, -2 on systemd not available
*/
static int
virCgroupNewMachineSystemd(const char *name,
const char *drivername,
bool privileged,
const unsigned char *uuid,
const char *rootdir,
pid_t pidleader,
bool isContainer,
const char *partition,
int controllers,
virCgroupPtr *group)
{
int ret = -1;
int rv;
virCgroupPtr init, parent = NULL;
char *path = NULL;
char *offset;
VIR_DEBUG("Trying to setup machine '%s' via systemd", name);
if ((rv = virSystemdCreateMachine(name,
drivername,
privileged,
uuid,
rootdir,
pidleader,
isContainer,
partition)) < 0)
return rv;
if (controllers != -1)
controllers |= (1 << VIR_CGROUP_CONTROLLER_SYSTEMD);
VIR_DEBUG("Detecting systemd placement");
if (virCgroupNewDetect(pidleader,
controllers,
&init) < 0)
return -1;
path = init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement;
init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement = NULL;
virCgroupFree(&init);
if (!path || STREQ(path, "/") || path[0] != '/') {
VIR_DEBUG("Systemd didn't setup its controller");
ret = -2;
goto cleanup;
}
offset = path;
if (virCgroupNew(pidleader,
"",
NULL,
controllers,
&parent) < 0)
goto cleanup;
for (;;) {
virCgroupPtr tmp;
char *t = strchr(offset + 1, '/');
if (t)
*t = '\0';
if (virCgroupNew(pidleader,
path,
parent,
controllers,
&tmp) < 0)
goto cleanup;
if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_NONE) < 0) {
virCgroupFree(&tmp);
goto cleanup;
}
if (t) {
*t = '/';
offset = t;
virCgroupFree(&parent);
parent = tmp;
} else {
*group = tmp;
break;
}
}
if (virCgroupAddTask(*group, pidleader) < 0) {
virErrorPtr saved = virSaveLastError();
virCgroupRemove(*group);
virCgroupFree(group);
if (saved) {
virSetError(saved);
virFreeError(saved);
}
}
ret = 0;
cleanup:
virCgroupFree(&parent);
VIR_FREE(path);
return ret;
}
static int
virCgroupNewMachineManual(const char *name,
const char *drivername,
pid_t pidleader,
const char *partition,
int controllers,
virCgroupPtr *group)
{
virCgroupPtr parent = NULL;
int ret = -1;
*group = NULL;
VIR_DEBUG("Fallback to non-systemd setup");
if (virCgroupNewPartition(partition,
STREQ(partition, "/machine"),
controllers,
@ -1719,6 +1836,44 @@ cleanup:
return ret;
}
int virCgroupNewMachine(const char *name,
const char *drivername,
bool privileged,
const unsigned char *uuid,
const char *rootdir,
pid_t pidleader,
bool isContainer,
const char *partition,
int controllers,
virCgroupPtr *group)
{
int rv;
*group = NULL;
if ((rv = virCgroupNewMachineSystemd(name,
drivername,
privileged,
uuid,
rootdir,
pidleader,
isContainer,
partition,
controllers,
group)) == 0)
return 0;
if (rv == -1)
return -1;
return virCgroupNewMachineManual(name,
drivername,
pidleader,
partition,
controllers,
group);
}
bool virCgroupNewIgnoreError(void)
{
if (virLastErrorIsSystemErrno(ENXIO) ||

View File

@ -83,6 +83,7 @@ int virCgroupNewDetect(pid_t pid,
int virCgroupNewDetectMachine(const char *name,
const char *drivername,
pid_t pid,
const char *partition,
int controllers,
virCgroupPtr *group);