Provides the source for pools backed by physical devices
+@@ -386,6 +396,12 @@
+ LVM metadata type. All drivers are required to have a default
+ value for this, so it is optional. Since 0.4.1
+
++
protocol
++
For a netfs Storage Pool provide a mechanism to
++ define which NFS protocol version number will be used to contact
++ the server's NFS service. The attribute ver accepts
++ an unsigned integer as the version number to use.
++ Since 5.1.0
+
vendor
+
Provides optional information about the vendor of the
+ storage device. This contains a single
+diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng
+index 52b2044bef..0cb8beb926 100644
+--- a/docs/schemas/storagepool.rng
++++ b/docs/schemas/storagepool.rng
+@@ -520,6 +520,13 @@
+
+
+
++
++
++
++
++
++
++
+
+
+
+diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
+index 5036ab9ef8..5a124a0a2f 100644
+--- a/src/conf/storage_conf.c
++++ b/src/conf/storage_conf.c
+@@ -415,6 +415,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
+ virStorageAuthDefPtr authdef = NULL;
+ char *name = NULL;
+ char *port = NULL;
++ char *ver = NULL;
+ int n;
+
+ relnode = ctxt->node;
+@@ -540,6 +541,24 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
+ authdef = NULL;
+ }
+
++ /* Option protocol version string (NFSvN) */
++ if ((ver = virXPathString("string(./protocol/@ver)", ctxt))) {
++ if ((source->format != VIR_STORAGE_POOL_NETFS_NFS) &&
++ (source->format != VIR_STORAGE_POOL_NETFS_AUTO)) {
++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++ _("storage pool protocol ver unsupported for "
++ "pool type '%s'"),
++ virStoragePoolFormatFileSystemNetTypeToString(source->format));
++ goto cleanup;
++ }
++ if (virStrToLong_uip(ver, NULL, 0, &source->protocolVer) < 0) {
++ virReportError(VIR_ERR_XML_ERROR,
++ _("storage pool protocol ver '%s' is malformaed"),
++ ver);
++ goto cleanup;
++ }
++ }
++
+ source->vendor = virXPathString("string(./vendor/@name)", ctxt);
+ source->product = virXPathString("string(./product/@name)", ctxt);
+
+@@ -956,6 +975,9 @@ virStoragePoolSourceFormat(virBufferPtr buf,
+ if (src->auth)
+ virStorageAuthDefFormat(buf, src->auth);
+
++ if (src->protocolVer)
++ virBufferAsprintf(buf, "\n", src->protocolVer);
++
+ virBufferEscapeString(buf, "\n", src->vendor);
+ virBufferEscapeString(buf, "\n", src->product);
+
+diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
+index 15dfd8becf..3b637e2258 100644
+--- a/src/conf/storage_conf.h
++++ b/src/conf/storage_conf.h
+@@ -203,6 +203,9 @@ struct _virStoragePoolSource {
+ * or lvm version, etc.
+ */
+ int format;
++
++ /* Protocol version value for netfs */
++ unsigned int protocolVer;
+ };
+
+ typedef struct _virStoragePoolTarget virStoragePoolTarget;
+diff --git a/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml b/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml
+new file mode 100644
+index 0000000000..40f3f94e41
+--- /dev/null
++++ b/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml
+@@ -0,0 +1,21 @@
++
++ nfsimages
++ 7641d5a8-af11-f730-a34e-0a7dfcede71f
++ 0
++ 0
++ 0
++
++
++ /mnt
++
++ 0700
++ 0
++ 0
++
++
++
+diff --git a/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml b/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml
+new file mode 100644
+index 0000000000..5fcad1305b
+--- /dev/null
++++ b/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml
+@@ -0,0 +1,21 @@
++
++ nfsimages
++ 7641d5a8-af11-f730-a34e-0a7dfcede71f
++ 0
++ 0
++ 0
++
++
++ /mnt
++
++ 0700
++ 0
++ 0
++
++
++
+diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c
+index 29c0e42479..cf41b4d065 100644
+--- a/tests/storagepoolxml2xmltest.c
++++ b/tests/storagepoolxml2xmltest.c
+@@ -86,6 +86,7 @@ mymain(void)
+ DO_TEST("pool-iscsi-auth");
+ DO_TEST("pool-netfs");
+ DO_TEST("pool-netfs-auto");
++ DO_TEST("pool-netfs-protocol-ver");
+ DO_TEST("pool-netfs-gluster");
+ DO_TEST("pool-netfs-cifs");
+ DO_TEST("pool-scsi");
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Add-return-value-check-to-virResctrlAllocForeachCache.patch b/SOURCES/libvirt-conf-Add-return-value-check-to-virResctrlAllocForeachCache.patch
new file mode 100644
index 0000000..13da8f8
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-return-value-check-to-virResctrlAllocForeachCache.patch
@@ -0,0 +1,49 @@
+From 7a8c614b37e0d7e1b2eac08a72f46ef715b72c5a Mon Sep 17 00:00:00 2001
+Message-Id: <7a8c614b37e0d7e1b2eac08a72f46ef715b72c5a@dist-git>
+From: Bing Niu
+Date: Mon, 15 Apr 2019 17:32:59 +0200
+Subject: [PATCH] conf: Add return value check to virResctrlAllocForeachCache
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add return value check to virResctrlAllocForeachCache in
+virDomainCachetuneDefFormat. The virResctrlAllocForeachCache does have
+return value, so need check return value to make sure function executed
+without error.
+
+Signed-off-by: Bing Niu
+Reviewed-by: John Ferlan
+(cherry picked from commit 8d6f508e64728f9aaa5a624462ac0da325854cad)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ src/conf/domain_conf.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 2f56c077a9..74781fe596 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -27258,10 +27258,10 @@ virDomainCachetuneDefFormat(virBufferPtr buf,
+ int ret = -1;
+
+ virBufferSetChildIndent(&childrenBuf, buf);
+- virResctrlAllocForeachCache(resctrl->alloc,
+- virDomainCachetuneDefFormatHelper,
+- &childrenBuf);
+-
++ if (virResctrlAllocForeachCache(resctrl->alloc,
++ virDomainCachetuneDefFormatHelper,
++ &childrenBuf) < 0)
++ goto cleanup;
+
+ if (virBufferCheckError(&childrenBuf) < 0)
+ goto cleanup;
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Add-support-for-memorytune-XML-processing-for-resctrl-MBA.patch b/SOURCES/libvirt-conf-Add-support-for-memorytune-XML-processing-for-resctrl-MBA.patch
new file mode 100644
index 0000000..2d34310
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-support-for-memorytune-XML-processing-for-resctrl-MBA.patch
@@ -0,0 +1,503 @@
+From 1240e6d5b3d53a34a94b308ddf2f10a12f2556f6 Mon Sep 17 00:00:00 2001
+Message-Id: <1240e6d5b3d53a34a94b308ddf2f10a12f2556f6@dist-git>
+From: Bing Niu
+Date: Mon, 15 Apr 2019 17:32:58 +0200
+Subject: [PATCH] conf: Add support for memorytune XML processing for resctrl
+ MBA
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce a new section memorytune to support memory bandwidth allocation.
+This is consistent with existing cachetune. As the example:
+below:
+
+ ......
+
+
+
+
+
+vpus --- vpus subjected to this memory bandwidth.
+id --- on which node memory bandwidth to be set.
+bandwidth --- the memory bandwidth percent to set.
+
+Signed-off-by: Bing Niu
+Reviewed-by: John Ferlan
+(cherry picked from commit 6956b7eedce4cb6dc2f95684fc3e10c163dfc6fc)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id: <3139e3b8f3c3d66891847b5a99bd9125ec01f00b.1555342313.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ docs/formatdomain.html.in | 39 +++-
+ docs/schemas/domaincommon.rng | 17 ++
+ src/conf/domain_conf.c | 200 ++++++++++++++++++
+ .../memorytune-colliding-allocs.xml | 30 +++
+ .../memorytune-colliding-cachetune.xml | 32 +++
+ tests/genericxml2xmlindata/memorytune.xml | 33 +++
+ tests/genericxml2xmltest.c | 5 +
+ 7 files changed, 355 insertions(+), 1 deletion(-)
+ create mode 100644 tests/genericxml2xmlindata/memorytune-colliding-allocs.xml
+ create mode 100644 tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml
+ create mode 100644 tests/genericxml2xmlindata/memorytune.xml
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 42acf7a828..8cf2c12524 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -757,6 +757,10 @@
+ <cache id='0' level='3' type='both' size='3' unit='MiB'/>
+ <cache id='1' level='3' type='both' size='3' unit='MiB'/>
+ </cachetune>
++ <memorytune vcpus='0-3'>
++ <node id='0' bandwidth='60'/>
++ </memorytune>
++
+ </cputune>
+ ...
+ </domain>
+@@ -910,7 +914,9 @@
+ size and required granularity are reported as well. The required
+ attribute vcpus specifies to which vCPUs this allocation
+ applies. A vCPU can only be member of one cachetune element
+- allocations. Supported subelements are:
++ allocation. The vCPUs specified by cachetune can be identical with those
++ in memorytune, however they are not allowed to overlap.
++ Supported subelements are:
+
+
cache
+
+@@ -950,7 +956,38 @@
+
+
+
++
+
++
memorytuneSince 4.7.0
++
++ Optional memorytune element can control allocations for
++ memory bandwidth using the resctrl on the host. Whether or not is this
++ supported can be gathered from capabilities where some limitations like
++ minimum bandwidth and required granularity are reported as well. The
++ required attribute vcpus specifies to which vCPUs this
++ allocation applies. A vCPU can only be member of one
++ memorytune element allocation. The vcpus specified
++ by memorytune can be identical to those specified by
++ cachetune. However they are not allowed to overlap each other.
++ Supported subelements are:
++
++
node
++
++ This element controls the allocation of CPU memory bandwidth and has the
++ following attributes:
++
++
id
++
++ Host node id from which to allocate memory bandwidth.
++
++
bandwidth
++
++ The memory bandwidth to allocate from this node. The value by default
++ is in percentage.
++
++
++
++
+
+
+
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index ac04af51a1..48f0637cad 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -983,6 +983,23 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 44bfd75b72..2f56c077a9 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19296,6 +19296,129 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ }
+
+
++static int
++virDomainMemorytuneDefParseMemory(xmlXPathContextPtr ctxt,
++ xmlNodePtr node,
++ virResctrlAllocPtr alloc)
++{
++ xmlNodePtr oldnode = ctxt->node;
++ unsigned int id;
++ unsigned int bandwidth;
++ char *tmp = NULL;
++ int ret = -1;
++
++ ctxt->node = node;
++
++ tmp = virXMLPropString(node, "id");
++ if (!tmp) {
++ virReportError(VIR_ERR_XML_ERROR, "%s",
++ _("Missing memorytune attribute 'id'"));
++ goto cleanup;
++ }
++ if (virStrToLong_uip(tmp, NULL, 10, &id) < 0) {
++ virReportError(VIR_ERR_XML_ERROR,
++ _("Invalid memorytune attribute 'id' value '%s'"),
++ tmp);
++ goto cleanup;
++ }
++ VIR_FREE(tmp);
++
++ tmp = virXMLPropString(node, "bandwidth");
++ if (!tmp) {
++ virReportError(VIR_ERR_XML_ERROR, "%s",
++ _("Missing memorytune attribute 'bandwidth'"));
++ goto cleanup;
++ }
++ if (virStrToLong_uip(tmp, NULL, 10, &bandwidth) < 0) {
++ virReportError(VIR_ERR_XML_ERROR,
++ _("Invalid memorytune attribute 'bandwidth' value '%s'"),
++ tmp);
++ goto cleanup;
++ }
++ VIR_FREE(tmp);
++ if (virResctrlAllocSetMemoryBandwidth(alloc, id, bandwidth) < 0)
++ goto cleanup;
++
++ ret = 0;
++ cleanup:
++ ctxt->node = oldnode;
++ VIR_FREE(tmp);
++ return ret;
++}
++
++
++static int
++virDomainMemorytuneDefParse(virDomainDefPtr def,
++ xmlXPathContextPtr ctxt,
++ xmlNodePtr node,
++ unsigned int flags)
++{
++ xmlNodePtr oldnode = ctxt->node;
++ xmlNodePtr *nodes = NULL;
++ virBitmapPtr vcpus = NULL;
++ virResctrlAllocPtr alloc = NULL;
++ ssize_t i = 0;
++ int n;
++ int ret = -1;
++ bool new_alloc = false;
++
++ ctxt->node = node;
++
++ if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0)
++ goto cleanup;
++
++ if (virBitmapIsAllClear(vcpus)) {
++ ret = 0;
++ goto cleanup;
++ }
++
++ if ((n = virXPathNodeSet("./node", ctxt, &nodes)) < 0) {
++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++ _("Cannot extract memory nodes under memorytune"));
++ goto cleanup;
++ }
++
++ if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0)
++ goto cleanup;
++
++ if (!alloc) {
++ alloc = virResctrlAllocNew();
++ if (!alloc)
++ goto cleanup;
++ new_alloc = true;
++ } else {
++ alloc = virObjectRef(alloc);
++ }
++
++ for (i = 0; i < n; i++) {
++ if (virDomainMemorytuneDefParseMemory(ctxt, nodes[i], alloc) < 0)
++ goto cleanup;
++ }
++ if (virResctrlAllocIsEmpty(alloc)) {
++ ret = 0;
++ goto cleanup;
++ }
++ /*
++ * If this is a new allocation, format ID and append to resctrl, otherwise
++ * just update the existing alloc information, which is done in above
++ * virDomainMemorytuneDefParseMemory */
++ if (new_alloc) {
++ if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
++ goto cleanup;
++ vcpus = NULL;
++ alloc = NULL;
++ }
++
++ ret = 0;
++ cleanup:
++ ctxt->node = oldnode;
++ virObjectUnref(alloc);
++ virBitmapFree(vcpus);
++ VIR_FREE(nodes);
++ return ret;
++}
++
++
+ static virDomainDefPtr
+ virDomainDefParseXML(xmlDocPtr xml,
+ xmlNodePtr root,
+@@ -19856,6 +19979,18 @@ virDomainDefParseXML(xmlDocPtr xml,
+ }
+ VIR_FREE(nodes);
+
++ if ((n = virXPathNodeSet("./cputune/memorytune", ctxt, &nodes)) < 0) {
++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++ _("cannot extract memorytune nodes"));
++ goto error;
++ }
++
++ for (i = 0; i < n; i++) {
++ if (virDomainMemorytuneDefParse(def, ctxt, nodes[i], flags) < 0)
++ goto error;
++ }
++ VIR_FREE(nodes);
++
+ if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu) < 0)
+ goto error;
+
+@@ -27162,6 +27297,68 @@ virDomainCachetuneDefFormat(virBufferPtr buf,
+ }
+
+
++static int
++virDomainMemorytuneDefFormatHelper(unsigned int id,
++ unsigned int bandwidth,
++ void *opaque)
++{
++ virBufferPtr buf = opaque;
++
++ virBufferAsprintf(buf,
++ "\n",
++ id, bandwidth);
++ return 0;
++}
++
++
++static int
++virDomainMemorytuneDefFormat(virBufferPtr buf,
++ virDomainResctrlDefPtr resctrl,
++ unsigned int flags)
++{
++ virBuffer childrenBuf = VIR_BUFFER_INITIALIZER;
++ char *vcpus = NULL;
++ int ret = -1;
++
++ virBufferSetChildIndent(&childrenBuf, buf);
++ if (virResctrlAllocForeachMemory(resctrl->alloc,
++ virDomainMemorytuneDefFormatHelper,
++ &childrenBuf) < 0)
++ goto cleanup;
++
++ if (virBufferCheckError(&childrenBuf) < 0)
++ goto cleanup;
++
++ if (!virBufferUse(&childrenBuf)) {
++ ret = 0;
++ goto cleanup;
++ }
++
++ vcpus = virBitmapFormat(resctrl->vcpus);
++ if (!vcpus)
++ goto cleanup;
++
++ virBufferAsprintf(buf, "alloc);
++ if (!alloc_id)
++ goto cleanup;
++
++ virBufferAsprintf(buf, " id='%s'", alloc_id);
++ }
++ virBufferAddLit(buf, ">\n");
++
++ virBufferAddBuffer(buf, &childrenBuf);
++ virBufferAddLit(buf, "\n");
++
++ ret = 0;
++ cleanup:
++ virBufferFreeAndReset(&childrenBuf);
++ VIR_FREE(vcpus);
++ return ret;
++}
++
+ static int
+ virDomainCputuneDefFormat(virBufferPtr buf,
+ virDomainDefPtr def,
+@@ -27267,6 +27464,9 @@ virDomainCputuneDefFormat(virBufferPtr buf,
+ for (i = 0; i < def->nresctrls; i++)
+ virDomainCachetuneDefFormat(&childrenBuf, def->resctrls[i], flags);
+
++ for (i = 0; i < def->nresctrls; i++)
++ virDomainMemorytuneDefFormat(&childrenBuf, def->resctrls[i], flags);
++
+ if (virBufferCheckError(&childrenBuf) < 0)
+ return -1;
+
+diff --git a/tests/genericxml2xmlindata/memorytune-colliding-allocs.xml b/tests/genericxml2xmlindata/memorytune-colliding-allocs.xml
+new file mode 100644
+index 0000000000..9b8ebaa084
+--- /dev/null
++++ b/tests/genericxml2xmlindata/memorytune-colliding-allocs.xml
+@@ -0,0 +1,30 @@
++
++ QEMUGuest1
++ c7a5fdbd-edaf-9455-926a-d65c16db1809
++ 219136
++ 219136
++ 4
++
++
++
++
++
++
++
++ hvm
++
++
++
++ destroy
++ restart
++ destroy
++
++ /usr/bin/qemu-system-i686
++
++
++
++
++
++
++
++
+diff --git a/tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml b/tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml
+new file mode 100644
+index 0000000000..5416870de2
+--- /dev/null
++++ b/tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml
+@@ -0,0 +1,32 @@
++
++ QEMUGuest1
++ c7a5fdbd-edaf-9455-926a-d65c16db1809
++ 219136
++ 219136
++ 4
++
++
++
++
++
++
++
++
++
++ hvm
++
++
++
++ destroy
++ restart
++ destroy
++
++ /usr/bin/qemu-system-i686
++
++
++
++
++
++
++
++
+diff --git a/tests/genericxml2xmlindata/memorytune.xml b/tests/genericxml2xmlindata/memorytune.xml
+new file mode 100644
+index 0000000000..ea03e22fc2
+--- /dev/null
++++ b/tests/genericxml2xmlindata/memorytune.xml
+@@ -0,0 +1,33 @@
++
++ QEMUGuest1
++ c7a5fdbd-edaf-9455-926a-d65c16db1809
++ 219136
++ 219136
++ 4
++
++
++
++
++
++
++
++
++
++
++ hvm
++
++
++
++ destroy
++ restart
++ destroy
++
++ /usr/bin/qemu-system-i686
++
++
++
++
++
++
++
++
+diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
+index 7a4fc1eb7a..e6d4ef2a7f 100644
+--- a/tests/genericxml2xmltest.c
++++ b/tests/genericxml2xmltest.c
+@@ -140,6 +140,11 @@ mymain(void)
+ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
+ DO_TEST_FULL("cachetune-colliding-types", false, true,
+ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
++ DO_TEST("memorytune");
++ DO_TEST_FULL("memorytune-colliding-allocs", false, true,
++ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
++ DO_TEST_FULL("memorytune-colliding-cachetune", false, true,
++ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
+
+ DO_TEST("tseg");
+
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch
new file mode 100644
index 0000000..ab7257b
--- /dev/null
+++ b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch
@@ -0,0 +1,68 @@
+From bb9521f7e0e8a67f04b5776cccf8b458a16bc94b Mon Sep 17 00:00:00 2001
+Message-Id:
+From: Michal Privoznik
+Date: Thu, 18 Apr 2019 18:43:10 +0200
+Subject: [PATCH] conf: Expose virDomainSCSIDriveAddressIsUsed
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1692296
+
+This function checks if given drive address is already present in
+passed domain definition. Expose the function as it will be used
+shortly.
+
+Signed-off-by: Michal Privoznik
+Tested-by: Daniel Henrique Barboza
+Reviewed-by: Jim Fehlig
+(cherry picked from commit 89237d534f0fe950d06a2081089154160c6c2224)
+Signed-off-by: Michal Privoznik
+Message-Id: <79f85c93272ac232b81cb80f80d1ba396d557198.1555605741.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ src/conf/domain_conf.c | 2 +-
+ src/conf/domain_conf.h | 4 ++++
+ src/libvirt_private.syms | 1 +
+ 3 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 712efbb9f9..1096499831 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -4400,7 +4400,7 @@ virDomainDriveAddressIsUsedByHostdev(const virDomainDef *def,
+ * Return true if the SCSI drive address is already in use, false
+ * otherwise.
+ */
+-static bool
++bool
+ virDomainSCSIDriveAddressIsUsed(const virDomainDef *def,
+ const virDomainDeviceDriveAddress *addr)
+ {
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 5e2f21dea3..390bd81aa0 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -2785,6 +2785,10 @@ virDomainXMLNamespacePtr
+ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
+ ATTRIBUTE_NONNULL(1);
+
++bool
++virDomainSCSIDriveAddressIsUsed(const virDomainDef *def,
++ const virDomainDeviceDriveAddress *addr);
++
+ int virDomainDefPostParse(virDomainDefPtr def,
+ virCapsPtr caps,
+ unsigned int parseFlags,
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 3325b90535..3000d6ee0a 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -520,6 +520,7 @@ virDomainRunningReasonTypeToString;
+ virDomainSaveConfig;
+ virDomainSaveStatus;
+ virDomainSaveXML;
++virDomainSCSIDriveAddressIsUsed;
+ virDomainSeclabelTypeFromString;
+ virDomainSeclabelTypeToString;
+ virDomainShmemDefEquals;
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Factor-out-vcpus-overlapping-from-virDomainCachetuneDefParse.patch b/SOURCES/libvirt-conf-Factor-out-vcpus-overlapping-from-virDomainCachetuneDefParse.patch
new file mode 100644
index 0000000..f46e7db
--- /dev/null
+++ b/SOURCES/libvirt-conf-Factor-out-vcpus-overlapping-from-virDomainCachetuneDefParse.patch
@@ -0,0 +1,124 @@
+From c00106d41b74d86ee7357ed62399ea7ffb9cd393 Mon Sep 17 00:00:00 2001
+Message-Id:
+From: Bing Niu
+Date: Mon, 15 Apr 2019 17:32:56 +0200
+Subject: [PATCH] conf: Factor out vcpus overlapping from
+ virDomainCachetuneDefParse
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Factor out vcpus overlapping detecting part from
+virDomainCachetuneDefParse and introduce virDomainResctrlVcpuMatch.
+Instead of allocating virResctrlAllocPtr by default, allocating
+virResctrlAllocPtr after confirm vcpus not overlap with existing ones.
+And virDomainResctrlVcpuMatch can be reused by other resource control
+technologies. virDomainResctrlVcpuMatch can clarify old vcpus overlap
+error whether an overlap or a redefinition.
+
+Signed-off-by: Bing Niu
+Reviewed-by: John Ferlan
+(cherry picked from commit e5cc7c0a0258530000aa9fd930c649b525b6f801)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ src/conf/domain_conf.c | 51 ++++++++++++++++++++++++++++++++----------
+ 1 file changed, 39 insertions(+), 12 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 07d21f8026..fb5adbcd10 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19077,6 +19077,31 @@ virDomainResctrlParseVcpus(virDomainDefPtr def,
+ }
+
+
++static int
++virDomainResctrlVcpuMatch(virDomainDefPtr def,
++ virBitmapPtr vcpus,
++ virResctrlAllocPtr *alloc)
++{
++ ssize_t i = 0;
++
++ for (i = 0; i < def->nresctrls; i++) {
++ /* vcpus group has been created, directly use the existing one.
++ * Just updating memory allocation information of that group
++ */
++ if (virBitmapEqual(def->resctrls[i]->vcpus, vcpus)) {
++ *alloc = def->resctrls[i]->alloc;
++ break;
++ }
++ if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) {
++ virReportError(VIR_ERR_XML_ERROR, "%s",
++ _("Overlapping vcpus in resctrls"));
++ return -1;
++ }
++ }
++ return 0;
++}
++
++
+ static int
+ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt,
+ xmlNodePtr node,
+@@ -19160,7 +19185,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ xmlNodePtr oldnode = ctxt->node;
+ xmlNodePtr *nodes = NULL;
+ virBitmapPtr vcpus = NULL;
+- virResctrlAllocPtr alloc = virResctrlAllocNew();
++ virResctrlAllocPtr alloc = NULL;
+ virDomainResctrlDefPtr tmp_resctrl = NULL;
+ char *tmp = NULL;
+ char *vcpus_str = NULL;
+@@ -19171,9 +19196,6 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+
+ ctxt->node = node;
+
+- if (!alloc)
+- goto cleanup;
+-
+ if (VIR_ALLOC(tmp_resctrl) < 0)
+ goto cleanup;
+
+@@ -19191,6 +19213,19 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ goto cleanup;
+ }
+
++ if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0)
++ goto cleanup;
++
++ if (!alloc) {
++ alloc = virResctrlAllocNew();
++ if (!alloc)
++ goto cleanup;
++ } else {
++ virReportError(VIR_ERR_XML_ERROR, "%s",
++ _("Identical vcpus in cachetunes found"));
++ goto cleanup;
++ }
++
+ for (i = 0; i < n; i++) {
+ if (virDomainCachetuneDefParseCache(ctxt, nodes[i], alloc) < 0)
+ goto cleanup;
+@@ -19201,14 +19236,6 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ goto cleanup;
+ }
+
+- for (i = 0; i < def->nresctrls; i++) {
+- if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) {
+- virReportError(VIR_ERR_XML_ERROR, "%s",
+- _("Overlapping vcpus in cachetunes"));
+- goto cleanup;
+- }
+- }
+-
+ /* We need to format it back because we need to be consistent in the naming
+ * even when users specify some "sub-optimal" string there. */
+ VIR_FREE(vcpus_str);
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Factor-out-vcpus-parsing-part-from-virDomainCachetuneDefParse.patch b/SOURCES/libvirt-conf-Factor-out-vcpus-parsing-part-from-virDomainCachetuneDefParse.patch
new file mode 100644
index 0000000..461216f
--- /dev/null
+++ b/SOURCES/libvirt-conf-Factor-out-vcpus-parsing-part-from-virDomainCachetuneDefParse.patch
@@ -0,0 +1,99 @@
+From ca59034c25fe39acb246f82587c0c32ba04d6c89 Mon Sep 17 00:00:00 2001
+Message-Id:
+From: Bing Niu
+Date: Mon, 15 Apr 2019 17:32:55 +0200
+Subject: [PATCH] conf: Factor out vcpus parsing part from
+ virDomainCachetuneDefParse
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Extract vcpus parsing part from virDomainCachetuneDefParse into one
+function called virDomainResctrlParseVcpus. So that vcpus parsing logic
+can be reused by other resource control technologies. Adjust error
+message and use node->name so that the error message can fit to all
+technologies.
+
+Signed-off-by: Bing Niu
+Reviewed-by: John Ferlan
+(cherry picked from commit 6021c3926ba62a2593f0db63e5413e9663c69a5f)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id: <2f330b4bbface15dce23370d5f212b2240e031cd.1555342313.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ src/conf/domain_conf.c | 48 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 33 insertions(+), 15 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 0c8afe78c6..07d21f8026 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19045,6 +19045,38 @@ virDomainDefParseBootOptions(virDomainDefPtr def,
+ }
+
+
++static int
++virDomainResctrlParseVcpus(virDomainDefPtr def,
++ xmlNodePtr node,
++ virBitmapPtr *vcpus)
++{
++ char *vcpus_str = NULL;
++ int ret = -1;
++
++ vcpus_str = virXMLPropString(node, "vcpus");
++ if (!vcpus_str) {
++ virReportError(VIR_ERR_XML_ERROR, _("Missing %s attribute 'vcpus'"),
++ node->name);
++ goto cleanup;
++ }
++ if (virBitmapParse(vcpus_str, vcpus, VIR_DOMAIN_CPUMASK_LEN) < 0) {
++ virReportError(VIR_ERR_XML_ERROR,
++ _("Invalid %s attribute 'vcpus' value '%s'"),
++ node->name, vcpus_str);
++ goto cleanup;
++ }
++
++ /* We need to limit the bitmap to number of vCPUs. If there's nothing left,
++ * then we can just clean up and return 0 immediately */
++ virBitmapShrink(*vcpus, def->maxvcpus);
++
++ ret = 0;
++ cleanup:
++ VIR_FREE(vcpus_str);
++ return ret;
++}
++
++
+ static int
+ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt,
+ xmlNodePtr node,
+@@ -19145,22 +19177,8 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ if (VIR_ALLOC(tmp_resctrl) < 0)
+ goto cleanup;
+
+- vcpus_str = virXMLPropString(node, "vcpus");
+- if (!vcpus_str) {
+- virReportError(VIR_ERR_XML_ERROR, "%s",
+- _("Missing cachetune attribute 'vcpus'"));
++ if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0)
+ goto cleanup;
+- }
+- if (virBitmapParse(vcpus_str, &vcpus, VIR_DOMAIN_CPUMASK_LEN) < 0) {
+- virReportError(VIR_ERR_XML_ERROR,
+- _("Invalid cachetune attribute 'vcpus' value '%s'"),
+- vcpus_str);
+- goto cleanup;
+- }
+-
+- /* We need to limit the bitmap to number of vCPUs. If there's nothing left,
+- * then we can just clean up and return 0 immediately */
+- virBitmapShrink(vcpus, def->maxvcpus);
+
+ if (virBitmapIsAllClear(vcpus)) {
+ ret = 0;
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Factor-out-virDomainResctrlDef-update-from-virDomainCachetuneDefParse.patch b/SOURCES/libvirt-conf-Factor-out-virDomainResctrlDef-update-from-virDomainCachetuneDefParse.patch
new file mode 100644
index 0000000..c8b844e
--- /dev/null
+++ b/SOURCES/libvirt-conf-Factor-out-virDomainResctrlDef-update-from-virDomainCachetuneDefParse.patch
@@ -0,0 +1,164 @@
+From 7551c4a8b453278e7a27a8e7a722851af1f23efc Mon Sep 17 00:00:00 2001
+Message-Id: <7551c4a8b453278e7a27a8e7a722851af1f23efc@dist-git>
+From: Bing Niu
+Date: Mon, 15 Apr 2019 17:32:57 +0200
+Subject: [PATCH] conf: Factor out virDomainResctrlDef update from
+ virDomainCachetuneDefParse
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Factor out vcpus virDomainResctrlDef update from
+virDomainCachetuneDefParse and introduce virDomainResctrlAppend.
+virDomainResctrlAppend will format vcpus string and append a new
+virDomainResctrlDef to virDomainDefPtr. So that this logic can
+be reusable.
+
+Signed-off-by: Bing Niu
+Reviewed-by: John Ferlan
+(cherry picked from commit 72824f67cdb9c474034539e81fb03fb1bc94495f)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ src/conf/domain_conf.c | 93 +++++++++++++++++++++++++-----------------
+ 1 file changed, 55 insertions(+), 38 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index fb5adbcd10..44bfd75b72 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19176,6 +19176,58 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt,
+ }
+
+
++static int
++virDomainResctrlAppend(virDomainDefPtr def,
++ xmlNodePtr node,
++ virResctrlAllocPtr alloc,
++ virBitmapPtr vcpus,
++ unsigned int flags)
++{
++ char *vcpus_str = NULL;
++ char *alloc_id = NULL;
++ virDomainResctrlDefPtr tmp_resctrl = NULL;
++ int ret = -1;
++
++ if (VIR_ALLOC(tmp_resctrl) < 0)
++ goto cleanup;
++
++ /* We need to format it back because we need to be consistent in the naming
++ * even when users specify some "sub-optimal" string there. */
++ vcpus_str = virBitmapFormat(vcpus);
++ if (!vcpus_str)
++ goto cleanup;
++
++ if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
++ alloc_id = virXMLPropString(node, "id");
++
++ if (!alloc_id) {
++ /* The number of allocations is limited and the directory structure is flat,
++ * not hierarchical, so we need to have all same allocations in one
++ * directory, so it's nice to have it named appropriately. For now it's
++ * 'vcpus_...' but it's designed in order for it to be changeable in the
++ * future (it's part of the status XML). */
++ if (virAsprintf(&alloc_id, "vcpus_%s", vcpus_str) < 0)
++ goto cleanup;
++ }
++
++ if (virResctrlAllocSetID(alloc, alloc_id) < 0)
++ goto cleanup;
++
++ tmp_resctrl->vcpus = vcpus;
++ tmp_resctrl->alloc = alloc;
++
++ if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0)
++ goto cleanup;
++
++ ret = 0;
++ cleanup:
++ virDomainResctrlDefFree(tmp_resctrl);
++ VIR_FREE(alloc_id);
++ VIR_FREE(vcpus_str);
++ return ret;
++}
++
++
+ static int
+ virDomainCachetuneDefParse(virDomainDefPtr def,
+ xmlXPathContextPtr ctxt,
+@@ -19186,19 +19238,12 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ xmlNodePtr *nodes = NULL;
+ virBitmapPtr vcpus = NULL;
+ virResctrlAllocPtr alloc = NULL;
+- virDomainResctrlDefPtr tmp_resctrl = NULL;
+- char *tmp = NULL;
+- char *vcpus_str = NULL;
+- char *alloc_id = NULL;
+ ssize_t i = 0;
+ int n;
+ int ret = -1;
+
+ ctxt->node = node;
+
+- if (VIR_ALLOC(tmp_resctrl) < 0)
+- goto cleanup;
+-
+ if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0)
+ goto cleanup;
+
+@@ -19236,45 +19281,17 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ goto cleanup;
+ }
+
+- /* We need to format it back because we need to be consistent in the naming
+- * even when users specify some "sub-optimal" string there. */
+- VIR_FREE(vcpus_str);
+- vcpus_str = virBitmapFormat(vcpus);
+- if (!vcpus_str)
+- goto cleanup;
+-
+- if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
+- alloc_id = virXMLPropString(node, "id");
+-
+- if (!alloc_id) {
+- /* The number of allocations is limited and the directory structure is flat,
+- * not hierarchical, so we need to have all same allocations in one
+- * directory, so it's nice to have it named appropriately. For now it's
+- * 'vcpus_...' but it's designed in order for it to be changeable in the
+- * future (it's part of the status XML). */
+- if (virAsprintf(&alloc_id, "vcpus_%s", vcpus_str) < 0)
+- goto cleanup;
+- }
+-
+- if (virResctrlAllocSetID(alloc, alloc_id) < 0)
+- goto cleanup;
+-
+- VIR_STEAL_PTR(tmp_resctrl->vcpus, vcpus);
+- VIR_STEAL_PTR(tmp_resctrl->alloc, alloc);
+-
+- if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0)
++ if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
+ goto cleanup;
++ vcpus = NULL;
++ alloc = NULL;
+
+ ret = 0;
+ cleanup:
+ ctxt->node = oldnode;
+- virDomainResctrlDefFree(tmp_resctrl);
+ virObjectUnref(alloc);
+ virBitmapFree(vcpus);
+- VIR_FREE(alloc_id);
+- VIR_FREE(vcpus_str);
+ VIR_FREE(nodes);
+- VIR_FREE(tmp);
+ return ret;
+ }
+
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Fix-bug-in-finding-alloc-through-matching-vcpus.patch b/SOURCES/libvirt-conf-Fix-bug-in-finding-alloc-through-matching-vcpus.patch
new file mode 100644
index 0000000..2d9f402
--- /dev/null
+++ b/SOURCES/libvirt-conf-Fix-bug-in-finding-alloc-through-matching-vcpus.patch
@@ -0,0 +1,52 @@
+From 408d9e217f05b6c68351804df56aa9c9af7db4e7 Mon Sep 17 00:00:00 2001
+Message-Id: <408d9e217f05b6c68351804df56aa9c9af7db4e7@dist-git>
+From: Wang Huaqiang
+Date: Mon, 15 Apr 2019 17:33:01 +0200
+Subject: [PATCH] conf: Fix bug in finding alloc through matching vcpus
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The @alloc object returned by virDomainResctrlVcpuMatch is not
+properly referenced and un-referenced in virDomainCachetuneDefParse.
+
+This patch fixes this problem.
+
+Signed-off-by: Wang Huaqiang
+Reviewed-by: John Ferlan
+(cherry picked from commit 3a1cdb06fd9bc5e35230f6198e697d6ec03d1206)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id: <7049386040dc0d170193b5fbfc81f2a8335d0063.1555342313.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ src/conf/domain_conf.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 74781fe596..6af14cc06f 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19089,7 +19089,7 @@ virDomainResctrlVcpuMatch(virDomainDefPtr def,
+ * Just updating memory allocation information of that group
+ */
+ if (virBitmapEqual(def->resctrls[i]->vcpus, vcpus)) {
+- *alloc = def->resctrls[i]->alloc;
++ *alloc = virObjectRef(def->resctrls[i]->alloc);
+ break;
+ }
+ if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) {
+@@ -19386,8 +19386,6 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
+ if (!alloc)
+ goto cleanup;
+ new_alloc = true;
+- } else {
+- alloc = virObjectRef(alloc);
+ }
+
+ for (i = 0; i < n; i++) {
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch b/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch
new file mode 100644
index 0000000..8b03303
--- /dev/null
+++ b/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch
@@ -0,0 +1,112 @@
+From dc638f4d9fea8647a190dc9d2dabc4ce81ab2a3c Mon Sep 17 00:00:00 2001
+Message-Id:
+From: Andrea Bolognani
+Date: Wed, 3 Apr 2019 17:08:57 +0200
+Subject: [PATCH] conf: Fix check for chardev source path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Attempting to use a chardev definition like
+
+
+
+
+
+correctly results in an error being reported, since the source
+path - a required piece of information - is missing; however,
+the very similar
+
+
+
+
+
+was happily accepted by libvirt, only to result in libvirtd
+crashing as soon as the guest was started.
+
+The issue was caused by checking the chardev's targetType
+against whitelisted values from virDomainChrChannelTargetType
+without first checking the chardev's deviceType to make sure
+it is actually a channel, for which the check makes sense,
+rather than a different type of chardev.
+
+The only reason this wasn't spotted earlier is that the
+whitelisted values just so happen to correspond to USB and
+PCI serial devices and Xen and UML consoles respectively,
+all of which are fairly uncommon.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1609720
+
+Signed-off-by: Andrea Bolognani
+Reviewed-by: Ján Tomko
+
+(cherry picked from commit 614193fac67445a7e92bf620ffef726ed1bd6f07)
+Signed-off-by: Andrea Bolognani
+Message-Id: <20190403150857.20850-1-abologna@redhat.com>
+Reviewed-by: Erik Skultety
+---
+ src/conf/domain_conf.c | 11 +++++++----
+ .../serial-unix-missing-source.xml | 15 +++++++++++++++
+ tests/qemuxml2argvtest.c | 1 +
+ 3 files changed, 23 insertions(+), 4 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/serial-unix-missing-source.xml
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index eb4e9ac523..712efbb9f9 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -5531,11 +5531,14 @@ virDomainChrSourceDefValidate(const virDomainChrSourceDef *def,
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+- /* path can be auto generated */
++ /* The source path can be auto generated for certain specific
++ * types of channels, but in most cases we should report an
++ * error if the user didn't provide it */
+ if (!def->data.nix.path &&
+- (!chr_def ||
+- (chr_def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN &&
+- chr_def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO))) {
++ !(chr_def &&
++ chr_def->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
++ (chr_def->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN ||
++ chr_def->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Missing source path attribute for char device"));
+ return -1;
+diff --git a/tests/qemuxml2argvdata/serial-unix-missing-source.xml b/tests/qemuxml2argvdata/serial-unix-missing-source.xml
+new file mode 100644
+index 0000000000..1e1221f12d
+--- /dev/null
++++ b/tests/qemuxml2argvdata/serial-unix-missing-source.xml
+@@ -0,0 +1,15 @@
++
++ guest
++ c7a5fdbd-edaf-9455-926a-d65c16db1809
++ 1048576
++ 1
++
++ hvm
++
++
++ /usr/bin/qemu-system-aarch64
++
++
++
++
++
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index d97dc0ea8d..7a731e2f40 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1363,6 +1363,7 @@ mymain(void)
+ DO_TEST("serial-unix-chardev",
+ QEMU_CAPS_DEVICE_ISA_SERIAL);
+ DO_TEST_CAPS_LATEST("serial-unix-chardev");
++ DO_TEST_PARSE_ERROR("serial-unix-missing-source", NONE);
+ DO_TEST("serial-tcp-chardev",
+ QEMU_CAPS_DEVICE_ISA_SERIAL);
+ DO_TEST("serial-udp-chardev",
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Introduce-virDomainGraphics-related-helpers.patch b/SOURCES/libvirt-conf-Introduce-virDomainGraphics-related-helpers.patch
new file mode 100644
index 0000000..06ce7a0
--- /dev/null
+++ b/SOURCES/libvirt-conf-Introduce-virDomainGraphics-related-helpers.patch
@@ -0,0 +1,121 @@
+From 7b4b21814c4a1af212b061e265ee0ca8220abd1e Mon Sep 17 00:00:00 2001
+Message-Id: <7b4b21814c4a1af212b061e265ee0ca8220abd1e@dist-git>
+From: Erik Skultety
+Date: Tue, 9 Apr 2019 08:34:26 +0200
+Subject: [PATCH] conf: Introduce virDomainGraphics-related helpers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A few simple helpers that allow us to determine whether a graphics can
+and will need to make use of a DRM render node.
+
+Signed-off-by: Erik Skultety
+Reviewed-by: Ján Tomko
+(cherry picked from commit 255e073263b55b524f68b64c282e73509f93985e)
+
+https: //bugzilla.redhat.com/show_bug.cgi?id=1628892
+Signed-off-by: Erik Skultety
+Message-Id: <24845c3d51a90b5de6989e70e9de51b07b44ade9.1554791287.git.eskultet@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ src/conf/domain_conf.c | 43 ++++++++++++++++++++++++++++++++++++++++
+ src/conf/domain_conf.h | 9 +++++++++
+ src/libvirt_private.syms | 3 +++
+ 3 files changed, 55 insertions(+)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 6af14cc06f..d079be2bb5 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -30713,3 +30713,46 @@ virDomainGraphicsDefHasOpenGL(const virDomainDef *def)
+
+ return false;
+ }
++
++
++bool
++virDomainGraphicsSupportsRenderNode(const virDomainGraphicsDef *graphics)
++{
++ return graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE;
++}
++
++
++const char *
++virDomainGraphicsGetRenderNode(const virDomainGraphicsDef *graphics)
++{
++ const char *ret = NULL;
++
++ switch (graphics->type) {
++ case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
++ if (graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES)
++ ret = graphics->data.spice.rendernode;
++ break;
++ case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
++ case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
++ case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
++ case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
++ case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
++ case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
++ break;
++ }
++
++ return ret;
++}
++
++
++bool
++virDomainGraphicsNeedsAutoRenderNode(const virDomainGraphicsDef *graphics)
++{
++ if (!virDomainGraphicsSupportsRenderNode(graphics))
++ return false;
++
++ if (virDomainGraphicsGetRenderNode(graphics))
++ return false;
++
++ return true;
++}
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 65abe9cde6..b1139812d5 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -3651,4 +3651,13 @@ virDomainDefHasManagedPR(const virDomainDef *def);
+ bool
+ virDomainGraphicsDefHasOpenGL(const virDomainDef *def);
+
++bool
++virDomainGraphicsSupportsRenderNode(const virDomainGraphicsDef *graphics);
++
++const char *
++virDomainGraphicsGetRenderNode(const virDomainGraphicsDef *graphics);
++
++bool
++virDomainGraphicsNeedsAutoRenderNode(const virDomainGraphicsDef *graphics);
++
+ #endif /* __DOMAIN_CONF_H */
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 6655dfdecc..984a9be18f 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -370,8 +370,10 @@ virDomainGraphicsAuthConnectedTypeToString;
+ virDomainGraphicsDefFree;
+ virDomainGraphicsDefHasOpenGL;
+ virDomainGraphicsGetListen;
++virDomainGraphicsGetRenderNode;
+ virDomainGraphicsListenAppendAddress;
+ virDomainGraphicsListenAppendSocket;
++virDomainGraphicsNeedsAutoRenderNode;
+ virDomainGraphicsSpiceChannelModeTypeFromString;
+ virDomainGraphicsSpiceChannelModeTypeToString;
+ virDomainGraphicsSpiceChannelNameTypeFromString;
+@@ -386,6 +388,7 @@ virDomainGraphicsSpiceStreamingModeTypeFromString;
+ virDomainGraphicsSpiceStreamingModeTypeToString;
+ virDomainGraphicsSpiceZlibCompressionTypeFromString;
+ virDomainGraphicsSpiceZlibCompressionTypeToString;
++virDomainGraphicsSupportsRenderNode;
+ virDomainGraphicsTypeFromString;
+ virDomainGraphicsTypeToString;
+ virDomainGraphicsVNCSharePolicyTypeFromString;
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Rename-cachetune-to-resctrl.patch b/SOURCES/libvirt-conf-Rename-cachetune-to-resctrl.patch
new file mode 100644
index 0000000..f9ba031
--- /dev/null
+++ b/SOURCES/libvirt-conf-Rename-cachetune-to-resctrl.patch
@@ -0,0 +1,267 @@
+From 8e87a5625a571d05177c6766405db814b6e8e7b3 Mon Sep 17 00:00:00 2001
+Message-Id: <8e87a5625a571d05177c6766405db814b6e8e7b3@dist-git>
+From: Bing Niu
+Date: Mon, 15 Apr 2019 17:32:54 +0200
+Subject: [PATCH] conf: Rename cachetune to resctrl
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Resctrl not only supports cache tuning, but also memory bandwidth
+tuning. Renaming cachetune to resctrl to reflect that. With resctrl,
+all allocation for different resources (cache, memory bandwidth) are
+aggregated and represented by a virResctrlAllocPtr inside
+virDomainResctrlDef.
+
+Signed-off-by: Bing Niu
+Reviewed-by: John Ferlan
+(cherry picked from commit acc288d655237a22a95c5a1ae7207916fb9efac9)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
+
+Signed-off-by: Pavel Hrdina
+Message-Id: <9ee9c0993a62ddf084968b211ca82c9e6b62ef0d.1555342313.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ src/conf/domain_conf.c | 44 ++++++++++++++++++++---------------------
+ src/conf/domain_conf.h | 10 +++++-----
+ src/qemu/qemu_domain.c | 2 +-
+ src/qemu/qemu_process.c | 18 ++++++++---------
+ 4 files changed, 37 insertions(+), 37 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index e04edd97dc..0c8afe78c6 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -2966,14 +2966,14 @@ virDomainLoaderDefFree(virDomainLoaderDefPtr loader)
+
+
+ static void
+-virDomainCachetuneDefFree(virDomainCachetuneDefPtr cachetune)
++virDomainResctrlDefFree(virDomainResctrlDefPtr resctrl)
+ {
+- if (!cachetune)
++ if (!resctrl)
+ return;
+
+- virObjectUnref(cachetune->alloc);
+- virBitmapFree(cachetune->vcpus);
+- VIR_FREE(cachetune);
++ virObjectUnref(resctrl->alloc);
++ virBitmapFree(resctrl->vcpus);
++ VIR_FREE(resctrl);
+ }
+
+
+@@ -3163,9 +3163,9 @@ void virDomainDefFree(virDomainDefPtr def)
+ virDomainShmemDefFree(def->shmems[i]);
+ VIR_FREE(def->shmems);
+
+- for (i = 0; i < def->ncachetunes; i++)
+- virDomainCachetuneDefFree(def->cachetunes[i]);
+- VIR_FREE(def->cachetunes);
++ for (i = 0; i < def->nresctrls; i++)
++ virDomainResctrlDefFree(def->resctrls[i]);
++ VIR_FREE(def->resctrls);
+
+ VIR_FREE(def->keywrap);
+
+@@ -19129,7 +19129,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ xmlNodePtr *nodes = NULL;
+ virBitmapPtr vcpus = NULL;
+ virResctrlAllocPtr alloc = virResctrlAllocNew();
+- virDomainCachetuneDefPtr tmp_cachetune = NULL;
++ virDomainResctrlDefPtr tmp_resctrl = NULL;
+ char *tmp = NULL;
+ char *vcpus_str = NULL;
+ char *alloc_id = NULL;
+@@ -19142,7 +19142,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ if (!alloc)
+ goto cleanup;
+
+- if (VIR_ALLOC(tmp_cachetune) < 0)
++ if (VIR_ALLOC(tmp_resctrl) < 0)
+ goto cleanup;
+
+ vcpus_str = virXMLPropString(node, "vcpus");
+@@ -19183,8 +19183,8 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ goto cleanup;
+ }
+
+- for (i = 0; i < def->ncachetunes; i++) {
+- if (virBitmapOverlaps(def->cachetunes[i]->vcpus, vcpus)) {
++ for (i = 0; i < def->nresctrls; i++) {
++ if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Overlapping vcpus in cachetunes"));
+ goto cleanup;
+@@ -19214,16 +19214,16 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
+ if (virResctrlAllocSetID(alloc, alloc_id) < 0)
+ goto cleanup;
+
+- VIR_STEAL_PTR(tmp_cachetune->vcpus, vcpus);
+- VIR_STEAL_PTR(tmp_cachetune->alloc, alloc);
++ VIR_STEAL_PTR(tmp_resctrl->vcpus, vcpus);
++ VIR_STEAL_PTR(tmp_resctrl->alloc, alloc);
+
+- if (VIR_APPEND_ELEMENT(def->cachetunes, def->ncachetunes, tmp_cachetune) < 0)
++ if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ ctxt->node = oldnode;
+- virDomainCachetuneDefFree(tmp_cachetune);
++ virDomainResctrlDefFree(tmp_resctrl);
+ virObjectUnref(alloc);
+ virBitmapFree(vcpus);
+ VIR_FREE(alloc_id);
+@@ -27053,7 +27053,7 @@ virDomainCachetuneDefFormatHelper(unsigned int level,
+
+ static int
+ virDomainCachetuneDefFormat(virBufferPtr buf,
+- virDomainCachetuneDefPtr cachetune,
++ virDomainResctrlDefPtr resctrl,
+ unsigned int flags)
+ {
+ virBuffer childrenBuf = VIR_BUFFER_INITIALIZER;
+@@ -27061,7 +27061,7 @@ virDomainCachetuneDefFormat(virBufferPtr buf,
+ int ret = -1;
+
+ virBufferSetChildIndent(&childrenBuf, buf);
+- virResctrlAllocForeachCache(cachetune->alloc,
++ virResctrlAllocForeachCache(resctrl->alloc,
+ virDomainCachetuneDefFormatHelper,
+ &childrenBuf);
+
+@@ -27074,14 +27074,14 @@ virDomainCachetuneDefFormat(virBufferPtr buf,
+ goto cleanup;
+ }
+
+- vcpus = virBitmapFormat(cachetune->vcpus);
++ vcpus = virBitmapFormat(resctrl->vcpus);
+ if (!vcpus)
+ goto cleanup;
+
+ virBufferAsprintf(buf, "alloc);
++ const char *alloc_id = virResctrlAllocGetID(resctrl->alloc);
+ if (!alloc_id)
+ goto cleanup;
+
+@@ -27202,8 +27202,8 @@ virDomainCputuneDefFormat(virBufferPtr buf,
+ def->iothreadids[i]->iothread_id);
+ }
+
+- for (i = 0; i < def->ncachetunes; i++)
+- virDomainCachetuneDefFormat(&childrenBuf, def->cachetunes[i], flags);
++ for (i = 0; i < def->nresctrls; i++)
++ virDomainCachetuneDefFormat(&childrenBuf, def->resctrls[i], flags);
+
+ if (virBufferCheckError(&childrenBuf) < 0)
+ return -1;
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 390bd81aa0..65abe9cde6 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -2232,10 +2232,10 @@ struct _virDomainCputune {
+ };
+
+
+-typedef struct _virDomainCachetuneDef virDomainCachetuneDef;
+-typedef virDomainCachetuneDef *virDomainCachetuneDefPtr;
++typedef struct _virDomainResctrlDef virDomainResctrlDef;
++typedef virDomainResctrlDef *virDomainResctrlDefPtr;
+
+-struct _virDomainCachetuneDef {
++struct _virDomainResctrlDef {
+ virBitmapPtr vcpus;
+ virResctrlAllocPtr alloc;
+ };
+@@ -2413,8 +2413,8 @@ struct _virDomainDef {
+
+ virDomainCputune cputune;
+
+- virDomainCachetuneDefPtr *cachetunes;
+- size_t ncachetunes;
++ virDomainResctrlDefPtr *resctrls;
++ size_t nresctrls;
+
+ virDomainNumaPtr numa;
+ virDomainResourceDefPtr resource;
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index d80f9b393e..112958f64a 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -3999,7 +3999,7 @@ qemuDomainDefValidate(const virDomainDef *def,
+ }
+ }
+
+- if (def->ncachetunes &&
++ if (def->nresctrls &&
+ def->virtType != VIR_DOMAIN_VIRT_KVM) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("cachetune is only supported for KVM domains"));
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 208c64381c..a44f371346 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -2584,7 +2584,7 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver,
+ virCapsPtr caps = NULL;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+- if (!vm->def->ncachetunes)
++ if (!vm->def->nresctrls)
+ return 0;
+
+ /* Force capability refresh since resctrl info can change
+@@ -2593,9 +2593,9 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver,
+ if (!caps)
+ return -1;
+
+- for (i = 0; i < vm->def->ncachetunes; i++) {
++ for (i = 0; i < vm->def->nresctrls; i++) {
+ if (virResctrlAllocCreate(caps->host.resctrl,
+- vm->def->cachetunes[i]->alloc,
++ vm->def->resctrls[i]->alloc,
+ priv->machineName) < 0)
+ goto cleanup;
+ }
+@@ -5411,8 +5411,8 @@ qemuProcessSetupVcpu(virDomainObjPtr vm,
+ &vcpu->sched) < 0)
+ return -1;
+
+- for (i = 0; i < vm->def->ncachetunes; i++) {
+- virDomainCachetuneDefPtr ct = vm->def->cachetunes[i];
++ for (i = 0; i < vm->def->nresctrls; i++) {
++ virDomainResctrlDefPtr ct = vm->def->resctrls[i];
+
+ if (virBitmapIsBitSet(ct->vcpus, vcpuid)) {
+ if (virResctrlAllocAddPID(ct->alloc, vcpupid) < 0)
+@@ -7108,8 +7108,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
+ /* Remove resctrl allocation after cgroups are cleaned up which makes it
+ * kind of safer (although removing the allocation should work even with
+ * pids in tasks file */
+- for (i = 0; i < vm->def->ncachetunes; i++)
+- virResctrlAllocRemove(vm->def->cachetunes[i]->alloc);
++ for (i = 0; i < vm->def->nresctrls; i++)
++ virResctrlAllocRemove(vm->def->resctrls[i]->alloc);
+
+ qemuProcessRemoveDomainStatus(driver, vm);
+
+@@ -7835,8 +7835,8 @@ qemuProcessReconnect(void *opaque)
+ if (qemuConnectAgent(driver, obj) < 0)
+ goto error;
+
+- for (i = 0; i < obj->def->ncachetunes; i++) {
+- if (virResctrlAllocDeterminePath(obj->def->cachetunes[i]->alloc,
++ for (i = 0; i < obj->def->nresctrls; i++) {
++ if (virResctrlAllocDeterminePath(obj->def->resctrls[i]->alloc,
+ priv->machineName) < 0)
+ goto error;
+ }
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-Report-TSC-frequency-in-host-CPU-capabilities.patch b/SOURCES/libvirt-conf-Report-TSC-frequency-in-host-CPU-capabilities.patch
new file mode 100644
index 0000000..722ff32
--- /dev/null
+++ b/SOURCES/libvirt-conf-Report-TSC-frequency-in-host-CPU-capabilities.patch
@@ -0,0 +1,149 @@
+From 5b07ca7c378a5e62fec0ed4808e8905fe447e85e Mon Sep 17 00:00:00 2001
+Message-Id: <5b07ca7c378a5e62fec0ed4808e8905fe447e85e@dist-git>
+From: Jiri Denemark
+Date: Tue, 4 Jun 2019 13:04:30 +0200
+Subject: [PATCH] conf: Report TSC frequency in host CPU capabilities
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds a new
+
+
+
+element into the host CPU capabilities XML.
+
+Signed-off-by: Jiri Denemark
+(cherry picked from commit c277b9ad5c740bb4c4b915754ae74621f93f9d37)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1641702
+
+Conflicts:
+ src/conf/cpu_conf.h
+ - virenum.h doesn't exist downstream
+
+Signed-off-by: Jiri Denemark
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ src/conf/cpu_conf.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
+ src/conf/cpu_conf.h | 2 ++
+ 2 files changed, 50 insertions(+)
+
+diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
+index 43a3ab5dcd..d0ad265fbe 100644
+--- a/src/conf/cpu_conf.c
++++ b/src/conf/cpu_conf.c
+@@ -102,6 +102,7 @@ virCPUDefFree(virCPUDefPtr def)
+
+ virCPUDefFreeModel(def);
+ VIR_FREE(def->cache);
++ VIR_FREE(def->tsc);
+ VIR_FREE(def);
+ }
+
+@@ -223,6 +224,13 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
+ *copy->cache = *cpu->cache;
+ }
+
++ if (cpu->tsc) {
++ if (VIR_ALLOC(copy->tsc) < 0)
++ goto error;
++
++ *copy->tsc = *cpu->tsc;
++ }
++
+ return copy;
+
+ error:
+@@ -276,6 +284,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
+ char *cpuMode;
+ char *fallback = NULL;
+ char *vendor_id = NULL;
++ char *tscScaling = NULL;
++ virHostCPUTscInfoPtr tsc = NULL;
+ int ret = -1;
+
+ *cpu = NULL;
+@@ -392,6 +402,32 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
+ _("invalid microcode version"));
+ goto cleanup;
+ }
++
++ if (virXPathBoolean("boolean(./counter[@name='tsc'])", ctxt) > 0) {
++ if (VIR_ALLOC(tsc) < 0)
++ goto cleanup;
++
++ if (virXPathULongLong("./counter[@name='tsc']/@frequency", ctxt,
++ &tsc->frequency) < 0) {
++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++ _("Invalid TSC frequency"));
++ goto cleanup;
++ }
++
++ tscScaling = virXPathString("string(./counter[@name='tsc']/@scaling)",
++ ctxt);
++ if (tscScaling) {
++ int scaling = virTristateBoolTypeFromString(tscScaling);
++ if (scaling < 0) {
++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++ _("Invalid TSC scaling attribute"));
++ goto cleanup;
++ }
++ tsc->scaling = scaling;
++ }
++
++ VIR_STEAL_PTR(def->tsc, tsc);
++ }
+ }
+
+ if (!(def->model = virXPathString("string(./model[1])", ctxt)) &&
+@@ -577,6 +613,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
+ VIR_FREE(fallback);
+ VIR_FREE(vendor_id);
+ VIR_FREE(nodes);
++ VIR_FREE(tscScaling);
++ VIR_FREE(tsc);
+ virCPUDefFree(def);
+ return ret;
+ }
+@@ -734,6 +772,16 @@ virCPUDefFormatBuf(virBufferPtr buf,
+ virBufferAsprintf(buf, "\n",
+ def->microcodeVersion);
+
++ if (def->type == VIR_CPU_TYPE_HOST && def->tsc) {
++ virBufferAddLit(buf, "tsc->frequency);
++ if (def->tsc->scaling) {
++ virBufferAsprintf(buf, " scaling='%s'",
++ virTristateBoolTypeToString(def->tsc->scaling));
++ }
++ virBufferAddLit(buf, "/>\n");
++ }
++
+ if (def->sockets && def->cores && def->threads) {
+ virBufferAddLit(buf, "sockets);
+diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
+index 9f2e7ee264..5bda4d6961 100644
+--- a/src/conf/cpu_conf.h
++++ b/src/conf/cpu_conf.h
+@@ -30,6 +30,7 @@
+ # include "virbitmap.h"
+ # include "virarch.h"
+ # include "numa_conf.h"
++# include "virhostcpu.h"
+
+ # define VIR_CPU_VENDOR_ID_LENGTH 12
+
+@@ -141,6 +142,7 @@ struct _virCPUDef {
+ size_t nfeatures_max;
+ virCPUFeatureDefPtr features;
+ virCPUCacheDefPtr cache;
++ virHostCPUTscInfoPtr tsc;
+ };
+
+
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-gfx-Add-egl-headless-as-a-member-to-virDomainGraphicsDef-struct.patch b/SOURCES/libvirt-conf-gfx-Add-egl-headless-as-a-member-to-virDomainGraphicsDef-struct.patch
new file mode 100644
index 0000000..bc32606
--- /dev/null
+++ b/SOURCES/libvirt-conf-gfx-Add-egl-headless-as-a-member-to-virDomainGraphicsDef-struct.patch
@@ -0,0 +1,43 @@
+From 3af732efb21503e81d31ff600d024b240d6105f3 Mon Sep 17 00:00:00 2001
+Message-Id: <3af732efb21503e81d31ff600d024b240d6105f3@dist-git>
+From: Erik Skultety
+Date: Tue, 9 Apr 2019 08:34:30 +0200
+Subject: [PATCH] conf: gfx: Add egl-headless as a member to
+ virDomainGraphicsDef struct
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since we need to specify the rendernode option onto QEMU cmdline, we
+need this union member to retain consistency in how we build the
+cmdline.
+
+Signed-off-by: Erik Skultety
+Reviewed-by: Ján Tomko
+(cherry picked from commit 0a75de221984b971cb841c6918e6746eb22b1547)
+
+https: //bugzilla.redhat.com/show_bug.cgi?id=1628892
+Signed-off-by: Erik Skultety
+Message-Id: <5dc5762e104b6a4729bf6fa9a470f10a6e6c256f.1554791287.git.eskultet@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ src/conf/domain_conf.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index b1139812d5..2d272f907f 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -1656,6 +1656,9 @@ struct _virDomainGraphicsDef {
+ virTristateBool gl;
+ char *rendernode;
+ } spice;
++ struct {
++ char *rendernode;
++ } egl_headless;
+ } data;
+ /* nListens, listens, and *port are only useful if type is vnc,
+ * rdp, or spice. They've been extracted from the union only to
+--
+2.21.0
+
diff --git a/SOURCES/libvirt-conf-gfx-egl-headless-Introduce-a-new-gl-subelement.patch b/SOURCES/libvirt-conf-gfx-egl-headless-Introduce-a-new-gl-subelement.patch
new file mode 100644
index 0000000..db82645
--- /dev/null
+++ b/SOURCES/libvirt-conf-gfx-egl-headless-Introduce-a-new-gl-subelement.patch
@@ -0,0 +1,307 @@
+From a701d9ee0f3e5cd939356191f25d0ec378dbb5c4 Mon Sep 17 00:00:00 2001
+Message-Id:
+From: Erik Skultety
+Date: Tue, 9 Apr 2019 08:34:31 +0200
+Subject: [PATCH] conf: gfx: egl-headless: Introduce a new subelement
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Unlike with SPICE and SDL which use the subelement to enable OpenGL
+acceleration, specifying egl-headless graphics in the XML has
+essentially the same meaning, thus in case of egl-headless we don't have
+a need for the 'enable' element attribute and we'll only be interested
+in the 'rendernode' one further down the road.
+
+Signed-off-by: Erik Skultety
+Reviewed-by: Ján Tomko
+(cherry picked from commit 5f931fe39112129efb1204a1aac60b180ef31b42)
+
+https: //bugzilla.redhat.com/show_bug.cgi?id=1628892
+Signed-off-by: Erik Skultety
+Message-Id:
+Reviewed-by: Jiri Denemark
+---
+ docs/formatdomain.html.in | 11 +++--
+ docs/schemas/domaincommon.rng | 17 +++++--
+ src/conf/domain_conf.c | 45 ++++++++++++++++++-
+ src/qemu/qemu_process.c | 17 +++++--
+ .../graphics-egl-headless-rendernode.xml | 33 ++++++++++++++
+ .../graphics-egl-headless-rendernode.xml | 41 +++++++++++++++++
+ tests/qemuxml2xmltest.c | 2 +
+ 7 files changed, 156 insertions(+), 10 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless-rendernode.xml
+ create mode 100644 tests/qemuxml2xmloutdata/graphics-egl-headless-rendernode.xml
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 8cf2c12524..e848dc1e0d 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -6573,12 +6573,17 @@ qemu-kvm -net nic,model=? /dev/null
+ the other types, for practical reasons it should be paired with
+ either vnc or spice graphics types.
+ This display type is only supported by QEMU domains
+- (needs QEMU 2.10 or newer) and doesn't
+- accept any attributes.
++ (needs QEMU 2.10 or newer).
++ 5.0.0 this element accepts a
++ <gl/> sub-element with an optional attribute
++ rendernode which can be used to specify an absolute
++ path to a host's DRI device to be used for OpenGL rendering.
+