From 7e9660dbc7da853687a9855a44a8705454f06a41 Mon Sep 17 00:00:00 2001
From: Jaroslav Safka <jaroslavx.safka@intel.com>
Date: Thu, 16 Jun 2016 14:40:48 +0200
Subject: [PATCH] Add new elements source,access and allocation

3 new elements in memoryBacking are now parsed
(without command association yet)

<memoryBacking>
  <source type="file|anonymous"/>
  <access Mode="shared|private"/>
  <allocation mode="immediate|ondemand"/>
</memoryBacking>
---
 docs/schemas/domaincommon.rng                      | 45 +++++++++++++++++
 src/conf/domain_conf.c                             | 59 +++++++++++++++++++++-
 src/conf/domain_conf.h                             | 31 ++++++++++++
 .../qemuxml2argv-memorybacking-set.args            | 22 ++++++++
 .../qemuxml2argv-memorybacking-set.xml             | 32 ++++++++++++
 .../qemuxml2argv-memorybacking-unset.args          | 22 ++++++++
 .../qemuxml2argv-memorybacking-unset.xml           | 32 ++++++++++++
 .../qemuxml2xmlout-memorybacking-set.xml           | 40 +++++++++++++++
 .../qemuxml2xmlout-memorybacking-unset.xml         | 40 +++++++++++++++
 tests/qemuxml2xmltest.c                            |  3 ++
 10 files changed, 325 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 162c2e0..b1bdcc7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -546,6 +546,27 @@
                 <empty/>
               </element>
             </optional>
+            <optional>
+              <element name="source">
+                <attribute name="type">
+                   <ref name="mbSourceType"/>
+                </attribute>
+              </element>
+            </optional>
+            <optional>
+              <element name="access">
+                <attribute name="mode">
+                   <ref name="mbAccessMode"/>
+                </attribute>
+              </element>
+            </optional>
+            <optional>
+              <element name="allocation">
+                <attribute name="mode">
+                   <ref name="mbAllocMode"/>
+                </attribute>
+              </element>
+            </optional>
           </interleave>
         </element>
       </optional>
@@ -5597,4 +5618,28 @@
       </choice>
     </attribute>
   </define>
+  <define name="mbSourceType">
+    <attribute name="sourcetype">
+      <choice>
+        <value>file</value>
+        <value>anonymous</value>
+      </choice>
+    </attribute>
+  </define>
+  <define name="mbAccessMode">
+    <attribute name="accessmode">
+      <choice>
+        <value>shared</value>
+        <value>private</value>
+      </choice>
+    </attribute>
+  </define>
+  <define name="mbAllocMode">
+    <attribute name="allocmode">
+      <choice>
+        <value>immediate</value>
+        <value>ondemand</value>
+      </choice>
+    </attribute>
+  </define>
 </grammar>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 69995cc..524a2b8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -819,6 +819,21 @@ VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST,
               "abort",
               "pivot")
 
+VIR_ENUM_IMPL(virDomainMemorySource, VIR_DOMAIN_MEMORY_SOURCE_LAST,
+              "none",
+              "file",
+              "anonymous")
+
+VIR_ENUM_IMPL(virDomainMemoryAccess, VIR_DOMAIN_MEMORY_ACCESS_LAST,
+              "none",
+              "shared",
+              "private")
+
+VIR_ENUM_IMPL(virDomainMemoryAllocation, VIR_DOMAIN_MEMORY_ALLOCATION_LAST,
+              "none",
+              "immediate",
+              "ondemand")
+
 VIR_ENUM_IMPL(virDomainLoader,
               VIR_DOMAIN_LOADER_TYPE_LAST,
               "rom",
@@ -15848,6 +15863,36 @@ virDomainDefParseXML(xmlDocPtr xml,
     if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt))
         def->mem.locked = true;
 
+    tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt);
+    if (tmp) {
+        if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) < 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown memoryBacking/source/type '%s'"), tmp);
+            goto error;
+        }
+        VIR_FREE(tmp);
+    }
+
+    tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt);
+    if (tmp) {
+        if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) < 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown memoryBacking/access/mode '%s'"), tmp);
+            goto error;
+        }
+        VIR_FREE(tmp);
+    }
+
+    tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt);
+    if (tmp) {
+        if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) < 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown memoryBacking/allocation/mode '%s'"), tmp);
+            goto error;
+        }
+        VIR_FREE(tmp);
+    }
+
     /* Extract blkio cgroup tunables */
     if (virXPathUInt("string(./blkiotune/weight)", ctxt,
                      &def->blkio.weight) < 0)
@@ -22883,7 +22928,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
         virBufferAddLit(buf, "</memtune>\n");
     }
 
-    if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked) {
+    if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked
+        || def->mem.source || def->mem.access || def->mem.allocation)
+    {
         virBufferAddLit(buf, "<memoryBacking>\n");
         virBufferAdjustIndent(buf, 2);
         if (def->mem.nhugepages)
@@ -22892,6 +22939,16 @@ virDomainDefFormatInternal(virDomainDefPtr def,
             virBufferAddLit(buf, "<nosharepages/>\n");
         if (def->mem.locked)
             virBufferAddLit(buf, "<locked/>\n");
+        if (def->mem.source)
+           virBufferAsprintf(buf, "<source type='%s'/>\n",
+                virDomainMemorySourceTypeToString(def->mem.source));
+        if (def->mem.access)
+           virBufferAsprintf(buf, "<access mode='%s'/>\n",
+                virDomainMemoryAccessTypeToString(def->mem.access));
+        if (def->mem.allocation)
+           virBufferAsprintf(buf, "<allocation mode='%s'/>\n",
+                virDomainMemoryAllocationTypeToString(def->mem.allocation));
+
         virBufferAdjustIndent(buf, -2);
         virBufferAddLit(buf, "</memoryBacking>\n");
     }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 428f85d..602794b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -565,6 +565,30 @@ typedef enum {
     VIR_DOMAIN_DISK_MIRROR_STATE_LAST
 } virDomainDiskMirrorState;
 
+typedef enum {
+    VIR_DOMAIN_MEMORY_SOURCE_NONE = 0,  /* No memory source defined */
+    VIR_DOMAIN_MEMORY_SOURCE_FILE,      /* Memory source is set as file */
+    VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS, /* Memory source is set as anonymous */
+
+    VIR_DOMAIN_MEMORY_SOURCE_LAST,
+} virDomainMemorySource;
+
+typedef enum {
+    VIR_DOMAIN_MEMORY_ACCESS_NONE = 0,  /*  No memory access defined */
+    VIR_DOMAIN_MEMORY_ACCESS_SHARED,    /* Memory access is set as shared */
+    VIR_DOMAIN_MEMORY_ACCESS_PRIVATE,   /* Memory access is set as private */
+
+    VIR_DOMAIN_MEMORY_ACCESS_LAST,
+} virDomainMemoryAccess;
+
+typedef enum {
+    VIR_DOMAIN_MEMORY_ALLOCATION_NONE = 0,  /* No memory allocation defined */
+    VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE, /* Memory allocation is set as immediate */
+    VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND,  /* Memory allocation is set as ondemand */
+
+    VIR_DOMAIN_MEMORY_ALLOCATION_LAST,
+} virDomainMemoryAllocation;
+
 
 /* Stores the virtual disk configuration */
 struct _virDomainDiskDef {
@@ -2087,6 +2111,10 @@ struct _virDomainMemtune {
     unsigned long long soft_limit; /* in kibibytes, limit at off_t bytes */
     unsigned long long min_guarantee; /* in kibibytes, limit at off_t bytes */
     unsigned long long swap_hard_limit; /* in kibibytes, limit at off_t bytes */
+
+    int source; /* enum virDomainMemorySource */
+    int access; /* enum virDomainMemoryAccess */
+    int allocation; /* enum virDomainMemoryAllocation */
 };
 
 typedef struct _virDomainPowerManagement virDomainPowerManagement;
@@ -3002,6 +3030,9 @@ VIR_ENUM_DECL(virDomainTPMModel)
 VIR_ENUM_DECL(virDomainTPMBackend)
 VIR_ENUM_DECL(virDomainMemoryModel)
 VIR_ENUM_DECL(virDomainMemoryBackingModel)
+VIR_ENUM_DECL(virDomainMemorySource)
+VIR_ENUM_DECL(virDomainMemoryAccess)
+VIR_ENUM_DECL(virDomainMemoryAllocation)
 /* from libvirt.h */
 VIR_ENUM_DECL(virDomainState)
 VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.args b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.args
new file mode 100644
index 0000000..bb702dc
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.args
@@ -0,0 +1,22 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name SomeDummyHugepagesGuest \
+-S \
+-M pc \
+-m 1024 \
+-smp 2 \
+-uuid ef1bdff4-27f3-4e85-a807-5fb4d58463cc \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-SomeDummyHugepagesGu/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml
new file mode 100644
index 0000000..655eb8d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>SomeDummyHugepagesGuest</name>
+  <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <source type='file'/>
+    <access mode='shared'/>
+    <allocation mode='immediate'/>
+  </memoryBacking>
+  <vcpu placement='static'>2</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' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.args b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.args
new file mode 100644
index 0000000..bb702dc
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.args
@@ -0,0 +1,22 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name SomeDummyHugepagesGuest \
+-S \
+-M pc \
+-m 1024 \
+-smp 2 \
+-uuid ef1bdff4-27f3-4e85-a807-5fb4d58463cc \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-SomeDummyHugepagesGu/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
new file mode 100644
index 0000000..74f8a12
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>SomeDummyHugepagesGuest</name>
+  <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <source type="anonymous"/>
+    <access mode="private"/>
+    <allocation mode="ondemand"/>
+  </memoryBacking>
+  <vcpu placement='static'>2</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' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml
new file mode 100644
index 0000000..f63ae38
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+  <name>SomeDummyHugepagesGuest</name>
+  <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <source type='file'/>
+    <access mode='shared'/>
+    <allocation mode='immediate'/>
+  </memoryBacking>
+  <vcpu placement='static'>2</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' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml
new file mode 100644
index 0000000..7de9ffb
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+  <name>SomeDummyHugepagesGuest</name>
+  <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <source type='anonymous'/>
+    <access mode='private'/>
+    <allocation mode='ondemand'/>
+  </memoryBacking>
+  <vcpu placement='static'>2</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' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 7db9cb7..5adf1a7 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -822,6 +822,9 @@ mymain(void)
     DO_TEST("virtio-input");
     DO_TEST("virtio-input-passthrough");
 
+    DO_TEST("memorybacking-set");
+    DO_TEST("memorybacking-unset");
+
     virObjectUnref(cfg);
 
     DO_TEST("acpi-table");
-- 
2.8.3

