]> xenbits.xensource.com Git - libvirt.git/commitdiff
XML parsing for memory tunables
authorNikunj A. Dadhania <nikunj@linux.vnet.ibm.com>
Tue, 12 Oct 2010 14:43:39 +0000 (16:43 +0200)
committerDaniel Veillard <veillard@redhat.com>
Tue, 12 Oct 2010 17:26:09 +0000 (19:26 +0200)
Adding parsing code for memory tunables in the domain xml file
also change the internal define structures used for domain memory
informations
Adds a new specific test

22 files changed:
src/conf/domain_conf.c
src/conf/domain_conf.h
src/esx/esx_vmx.c
src/lxc/lxc_controller.c
src/lxc/lxc_driver.c
src/opennebula/one_conf.c
src/opennebula/one_driver.c
src/openvz/openvz_driver.c
src/phyp/phyp_driver.c
src/qemu/qemu_conf.c
src/qemu/qemu_driver.c
src/test/test_driver.c
src/uml/uml_conf.c
src/uml/uml_driver.c
src/vbox/vbox_tmpl.c
src/xen/xend_internal.c
src/xen/xm_internal.c
src/xenapi/xenapi_driver.c
src/xenapi/xenapi_utils.c
tests/qemuxml2argvdata/qemuxml2argv-memtune.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-memtune.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index 539d44350d29289e1c2bc326aa66cde7080a69cd..23ccaff29b5bf1d8f24299d7642f39059da31572 100644 (file)
@@ -4235,18 +4235,37 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
     def->description = virXPathString("string(./description[1])", ctxt);
 
     /* Extract domain memory */
-    if (virXPathULong("string(./memory[1])", ctxt, &def->maxmem) < 0) {
+    if (virXPathULong("string(./memory[1])", ctxt,
+                      &def->mem.max_balloon) < 0) {
         virDomainReportError(VIR_ERR_INTERNAL_ERROR,
                              "%s", _("missing memory element"));
         goto error;
     }
 
-    if (virXPathULong("string(./currentMemory[1])", ctxt, &def->memory) < 0)
-        def->memory = def->maxmem;
+    if (virXPathULong("string(./currentMemory[1])", ctxt,
+                      &def->mem.cur_balloon) < 0)
+        def->mem.cur_balloon = def->mem.max_balloon;
 
     node = virXPathNode("./memoryBacking/hugepages", ctxt);
     if (node)
-        def->hugepage_backed = 1;
+        def->mem.hugepage_backed = 1;
+
+    /* Extract other memory tunables */
+    if (virXPathULong("string(./memtune/hard_limit)", ctxt,
+                      &def->mem.hard_limit) < 0)
+        def->mem.hard_limit = 0;
+
+    if (virXPathULong("string(./memtune/soft_limit[1])", ctxt,
+                      &def->mem.soft_limit) < 0)
+        def->mem.soft_limit = 0;
+
+    if (virXPathULong("string(./memtune/min_guarantee[1])", ctxt,
+                      &def->mem.min_guarantee) < 0)
+        def->mem.min_guarantee = 0;
+
+    if (virXPathULong("string(./memtune/swap_hard_limit[1])", ctxt,
+                      &def->mem.swap_hard_limit) < 0)
+        def->mem.swap_hard_limit = 0;
 
     if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0)
         def->vcpus = 1;
@@ -6384,10 +6403,29 @@ char *virDomainDefFormat(virDomainDefPtr def,
         virBufferEscapeString(&buf, "  <description>%s</description>\n",
                               def->description);
 
-    virBufferVSprintf(&buf, "  <memory>%lu</memory>\n", def->maxmem);
+    virBufferVSprintf(&buf, "  <memory>%lu</memory>\n", def->mem.max_balloon);
     virBufferVSprintf(&buf, "  <currentMemory>%lu</currentMemory>\n",
-                      def->memory);
-    if (def->hugepage_backed) {
+                      def->mem.cur_balloon);
+
+    /* add memtune only if there are any */
+    if(def->mem.hard_limit || def->mem.hard_limit || def->mem.hard_limit)
+        virBufferVSprintf(&buf, "  <memtune>\n");
+    if (def->mem.hard_limit) {
+        virBufferVSprintf(&buf, "    <hard_limit>%lu</hard_limit>\n",
+                          def->mem.hard_limit);
+    }
+    if (def->mem.soft_limit) {
+        virBufferVSprintf(&buf, "    <soft_limit>%lu</soft_limit>\n",
+                          def->mem.soft_limit);
+    }
+    if (def->mem.swap_hard_limit) {
+        virBufferVSprintf(&buf, "    <swap_hard_limit>%lu</swap_hard_limit>\n",
+                          def->mem.swap_hard_limit);
+    }
+    if(def->mem.hard_limit || def->mem.hard_limit || def->mem.hard_limit)
+        virBufferVSprintf(&buf, "  </memtune>\n");
+
+    if (def->mem.hugepage_backed) {
         virBufferAddLit(&buf, "  <memoryBacking>\n");
         virBufferAddLit(&buf, "    <hugepages/>\n");
         virBufferAddLit(&buf, "  </memoryBacking>\n");
index 9bf13d80264504dbed80fa5cd64ae8331f77baa4..7c5215f5807789769bcc0745923c0f37fcf55b0b 100644 (file)
@@ -866,9 +866,15 @@ struct _virDomainDef {
     char *name;
     char *description;
 
-    unsigned long memory;
-    unsigned long maxmem;
-    unsigned char hugepage_backed;
+    struct {
+        unsigned long max_balloon;
+        unsigned long cur_balloon;
+        unsigned long hugepage_backed;
+        unsigned long hard_limit;
+        unsigned long soft_limit;
+        unsigned long min_guarantee;
+        unsigned long swap_hard_limit;
+    } mem;
     unsigned long vcpus;
     int cpumasklen;
     char *cpumask;
index bfebc4a0e0d1cb63acb6207f326282bb78f5535f..ece16b206a2d2d94bfa887fbd0bf76fc9149e85b 100644 (file)
@@ -48,8 +48,8 @@ domain-xml                        <=>   vmx
 def->id = <value>                 <=>   ???                                     # not representable
 def->uuid = <value>               <=>   uuid.bios = "<value>"
 def->name = <value>               <=>   displayName = "<value>"
-def->maxmem = <value kilobyte>    <=>   memsize = "<value megabyte>"            # must be a multiple of 4, defaults to 32
-def->memory = <value kilobyte>    <=>   sched.mem.max = "<value megabyte>"      # defaults to "unlimited" -> def->memory = def->maxmem
+def->mem.max_balloon = <value kilobyte>    <=>   memsize = "<value megabyte>"            # must be a multiple of 4, defaults to 32
+def->mem.cur_balloon = <value kilobyte>    <=>   sched.mem.max = "<value megabyte>"      # defaults to "unlimited" -> def->mem.cur_balloon = def->mem.max_balloon
 def->vcpus = <value>              <=>   numvcpus = "<value>"                    # must be 1 or a multiple of 2, defaults to 1
 def->cpumask = <uint list>        <=>   sched.cpu.affinity = "<uint list>"
 
@@ -1012,7 +1012,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
         *tmp2 = '\0';
     }
 
-    /* vmx:memsize -> def:maxmem */
+    /* vmx:memsize -> def:mem.max_balloon */
     if (esxUtil_GetConfigLong(conf, "memsize", &memsize, 32, true) < 0) {
         goto cleanup;
     }
@@ -1024,7 +1024,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
         goto cleanup;
     }
 
-    def->maxmem = memsize * 1024; /* Scale from megabytes to kilobytes */
+    def->mem.max_balloon = memsize * 1024; /* Scale from megabytes to kilobytes */
 
     /* vmx:sched.mem.max -> def:memory */
     if (esxUtil_GetConfigLong(conf, "sched.mem.max", &memory, memsize,
@@ -1036,10 +1036,10 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
         memory = memsize;
     }
 
-    def->memory = memory * 1024; /* Scale from megabytes to kilobytes */
+    def->mem.cur_balloon = memory * 1024; /* Scale from megabytes to kilobytes */
 
-    if (def->memory > def->maxmem) {
-        def->memory = def->maxmem;
+    if (def->mem.cur_balloon > def->mem.max_balloon) {
+        def->mem.cur_balloon = def->mem.max_balloon;
     }
 
     /* vmx:numvcpus -> def:vcpus */
@@ -2578,32 +2578,32 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
         virBufferVSprintf(&buffer, "annotation = \"%s\"\n", annotation);
     }
 
-    /* def:maxmem -> vmx:memsize */
-    if (def->maxmem <= 0 || def->maxmem % 4096 != 0) {
+    /* def:mem.max_balloon -> vmx:memsize */
+    if (def->mem.max_balloon <= 0 || def->mem.max_balloon % 4096 != 0) {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                   _("Expecting domain XML entry 'memory' to be an unsigned "
                     "integer (multiple of 4096) but found %lld"),
-                  (unsigned long long)def->maxmem);
+                  (unsigned long long)def->mem.max_balloon);
         goto cleanup;
     }
 
     /* Scale from kilobytes to megabytes */
     virBufferVSprintf(&buffer, "memsize = \"%d\"\n",
-                      (int)(def->maxmem / 1024));
+                      (int)(def->mem.max_balloon / 1024));
 
     /* def:memory -> vmx:sched.mem.max */
-    if (def->memory < def->maxmem) {
-        if (def->memory <= 0 || def->memory % 1024 != 0) {
+    if (def->mem.cur_balloon < def->mem.max_balloon) {
+        if (def->mem.cur_balloon <= 0 || def->mem.cur_balloon % 1024 != 0) {
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                       _("Expecting domain XML entry 'currentMemory' to be an "
                         "unsigned integer (multiple of 1024) but found %lld"),
-                      (unsigned long long)def->memory);
+                      (unsigned long long)def->mem.cur_balloon);
             goto cleanup;
         }
 
         /* Scale from kilobytes to megabytes */
         virBufferVSprintf(&buffer, "sched.mem.max = \"%d\"\n",
-                          (int)(def->memory / 1024));
+                          (int)(def->mem.cur_balloon / 1024));
     }
 
     /* def:vcpus -> vmx:numvcpus */
index 7dc51a55428bf098a303d0d54cf063a1dcc418d9..82ecce0de8e7a13d6ba282f4a3f79edf3b455709 100644 (file)
@@ -102,7 +102,7 @@ static int lxcSetContainerResources(virDomainDefPtr def)
         goto cleanup;
     }
 
-    rc = virCgroupSetMemory(cgroup, def->maxmem);
+    rc = virCgroupSetMemory(cgroup, def->mem.max_balloon);
     if (rc != 0) {
         virReportSystemError(-rc,
                              _("Unable to set memory limit for domain %s"),
index a240e6df59b18087aac3f984c91a572ae89de691..89778354465858f1ab83cb77f78cafa9534347d3 100644 (file)
@@ -500,7 +500,7 @@ static int lxcDomainGetInfo(virDomainPtr dom,
 
     if (!virDomainObjIsActive(vm) || driver->cgroup == NULL) {
         info->cpuTime = 0;
-        info->memory = vm->def->memory;
+        info->memory = vm->def->mem.cur_balloon;
     } else {
         if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
             lxcError(VIR_ERR_INTERNAL_ERROR,
@@ -520,7 +520,7 @@ static int lxcDomainGetInfo(virDomainPtr dom,
         }
     }
 
-    info->maxMem = vm->def->maxmem;
+    info->maxMem = vm->def->mem.max_balloon;
     info->nrVirtCpu = 1;
     ret = 0;
 
@@ -580,7 +580,7 @@ static unsigned long lxcDomainGetMaxMemory(virDomainPtr dom) {
         goto cleanup;
     }
 
-    ret = vm->def->maxmem;
+    ret = vm->def->mem.max_balloon;
 
 cleanup:
     if (vm)
@@ -605,13 +605,13 @@ static int lxcDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
         goto cleanup;
     }
 
-    if (newmax < vm->def->memory) {
+    if (newmax < vm->def->mem.cur_balloon) {
         lxcError(VIR_ERR_INVALID_ARG,
                          "%s", _("Cannot set max memory lower than current memory"));
         goto cleanup;
     }
 
-    vm->def->maxmem = newmax;
+    vm->def->mem.max_balloon = newmax;
     ret = 0;
 
 cleanup:
@@ -637,7 +637,7 @@ static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
         goto cleanup;
     }
 
-    if (newmem > vm->def->maxmem) {
+    if (newmem > vm->def->mem.max_balloon) {
         lxcError(VIR_ERR_INVALID_ARG,
                  "%s", _("Cannot set memory higher than max memory"));
         goto cleanup;
index 029d475d81d6b14ab02bfe670ef0433d705d1233..44e28dc8fb824df616604dab04398d1d7b9f15b1 100644 (file)
@@ -172,7 +172,7 @@ char* xmlOneTemplate(virDomainDefPtr def)
     virBufferVSprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
                       def->name,
                       def->vcpus,
-                      (def->maxmem)/1024);
+                      (def->mem.max_balloon)/1024);
 
     /*Optional Booting OpenNebula Information:*/
     if (def->os.kernel) {
index e70f17bc2b3de8e574e0b53cf46fd7e833e7ff98..ced9a3853fea1b0e80b8c97853bc83ce19bc0802 100644 (file)
@@ -357,7 +357,7 @@ static int oneDomainGetInfo(virDomainPtr dom,
         cptr=strstr(vm_info,"MEMORY");
         cptr=index(cptr,':');
         cptr++;
-        vm->def->memory = atoi(cptr);
+        vm->def->mem.cur_balloon = atoi(cptr);
 
         //run time:
         cptr=strstr(vm_info,"START TIME");
@@ -369,8 +369,8 @@ static int oneDomainGetInfo(virDomainPtr dom,
     }
 
     info->state = vm->state;
-    info->maxMem = vm->def->maxmem;
-    info->memory = vm->def->memory;
+    info->maxMem = vm->def->mem.max_balloon;
+    info->memory = vm->def->mem.cur_balloon;
     info->nrVirtCpu = vm->def->vcpus;
 
     virDomainObjUnlock(vm);
@@ -818,6 +818,8 @@ static virDriver oneDriver = {
     NULL, /* domainRevertToSnapshot */
     NULL, /* domainSnapshotDelete */
     NULL, /* qemuDomainMonitorCommand */
+    NULL, /* domainSetMemoryParameters */
+    NULL, /* domainGetMemoryParameters */
 };
 
 static virStateDriver oneStateDriver = {
index 4247e0aed469886266b1d2c631f0f37d70f5d75b..92cf4a18f4557a1c1d0c41700bb9382c1f2f354e 100644 (file)
@@ -403,8 +403,8 @@ static int openvzDomainGetInfo(virDomainPtr dom,
         }
     }
 
-    info->maxMem = vm->def->maxmem;
-    info->memory = vm->def->memory;
+    info->maxMem = vm->def->mem.max_balloon;
+    info->memory = vm->def->mem.cur_balloon;
     info->nrVirtCpu = vm->def->vcpus;
     ret = 0;
 
@@ -934,8 +934,8 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
         }
     }
 
-    if (vm->def->memory > 0) {
-        if (openvzDomainSetMemoryInternal(vm, vm->def->memory) < 0) {
+    if (vm->def->mem.cur_balloon > 0) {
+        if (openvzDomainSetMemoryInternal(vm, vm->def->mem.cur_balloon) < 0) {
             openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                         _("Could not set memory size"));
              goto cleanup;
index cf20624111e9fd0fc4178437c237bbd24908d908..e63d8d94518aad6de6f2f9133fad5be5a30d7284 100644 (file)
@@ -3516,13 +3516,13 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
         goto err;
     }
 
-    if ((def.maxmem =
+    if ((def.mem.max_balloon =
          phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) {
         VIR_ERROR0(_("Unable to determine domain's max memory."));
         goto err;
     }
 
-    if ((def.memory =
+    if ((def.mem.cur_balloon =
          phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) {
         VIR_ERROR0(_("Unable to determine domain's memory."));
         goto err;
@@ -3701,14 +3701,14 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
     int exit_status = 0;
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    if (!def->memory) {
+    if (!def->mem.cur_balloon) {
         PHYP_ERROR(VIR_ERR_XML_ERROR,"%s",
                 _("Field \"<memory>\" on the domain XML file is missing or has "
                     "invalid value."));
         goto err;
     }
 
-    if (!def->maxmem) {
+    if (!def->mem.max_balloon) {
         PHYP_ERROR(VIR_ERR_XML_ERROR,"%s",
                 _("Field \"<currentMemory>\" on the domain XML file is missing or"
                     " has invalid value."));
@@ -3733,8 +3733,9 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
         virBufferVSprintf(&buf, " -m %s", managed_system);
     virBufferVSprintf(&buf, " -r lpar -p %s -i min_mem=%d,desired_mem=%d,"
                       "max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s",
-                      def->name, (int) def->memory, (int) def->memory,
-                      (int) def->maxmem, (int) def->vcpus, def->disks[0]->src);
+                      def->name, (int) def->mem.cur_balloon,
+                      (int) def->mem.cur_balloon, (int) def->mem.max_balloon,
+                      (int) def->vcpus, def->disks[0]->src);
     if (virBufferError(&buf)) {
         virBufferFreeAndReset(&buf);
         virReportOOMError();
index 737b255d6a635d0b169ec047d9918a58b8cb3e29..b0c8dcc7017a9352f31511be3972d44aa13f0589 100644 (file)
@@ -3849,7 +3849,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
      * is set post-startup using the balloon driver. If balloon driver
      * is not supported, then they're out of luck anyway
      */
-    snprintf(memory, sizeof(memory), "%lu", def->maxmem/1024);
+    snprintf(memory, sizeof(memory), "%lu", def->mem.max_balloon/1024);
     snprintf(domid, sizeof(domid), "%d", def->id);
 
     ADD_ENV_LIT("LC_ALL=C");
@@ -3895,7 +3895,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
         ADD_ARG_LIT("-enable-kvm");
     ADD_ARG_LIT("-m");
     ADD_ARG_LIT(memory);
-    if (def->hugepage_backed) {
+    if (def->mem.hugepage_backed) {
         if (!driver->hugetlbfs_mount) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR,
                             "%s", _("hugetlbfs filesystem is not mounted"));
@@ -6122,7 +6122,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
     virUUIDGenerate(def->uuid);
 
     def->id = -1;
-    def->memory = def->maxmem = 64 * 1024;
+    def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024;
     def->vcpus = 1;
     def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
     def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
@@ -6237,7 +6237,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                                 _("cannot parse memory level '%s'"), val);
                 goto error;
             }
-            def->memory = def->maxmem = mem * 1024;
+            def->mem.cur_balloon = def->mem.max_balloon = mem * 1024;
         } else if (STREQ(arg, "-smp")) {
             WANT_VALUE();
             if (qemuParseCommandLineSmp(def, val) < 0)
index f44a18f550a26e0d0c05852661173d5224824b10..bf4373a77d3c59d4ec49261f782bbf467cf67c99 100644 (file)
@@ -3939,7 +3939,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
 
     DEBUG0("Setting initial memory amount");
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if (qemuMonitorSetBalloon(priv->mon, vm->def->memory) < 0) {
+    if (qemuMonitorSetBalloon(priv->mon, vm->def->mem.cur_balloon) < 0) {
         qemuDomainObjExitMonitorWithDriver(driver, vm);
         goto cleanup;
     }
@@ -4862,7 +4862,7 @@ static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) {
         goto cleanup;
     }
 
-    ret = vm->def->maxmem;
+    ret = vm->def->mem.max_balloon;
 
 cleanup:
     if (vm)
@@ -4893,7 +4893,7 @@ static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
         goto cleanup;
     }
 
-    if (newmem > vm->def->maxmem) {
+    if (newmem > vm->def->mem.max_balloon) {
         qemuReportError(VIR_ERR_INVALID_ARG,
                         "%s", _("cannot set memory higher than max memory"));
         goto cleanup;
@@ -4957,14 +4957,14 @@ static int qemudDomainGetInfo(virDomainPtr dom,
         }
     }
 
-    info->maxMem = vm->def->maxmem;
+    info->maxMem = vm->def->mem.max_balloon;
 
     if (virDomainObjIsActive(vm)) {
         qemuDomainObjPrivatePtr priv = vm->privateData;
 
         if ((vm->def->memballoon != NULL) &&
             (vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE)) {
-            info->memory = vm->def->maxmem;
+            info->memory = vm->def->mem.max_balloon;
         } else if (!priv->jobActive) {
             if (qemuDomainObjBeginJob(vm) < 0)
                 goto cleanup;
@@ -4980,7 +4980,7 @@ static int qemudDomainGetInfo(virDomainPtr dom,
 
             if (err == 0)
                 /* Balloon not supported, so maxmem is always the allocation */
-                info->memory = vm->def->maxmem;
+                info->memory = vm->def->mem.max_balloon;
             else
                 info->memory = balloon;
 
@@ -4989,10 +4989,10 @@ static int qemudDomainGetInfo(virDomainPtr dom,
                 goto cleanup;
             }
         } else {
-            info->memory = vm->def->memory;
+            info->memory = vm->def->mem.cur_balloon;
         }
     } else {
-        info->memory = vm->def->memory;
+        info->memory = vm->def->mem.cur_balloon;
     }
 
     info->nrVirtCpu = vm->def->vcpus;
@@ -6774,7 +6774,7 @@ static char *qemudDomainDumpXML(virDomainPtr dom,
             if (err < 0)
                 goto cleanup;
             if (err > 0)
-                vm->def->memory = balloon;
+                vm->def->mem.cur_balloon = balloon;
             /* err == 0 indicates no balloon support, so ignore it */
         }
     }
index 906211cbf6f31f122197723801b124e770d802ba..7d4d119dce39279201b59c95ec1403e95dd81a28 100644 (file)
@@ -1681,8 +1681,8 @@ static int testGetDomainInfo (virDomainPtr domain,
     }
 
     info->state = privdom->state;
-    info->memory = privdom->def->memory;
-    info->maxMem = privdom->def->maxmem;
+    info->memory = privdom->def->mem.cur_balloon;
+    info->maxMem = privdom->def->mem.max_balloon;
     info->nrVirtCpu = privdom->def->vcpus;
     info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll  * 1000ll) + (tv.tv_usec * 1000ll));
     ret = 0;
@@ -1963,7 +1963,7 @@ static unsigned long testGetMaxMemory(virDomainPtr domain) {
         goto cleanup;
     }
 
-    ret = privdom->def->maxmem;
+    ret = privdom->def->mem.max_balloon;
 
 cleanup:
     if (privdom)
@@ -1989,7 +1989,7 @@ static int testSetMaxMemory(virDomainPtr domain,
     }
 
     /* XXX validate not over host memory wrt to other domains */
-    privdom->def->maxmem = memory;
+    privdom->def->mem.max_balloon = memory;
     ret = 0;
 
 cleanup:
@@ -2015,12 +2015,12 @@ static int testSetMemory(virDomainPtr domain,
         goto cleanup;
     }
 
-    if (memory > privdom->def->maxmem) {
+    if (memory > privdom->def->mem.max_balloon) {
         testError(VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto cleanup;
     }
 
-    privdom->def->memory = memory;
+    privdom->def->mem.cur_balloon = memory;
     ret = 0;
 
 cleanup:
index f2eaef59c6a0fc234bf62af290e8a306e7b9abb3..33b2b04a95c4b392d9ad006148dc46064a10a21d 100644 (file)
@@ -502,7 +502,7 @@ int umlBuildCommandLine(virConnectPtr conn,
         }                                                               \
     } while (0)
 
-    snprintf(memory, sizeof(memory), "%luK", vm->def->memory);
+    snprintf(memory, sizeof(memory), "%luK", vm->def->mem.cur_balloon);
 
     ADD_ENV_LIT("LC_ALL=C");
 
index 1236abb8da9f03383b0f8bbb047bdbc6a72b3d41..e195541bc4080fdb77841f311a996494b9c4c58b 100644 (file)
@@ -1420,7 +1420,7 @@ static unsigned long umlDomainGetMaxMemory(virDomainPtr dom) {
                        _("no domain with matching uuid '%s'"), uuidstr);
         goto cleanup;
     }
-    ret = vm->def->maxmem;
+    ret = vm->def->mem.max_balloon;
 
 cleanup:
     if (vm)
@@ -1446,13 +1446,13 @@ static int umlDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
         goto cleanup;
     }
 
-    if (newmax < vm->def->memory) {
+    if (newmax < vm->def->mem.cur_balloon) {
         umlReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("cannot set max memory lower than current memory"));
         goto cleanup;
     }
 
-    vm->def->maxmem = newmax;
+    vm->def->mem.max_balloon = newmax;
     ret = 0;
 
 cleanup:
@@ -1485,13 +1485,13 @@ static int umlDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
         goto cleanup;
     }
 
-    if (newmem > vm->def->maxmem) {
+    if (newmem > vm->def->mem.max_balloon) {
         umlReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("cannot set memory higher than max memory"));
         goto cleanup;
     }
 
-    vm->def->memory = newmem;
+    vm->def->mem.cur_balloon = newmem;
     ret = 0;
 
 cleanup:
@@ -1528,8 +1528,8 @@ static int umlDomainGetInfo(virDomainPtr dom,
         }
     }
 
-    info->maxMem = vm->def->maxmem;
-    info->memory = vm->def->memory;
+    info->maxMem = vm->def->mem.max_balloon;
+    info->memory = vm->def->mem.cur_balloon;
     info->nrVirtCpu = vm->def->vcpus;
     ret = 0;
 
index b5cd2e49c83e1d13855e0dcd50d84da05a15a666..65bfd9e854f13a7484ba3b36b89c70645c81a0c4 100644 (file)
@@ -1708,7 +1708,7 @@ static int vboxDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) {
             if (STREQ(dom->name, machineName)) {
                 /* Get the Machine State (also match it with
                 * virDomainState). Get the Machine memory and
-                * for time being set maxmem and memory to same
+                * for time being set max_balloon and cur_balloon to same
                 * Also since there is no direct way of checking
                 * the cputime required (one condition being the
                 * VM is remote), return zero for cputime. Get the
@@ -1734,8 +1734,8 @@ static int vboxDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) {
 
                 info->cpuTime = 0;
                 info->nrVirtCpu = CPUCount;
-                info->memory = memorySize * 1024;
-                info->maxMem = maxMemorySize * 1024;
+                info->mem.cur_balloon = memorySize * 1024;
+                info->mem.max_balloon = maxMemorySize * 1024;
                 switch(state) {
                     case MachineState_Running:
                         info->state = VIR_DOMAIN_RUNNING;
@@ -1980,7 +1980,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
             def->name = strdup(dom->name);
 
             machine->vtbl->GetMemorySize(machine, &memorySize);
-            def->memory = memorySize * 1024;
+            def->mem.cur_balloon = memorySize * 1024;
 
             data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
             if (systemProperties) {
@@ -1996,8 +1996,8 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
              * the notation here seems to be inconsistent while
              * reading and while dumping xml
              */
-            /* def->maxmem = maxMemorySize * 1024; */
-            def->maxmem = memorySize * 1024;
+            /* def->mem.max_balloon = maxMemorySize * 1024; */
+            def->mem.max_balloon = memorySize * 1024;
 
             machine->vtbl->GetCPUCount(machine, &CPUCount);
             def->vcpus = CPUCount;
@@ -4562,12 +4562,12 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
         goto cleanup;
     }
 
-    rc = machine->vtbl->SetMemorySize(machine, def->memory / 1024);
+    rc = machine->vtbl->SetMemorySize(machine, def->mem.cur_balloon / 1024);
     if (NS_FAILED(rc)) {
         vboxError(VIR_ERR_INTERNAL_ERROR,
                   _("could not set the memory size of the domain to: %lu Kb, "
                     "rc=%08x"),
-                  def->memory, (unsigned)rc);
+                  def->mem.cur_balloon, (unsigned)rc);
     }
 
     rc = machine->vtbl->SetCPUCount(machine, def->vcpus);
index 4fba6af873467b53709bca20e9d045ac1daeb109..5ffc3c8a9fd8cce5400727e823d5f0f96505a6e1 100644 (file)
@@ -2167,10 +2167,12 @@ xenDaemonParseSxpr(virConnectPtr conn,
         }
     }
 
-    def->maxmem = (unsigned long) (sexpr_u64(root, "domain/maxmem") << 10);
-    def->memory = (unsigned long) (sexpr_u64(root, "domain/memory") << 10);
-    if (def->memory > def->maxmem)
-        def->maxmem = def->memory;
+    def->mem.max_balloon = (unsigned long)
+                           (sexpr_u64(root, "domain/maxmem") << 10);
+    def->mem.cur_balloon = (unsigned long)
+                           (sexpr_u64(root, "domain/memory") << 10);
+    if (def->mem.cur_balloon > def->mem.max_balloon)
+        def->mem.cur_balloon = def->mem.max_balloon;
 
     if (cpus != NULL) {
         def->cpumasklen = VIR_DOMAIN_CPUMASK_LEN;
@@ -5663,7 +5665,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
     virBufferAddLit(&buf, "(vm ");
     virBufferVSprintf(&buf, "(name '%s')", def->name);
     virBufferVSprintf(&buf, "(memory %lu)(maxmem %lu)",
-                      def->memory/1024, def->maxmem/1024);
+                      def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
     virBufferVSprintf(&buf, "(vcpus %lu)", def->vcpus);
 
     if (def->cpumask) {
index a30d78154eb748f30144aebfc8de9f6dc96e9da6..8e42a1cc054691ef4b8f2a274daf011d2b31cdcf 100644 (file)
@@ -644,8 +644,8 @@ int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) {
         goto error;
 
     memset(info, 0, sizeof(virDomainInfo));
-    info->maxMem = entry->def->maxmem;
-    info->memory = entry->def->memory;
+    info->maxMem = entry->def->mem.max_balloon;
+    info->memory = entry->def->mem.cur_balloon;
     info->nrVirtCpu = entry->def->vcpus;
     info->state = VIR_DOMAIN_SHUTOFF;
     info->cpuTime = 0;
@@ -759,14 +759,16 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
             goto cleanup;
     }
 
-    if (xenXMConfigGetULong(conf, "memory", &def->memory, MIN_XEN_GUEST_SIZE * 2) < 0)
+    if (xenXMConfigGetULong(conf, "memory", &def->mem.cur_balloon,
+                            MIN_XEN_GUEST_SIZE * 2) < 0)
         goto cleanup;
 
-    if (xenXMConfigGetULong(conf, "maxmem", &def->maxmem, def->memory) < 0)
+    if (xenXMConfigGetULong(conf, "maxmem", &def->mem.max_balloon,
+                            def->mem.cur_balloon) < 0)
         goto cleanup;
 
-    def->memory *= 1024;
-    def->maxmem *= 1024;
+    def->mem.cur_balloon *= 1024;
+    def->mem.max_balloon *= 1024;
 
 
     if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
@@ -1530,9 +1532,9 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) {
     if (!(entry = virHashLookup(priv->configCache, filename)))
         goto cleanup;
 
-    entry->def->memory = memory;
-    if (entry->def->memory > entry->def->maxmem)
-        entry->def->memory = entry->def->maxmem;
+    entry->def->mem.cur_balloon = memory;
+    if (entry->def->mem.cur_balloon > entry->def->mem.max_balloon)
+        entry->def->mem.cur_balloon = entry->def->mem.max_balloon;
 
     /* If this fails, should we try to undo our changes to the
      * in-memory representation of the config file. I say not!
@@ -1573,9 +1575,9 @@ int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) {
     if (!(entry = virHashLookup(priv->configCache, filename)))
         goto cleanup;
 
-    entry->def->maxmem = memory;
-    if (entry->def->memory > entry->def->maxmem)
-        entry->def->memory = entry->def->maxmem;
+    entry->def->mem.max_balloon = memory;
+    if (entry->def->mem.cur_balloon > entry->def->mem.max_balloon)
+        entry->def->mem.cur_balloon = entry->def->mem.max_balloon;
 
     /* If this fails, should we try to undo our changes to the
      * in-memory representation of the config file. I say not!
@@ -1614,7 +1616,7 @@ unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain) {
     if (!(entry = virHashLookup(priv->configCache, filename)))
         goto cleanup;
 
-    ret = entry->def->maxmem;
+    ret = entry->def->mem.max_balloon;
 
 cleanup:
     xenUnifiedUnlock(priv);
@@ -2233,10 +2235,10 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
     if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
         goto no_memory;
 
-    if (xenXMConfigSetInt(conf, "maxmem", def->maxmem / 1024) < 0)
+    if (xenXMConfigSetInt(conf, "maxmem", def->mem.max_balloon / 1024) < 0)
         goto no_memory;
 
-    if (xenXMConfigSetInt(conf, "memory", def->memory / 1024) < 0)
+    if (xenXMConfigSetInt(conf, "memory", def->mem.cur_balloon / 1024) < 0)
         goto no_memory;
 
     if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
index 730859b3d4485f19c1f9f4d4acd5fdaa2a49b790..ad5b5d8e9edcc46e70a81f2ca745a1c9e247f80a 100644 (file)
@@ -1284,12 +1284,12 @@ xenapiDomainDumpXML (virDomainPtr dom, int flags ATTRIBUTE_UNUSED)
     }
     unsigned long memory=0;
     memory = xenapiDomainGetMaxMemory(dom);
-    defPtr->maxmem = memory;
+    defPtr->mem.max_balloon = memory;
     int64_t dynamic_mem=0;
     if (xen_vm_get_memory_dynamic_max(session, &dynamic_mem, vm)) {
-        defPtr->memory = (unsigned long) (dynamic_mem / 1024);
+        defPtr->mem.cur_balloon = (unsigned long) (dynamic_mem / 1024);
     } else {
-        defPtr->memory = memory;
+        defPtr->mem.cur_balloon = memory;
     }
     defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
     enum xen_on_normal_exit action;
index 252073c117f28353da9225a4560e0161d5493469..be5549125d6d9b7a1793aadd7e96b3d605eb61ae 100644 (file)
@@ -503,10 +503,10 @@ createVMRecordFromXml (virConnectPtr conn, virDomainDefPtr def,
         if (!((*record)->pv_bootloader_args = strdup(def->os.bootloaderArgs)))
             goto error_cleanup;
 
-    if (def->memory)
-        (*record)->memory_static_max = (int64_t) (def->memory * 1024);
-    if (def->maxmem)
-        (*record)->memory_dynamic_max = (int64_t) (def->maxmem * 1024);
+    if (def->mem.cur_balloon)
+        (*record)->memory_static_max = (int64_t) (def->mem.cur_balloon * 1024);
+    if (def->mem.max_balloon)
+        (*record)->memory_dynamic_max = (int64_t) (def->mem.max_balloon * 1024);
     else
         (*record)->memory_dynamic_max = (*record)->memory_static_max;
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memtune.args b/tests/qemuxml2argvdata/qemuxml2argv-memtune.args
new file mode 100644 (file)
index 0000000..50da44f
--- /dev/null
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -name QEMUGuest1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memtune.xml b/tests/qemuxml2argvdata/qemuxml2argv-memtune.xml
new file mode 100644 (file)
index 0000000..9f713f0
--- /dev/null
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <memtune>
+    <hard_limit>512000</hard_limit>
+    <soft_limit>128000</soft_limit>
+    <swap_hard_limit>1024000</swap_hard_limit>
+  </memtune>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <controller type='ide' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 904183c65804ef66fc9ce9382818a45ec2598a82..a33d435a11acd4e0200c71086725c50bef42e244 100644 (file)
@@ -178,6 +178,7 @@ mymain(int argc, char **argv)
     DO_TEST("hostdev-pci-address");
 
     DO_TEST("encrypted-disk");
+    DO_TEST("memtune");
 
     /* These tests generate different XML */
     DO_TEST_DIFFERENT("balloon-device-auto");