diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 2c7f95e9f20e31b72bdfa3549e4069dcffb1c6b7..6358a25367cfc37acff7263d93c096b43aa30be8 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -212,7 +212,7 @@ virCgroupPartitionNeedsEscaping(const char *path) } -static int +int virCgroupPartitionEscape(char **path) { int rc; @@ -231,87 +231,6 @@ virCgroupPartitionEscape(char **path) } -static bool -virCgroupValidateMachineGroup(virCgroupPtr group, - const char *name, - const char *drivername, - const char *machinename) -{ - size_t i; - VIR_AUTOFREE(char *) partname = NULL; - VIR_AUTOFREE(char *) scopename_old = NULL; - VIR_AUTOFREE(char *) scopename_new = NULL; - VIR_AUTOFREE(char *) partmachinename = NULL; - - if (virAsprintf(&partname, "%s.libvirt-%s", - name, drivername) < 0) - return false; - - if (virCgroupPartitionEscape(&partname) < 0) - return false; - - if (virAsprintf(&partmachinename, "%s.libvirt-%s", - machinename, drivername) < 0 || - virCgroupPartitionEscape(&partmachinename) < 0) - return false; - - if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) - return false; - - if (!(scopename_new = virSystemdMakeScopeName(machinename, - drivername, false))) - return false; - - if (virCgroupPartitionEscape(&scopename_old) < 0) - return false; - - if (virCgroupPartitionEscape(&scopename_new) < 0) - return false; - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { - char *tmp; - - if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) - continue; - - if (!group->controllers[i].placement) - continue; - - tmp = strrchr(group->controllers[i].placement, '/'); - if (!tmp) - return false; - - if (i == VIR_CGROUP_CONTROLLER_CPU || - i == VIR_CGROUP_CONTROLLER_CPUACCT || - i == VIR_CGROUP_CONTROLLER_CPUSET) { - if (STREQ(tmp, "/emulator")) - *tmp = '\0'; - tmp = strrchr(group->controllers[i].placement, '/'); - if (!tmp) - return false; - } - - tmp++; - - if (STRNEQ(tmp, name) && - STRNEQ(tmp, machinename) && - STRNEQ(tmp, partname) && - STRNEQ(tmp, partmachinename) && - STRNEQ(tmp, scopename_old) && - STRNEQ(tmp, scopename_new)) { - VIR_DEBUG("Name '%s' for controller '%s' does not match " - "'%s', '%s', '%s', '%s' or '%s'", - tmp, virCgroupControllerTypeToString(i), - name, machinename, partname, - scopename_old, scopename_new); - return false; - } - } - - return true; -} - - static int virCgroupCopyMounts(virCgroupPtr group, virCgroupPtr parent) @@ -1504,7 +1423,7 @@ virCgroupNewDetectMachine(const char *name, return -1; } - if (!virCgroupValidateMachineGroup(*group, name, drivername, machinename)) { + if (!(*group)->backend->validateMachineGroup(*group, name, drivername, machinename)) { VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'", name, drivername); virCgroupFree(group); diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h index 88f51416b0f762e59268a98b1d5f3779963393e3..daf47bac09bbe1417dd7dd388d879b9c90c7db07 100644 --- a/src/util/vircgroupbackend.h +++ b/src/util/vircgroupbackend.h @@ -35,11 +35,18 @@ typedef enum { typedef bool (*virCgroupAvailableCB)(void); +typedef bool +(*virCgroupValidateMachineGroupCB)(virCgroupPtr group, + const char *name, + const char *drivername, + const char *machinename); + struct _virCgroupBackend { virCgroupBackendType type; /* Mandatory callbacks that need to be implemented for every backend. */ virCgroupAvailableCB available; + virCgroupValidateMachineGroupCB validateMachineGroup; }; typedef struct _virCgroupBackend virCgroupBackend; typedef virCgroupBackend *virCgroupBackendPtr; diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h index 2caa966fee73295024a811996f5c7fa4ecf37857..e7f4a1f0fc789edb5b33bbb798323230da261cb7 100644 --- a/src/util/vircgrouppriv.h +++ b/src/util/vircgrouppriv.h @@ -53,6 +53,8 @@ struct _virCgroup { virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; }; +int virCgroupPartitionEscape(char **path); + int virCgroupNewPartition(const char *path, bool create, int controllers, diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c index 73045b11090103b119ee57b56747303bb715eda5..d3879f90612c5dc4d3bb55459dc285b8e1f6248d 100644 --- a/src/util/vircgroupv1.c +++ b/src/util/vircgroupv1.c @@ -35,6 +35,8 @@ #include "vircgroupv1.h" #include "virfile.h" #include "virlog.h" +#include "virstring.h" +#include "virsystemd.h" VIR_LOG_INIT("util.cgroup"); @@ -76,10 +78,92 @@ virCgroupV1Available(void) } +static bool +virCgroupV1ValidateMachineGroup(virCgroupPtr group, + const char *name, + const char *drivername, + const char *machinename) +{ + size_t i; + VIR_AUTOFREE(char *) partname = NULL; + VIR_AUTOFREE(char *) scopename_old = NULL; + VIR_AUTOFREE(char *) scopename_new = NULL; + VIR_AUTOFREE(char *) partmachinename = NULL; + + if (virAsprintf(&partname, "%s.libvirt-%s", + name, drivername) < 0) + return false; + + if (virCgroupPartitionEscape(&partname) < 0) + return false; + + if (virAsprintf(&partmachinename, "%s.libvirt-%s", + machinename, drivername) < 0 || + virCgroupPartitionEscape(&partmachinename) < 0) + return false; + + if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) + return false; + + if (!(scopename_new = virSystemdMakeScopeName(machinename, + drivername, false))) + return false; + + if (virCgroupPartitionEscape(&scopename_old) < 0) + return false; + + if (virCgroupPartitionEscape(&scopename_new) < 0) + return false; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + char *tmp; + + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) + continue; + + if (!group->controllers[i].placement) + continue; + + tmp = strrchr(group->controllers[i].placement, '/'); + if (!tmp) + return false; + + if (i == VIR_CGROUP_CONTROLLER_CPU || + i == VIR_CGROUP_CONTROLLER_CPUACCT || + i == VIR_CGROUP_CONTROLLER_CPUSET) { + if (STREQ(tmp, "/emulator")) + *tmp = '\0'; + tmp = strrchr(group->controllers[i].placement, '/'); + if (!tmp) + return false; + } + + tmp++; + + if (STRNEQ(tmp, name) && + STRNEQ(tmp, machinename) && + STRNEQ(tmp, partname) && + STRNEQ(tmp, partmachinename) && + STRNEQ(tmp, scopename_old) && + STRNEQ(tmp, scopename_new)) { + VIR_DEBUG("Name '%s' for controller '%s' does not match " + "'%s', '%s', '%s', '%s' or '%s'", + tmp, virCgroupV1ControllerTypeToString(i), + name, machinename, partname, + scopename_old, scopename_new); + return false; + } + } + + return true; +} + + virCgroupBackend virCgroupV1Backend = { .type = VIR_CGROUP_BACKEND_TYPE_V1, .available = virCgroupV1Available, + .validateMachineGroup = virCgroupV1ValidateMachineGroup, };