From b1e5880740e1bc415140f650fff2c0ef51b1f5a0 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Wed, 20 Aug 2008 13:44:03 +0000 Subject: [PATCH] add cpu management functionality to OpenVZ driver * src/openvz_conf.c src/openvz_driver.c: patch from Evgeniy Sokolov to limit the number of CPUs used by OpenVZ domains. Daniel --- ChangeLog | 5 +++ src/openvz_conf.c | 12 ++++++++ src/openvz_driver.c | 75 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e89bdbb9c9..83011f3b26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Aug 20 15:42:09 CEST 2008 Daniel Veillard + + * src/openvz_conf.c src/openvz_driver.c: patch from Evgeniy Sokolov + to limit the number of CPUs used by OpenVZ domains. + Wed Aug 20 15:31:47 CEST 2008 Daniel Veillard * src/storage_backend_logical.c: Patch from Cole Robinson, fix diff --git a/src/openvz_conf.c b/src/openvz_conf.c index 4628c8e884..5f1cd621a7 100644 --- a/src/openvz_conf.c +++ b/src/openvz_conf.c @@ -513,6 +513,7 @@ openvzGetVPSInfo(virConnectPtr conn) { struct openvz_vm **pnext; struct openvz_driver *driver; struct openvz_vm_def *vmdef; + char temp[124]; vm = NULL; driver = conn->privateData; @@ -569,6 +570,17 @@ openvzGetVPSInfo(virConnectPtr conn) { goto error; } + /*get VCPU*/ + ret = openvzReadConfigParam(veid, "CPUS", temp, sizeof(temp)); + if (ret < 0) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + _("Cound not read config for container %d"), veid); + goto error; + } else if (ret > 0) { + vmdef->vcpus = strtoI(temp); + } + + (*pnext)->vmdef = vmdef; pnext = &(*pnext)->next; } diff --git a/src/openvz_driver.c b/src/openvz_driver.c index d117480b67..8fdc2494df 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -94,6 +94,9 @@ static int openvzDomainUndefine(virDomainPtr dom); static void cmdExecFree(const char *cmdExec[]); static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid); +static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type); +static int openvzDomainGetMaxVcpus(virDomainPtr dom); +static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus); struct openvz_driver ovz_driver; @@ -266,7 +269,7 @@ static int openvzDomainGetInfo(virDomainPtr dom, //info->cpuTime = //info->maxMem = vm->def->maxmem; //info->memory = vm->def->memory; - //info->nrVirtCpu = vm->def->vcpus; + info->nrVirtCpu = vm->vmdef->vcpus; return 0; } @@ -450,7 +453,6 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) goto exit; } - //TODO: set number virtual CPUs //TODO: set quota if (virRun(conn, prog, NULL) < 0) { @@ -475,6 +477,14 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) goto exit; } + if (vmdef->vcpus > 0) { + if (openvzDomainSetVcpus(dom, vmdef->vcpus) < 0) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + _("Could not set number of virtual cpu")); + goto exit; + } + } + exit: cmdExecFree(prog); return dom; @@ -548,6 +558,15 @@ openvzDomainCreateLinux(virConnectPtr conn, const char *xml, dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); if (dom) dom->id = vm->vpsid; + + if (vmdef->vcpus > 0) { + if (openvzDomainSetVcpus(dom, vmdef->vcpus) < 0) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + _("Could not set number of virtual cpu")); + goto exit; + } + } + exit: cmdExecFree(progcreate); return dom; @@ -662,6 +681,52 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) return 0; } +static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type) { + if (STRCASEEQ(type, "openvz")) + return 1028; //OpenVZ has no limitation + + openvzError(conn, VIR_ERR_INVALID_ARG, + _("unknown type '%s'"), type); + return -1; +} + + +static int openvzDomainGetMaxVcpus(virDomainPtr dom) { + return openvzGetMaxVCPUs(dom->conn, "openvz"); +} + +static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) { + virConnectPtr conn= dom->conn; + struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; + struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); + char str_vcpus[32]; + const char *prog[] = { VZCTL, "--quiet", "set", vm->vmdef->name, + "--cpus", str_vcpus, "--save", NULL }; + snprintf(str_vcpus, 31, "%d", nvcpus); + str_vcpus[31] = '\0'; + + if (nvcpus <= 0) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + _("VCPUs should be >= 1")); + return -1; + } + + if (!vm) { + openvzError(conn, VIR_ERR_INVALID_DOMAIN, + _("no domain with matching uuid")); + return -1; + } + + if (virRun(conn, prog, NULL) < 0) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + _("Could not exec %s"), VZCTL); + return -1; + } + + vm->vmdef->vcpus = nvcpus; + return 0; +} + static const char *openvzProbe(void) { #ifdef __linux__ @@ -886,7 +951,7 @@ static virDriver openvzDriver = { NULL, /* version */ NULL, /* hostname */ NULL, /* uri */ - NULL, /* getMaxVcpus */ + openvzGetMaxVCPUs, /* getMaxVcpus */ openvzGetNodeInfo, /* nodeGetInfo */ NULL, /* getCapabilities */ openvzListDomains, /* listDomains */ @@ -908,10 +973,10 @@ static virDriver openvzDriver = { NULL, /* domainSave */ NULL, /* domainRestore */ NULL, /* domainCoreDump */ - NULL, /* domainSetVcpus */ + openvzDomainSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ - NULL, /* domainGetMaxVcpus */ + openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainDumpXML */ openvzListDefinedDomains, /* listDomains */ openvzNumDefinedDomains, /* numOfDomains */