[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] manage number of virtual CPUs



OpenVZ containers use all CPUs available in system by default.
Limitations may be caused only by Linux kernel limitation.

There is way to artificially limit number of CPUs.

patch add cpu management functionality to OpenVZ driver.
Index: openvz_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_conf.c,v
retrieving revision 1.33
diff -u -p -r1.33 openvz_conf.c
--- openvz_conf.c	5 Aug 2008 10:53:05 -0000	1.33
+++ openvz_conf.c	13 Aug 2008 12:49:58 -0000
@@ -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;
     }
Index: openvz_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_driver.c,v
retrieving revision 1.37
diff -u -p -r1.37 openvz_driver.c
--- openvz_driver.c	5 Aug 2008 10:53:05 -0000	1.37
+++ openvz_driver.c	13 Aug 2008 12:49:58 -0000
@@ -94,6 +94,9 @@ static int openvzDomainUndefine(virDomai
 static void cmdExecFree(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(virDomain
     //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
         goto exit;
     }
 
-    //TODO: set number virtual CPUs
     //TODO: set quota
 
     if (virRun(conn, (char **)prog, NULL) < 0) {
@@ -475,6 +477,14 @@ openvzDomainDefineXML(virConnectPtr conn
         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 co
     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 do
     return 0;
 }
 
+static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type) {
+    if (STRCASEEQ(type, "openvz"))
+        return 4096; //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, (char **)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__
@@ -884,7 +949,7 @@ static virDriver openvzDriver = {
     NULL, /* version */
     NULL, /* hostname */
     NULL, /* uri */
-    NULL, /* getMaxVcpus */
+    openvzGetMaxVCPUs, /* getMaxVcpus */
     openvzGetNodeInfo, /* nodeGetInfo */
     NULL, /* getCapabilities */
     openvzListDomains, /* listDomains */
@@ -906,10 +971,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 */

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]