mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
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:
parent
75304eaa1a
commit
2fe2470181
@ -1203,8 +1203,9 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virCgroupNewDetectMachine(vm->def->name, "lxc",
|
if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid,
|
||||||
vm->pid, -1, &priv->cgroup) < 0)
|
vm->def->resource->partition,
|
||||||
|
-1, &priv->cgroup) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!priv->cgroup) {
|
if (!priv->cgroup) {
|
||||||
@ -1411,8 +1412,9 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
|
|||||||
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (virCgroupNewDetectMachine(vm->def->name, "lxc",
|
if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid,
|
||||||
vm->pid, -1, &priv->cgroup) < 0)
|
vm->def->resource->partition,
|
||||||
|
-1, &priv->cgroup) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!priv->cgroup) {
|
if (!priv->cgroup) {
|
||||||
|
@ -707,6 +707,7 @@ qemuConnectCgroup(virQEMUDriverPtr driver,
|
|||||||
if (virCgroupNewDetectMachine(vm->def->name,
|
if (virCgroupNewDetectMachine(vm->def->name,
|
||||||
"qemu",
|
"qemu",
|
||||||
vm->pid,
|
vm->pid,
|
||||||
|
vm->def->resource->partition,
|
||||||
cfg->cgroupControllers,
|
cfg->cgroupControllers,
|
||||||
&priv->cgroup) < 0)
|
&priv->cgroup) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "virhash.h"
|
#include "virhash.h"
|
||||||
#include "virhashcode.h"
|
#include "virhashcode.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "virsystemd.h"
|
||||||
|
|
||||||
#define CGROUP_MAX_VAL 512
|
#define CGROUP_MAX_VAL 512
|
||||||
|
|
||||||
@ -102,11 +103,13 @@ static bool
|
|||||||
virCgroupValidateMachineGroup(virCgroupPtr group,
|
virCgroupValidateMachineGroup(virCgroupPtr group,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *drivername,
|
const char *drivername,
|
||||||
|
const char *partition,
|
||||||
bool stripEmulatorSuffix)
|
bool stripEmulatorSuffix)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
char *partname;
|
char *partname;
|
||||||
|
char *scopename;
|
||||||
|
|
||||||
if (virAsprintf(&partname, "%s.libvirt-%s",
|
if (virAsprintf(&partname, "%s.libvirt-%s",
|
||||||
name, drivername) < 0)
|
name, drivername) < 0)
|
||||||
@ -115,6 +118,15 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
|
|||||||
if (virCgroupPartitionEscape(&partname) < 0)
|
if (virCgroupPartitionEscape(&partname) < 0)
|
||||||
goto cleanup;
|
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++) {
|
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
@ -142,9 +154,10 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
|
|||||||
tmp++;
|
tmp++;
|
||||||
|
|
||||||
if (STRNEQ(tmp, name) &&
|
if (STRNEQ(tmp, name) &&
|
||||||
STRNEQ(tmp, partname)) {
|
STRNEQ(tmp, partname) &&
|
||||||
VIR_DEBUG("Name '%s' for controller '%s' does not match '%s' or '%s'",
|
STRNEQ(tmp, scopename)) {
|
||||||
tmp, virCgroupControllerTypeToString(i), name, partname);
|
VIR_DEBUG("Name '%s' for controller '%s' does not match '%s', '%s' or '%s'",
|
||||||
|
tmp, virCgroupControllerTypeToString(i), name, partname, scopename);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,6 +166,7 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(partname);
|
VIR_FREE(partname);
|
||||||
|
VIR_FREE(scopename);
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1649,6 +1663,7 @@ int virCgroupNewDetect(pid_t pid ATTRIBUTE_UNUSED,
|
|||||||
int virCgroupNewDetectMachine(const char *name,
|
int virCgroupNewDetectMachine(const char *name,
|
||||||
const char *drivername,
|
const char *drivername,
|
||||||
pid_t pid,
|
pid_t pid,
|
||||||
|
const char *partition,
|
||||||
int controllers,
|
int controllers,
|
||||||
virCgroupPtr *group)
|
virCgroupPtr *group)
|
||||||
{
|
{
|
||||||
@ -1658,7 +1673,7 @@ int virCgroupNewDetectMachine(const char *name,
|
|||||||
return -1;
|
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'",
|
VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'",
|
||||||
name, drivername);
|
name, drivername);
|
||||||
virCgroupFree(group);
|
virCgroupFree(group);
|
||||||
@ -1668,13 +1683,116 @@ int virCgroupNewDetectMachine(const char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virCgroupNewMachine(const char *name,
|
/*
|
||||||
|
* Returns 0 on success, -1 on fatal error, -2 on systemd not available
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virCgroupNewMachineSystemd(const char *name,
|
||||||
const char *drivername,
|
const char *drivername,
|
||||||
bool privileged ATTRIBUTE_UNUSED,
|
bool privileged,
|
||||||
const unsigned char *uuid ATTRIBUTE_UNUSED,
|
const unsigned char *uuid,
|
||||||
const char *rootdir ATTRIBUTE_UNUSED,
|
const char *rootdir,
|
||||||
pid_t pidleader ATTRIBUTE_UNUSED,
|
pid_t pidleader,
|
||||||
bool isContainer ATTRIBUTE_UNUSED,
|
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,
|
const char *partition,
|
||||||
int controllers,
|
int controllers,
|
||||||
virCgroupPtr *group)
|
virCgroupPtr *group)
|
||||||
@ -1682,8 +1800,7 @@ int virCgroupNewMachine(const char *name,
|
|||||||
virCgroupPtr parent = NULL;
|
virCgroupPtr parent = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
*group = NULL;
|
VIR_DEBUG("Fallback to non-systemd setup");
|
||||||
|
|
||||||
if (virCgroupNewPartition(partition,
|
if (virCgroupNewPartition(partition,
|
||||||
STREQ(partition, "/machine"),
|
STREQ(partition, "/machine"),
|
||||||
controllers,
|
controllers,
|
||||||
@ -1719,6 +1836,44 @@ cleanup:
|
|||||||
return ret;
|
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)
|
bool virCgroupNewIgnoreError(void)
|
||||||
{
|
{
|
||||||
if (virLastErrorIsSystemErrno(ENXIO) ||
|
if (virLastErrorIsSystemErrno(ENXIO) ||
|
||||||
|
@ -83,6 +83,7 @@ int virCgroupNewDetect(pid_t pid,
|
|||||||
int virCgroupNewDetectMachine(const char *name,
|
int virCgroupNewDetectMachine(const char *name,
|
||||||
const char *drivername,
|
const char *drivername,
|
||||||
pid_t pid,
|
pid_t pid,
|
||||||
|
const char *partition,
|
||||||
int controllers,
|
int controllers,
|
||||||
virCgroupPtr *group);
|
virCgroupPtr *group);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user