[libvirt] [PATCH perl v2] Add constants for new perf event support

2017-02-23 Thread Nitesh Konkar
Signed-off-by: Nitesh Konkar 
---
 Changes|  9 +
 Virt.xs|  9 +
 lib/Sys/Virt/Domain.pm | 54 ++
 3 files changed, 72 insertions(+)

diff --git a/Changes b/Changes
index 842f21f..7d637f5 100644
--- a/Changes
+++ b/Changes
@@ -5,6 +5,15 @@ Revision history for perl module Sys::Virt
  - Add VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE constant
  - Add VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM constant
  - Add virDomainSetVcpu API
+ - Add PERF_PARAM_CPU_CLOCK constant
+ - Add PERF_PARAM_TASK_CLOCK constant
+ - Add PERF_PARAM_PAGE_FAULTS constant
+ - Add PERF_PARAM_CONTEXT_SWITCHES constant
+ - Add PERF_PARAM_CPU_MIGRATIONS constant
+ - Add PERF_PARAM_PAGE_FAULTS_MIN constant
+ - Add PERF_PARAM_PAGE_FAULTS_MAJ constant
+ - Add PERF_PARAM_ALIGNMENT_FAULTS constant
+ - Add PERF_PARAM_EMULATION_FAULTS constant
 
 3.0.0 2017-01-19
 
diff --git a/Virt.xs b/Virt.xs
index 9728fb0..e80182f 100644
--- a/Virt.xs
+++ b/Virt.xs
@@ -8500,6 +8500,15 @@ BOOT:
   REGISTER_CONSTANT_STR(VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND, 
PERF_PARAM_STALLED_CYCLES_FRONTEND);
   REGISTER_CONSTANT_STR(VIR_PERF_PARAM_STALLED_CYCLES_BACKEND, 
PERF_PARAM_STALLED_CYCLES_BACKEND);
   REGISTER_CONSTANT_STR(VIR_PERF_PARAM_REF_CPU_CYCLES, 
PERF_PARAM_REF_CPU_CYCLES);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_CPU_CLOCK, PERF_PARAM_CPU_CLOCK);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_TASK_CLOCK, PERF_PARAM_TASK_CLOCK);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_PAGE_FAULTS, 
PERF_PARAM_PAGE_FAULTS);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_CONTEXT_SWITCHES, 
PERF_PARAM_CONTEXT_SWITCHES);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_CPU_MIGRATIONS, 
PERF_PARAM_CPU_MIGRATIONS);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_PAGE_FAULTS_MIN, 
PERF_PARAM_PAGE_FAULTS_MIN);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_PAGE_FAULTS_MAJ, 
PERF_PARAM_PAGE_FAULTS_MAJ);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_ALIGNMENT_FAULTS, 
PERF_PARAM_ALIGNMENT_FAULTS);
+  REGISTER_CONSTANT_STR(VIR_PERF_PARAM_EMULATION_FAULTS, 
PERF_PARAM_EMULATION_FAULTS);
 
   REGISTER_CONSTANT_STR(VIR_DOMAIN_BANDWIDTH_IN_AVERAGE, 
BANDWIDTH_IN_AVERAGE);
   REGISTER_CONSTANT_STR(VIR_DOMAIN_BANDWIDTH_IN_PEAK, BANDWIDTH_IN_PEAK);
diff --git a/lib/Sys/Virt/Domain.pm b/lib/Sys/Virt/Domain.pm
index 6b36e73..eea8b26 100644
--- a/lib/Sys/Virt/Domain.pm
+++ b/lib/Sys/Virt/Domain.pm
@@ -2814,6 +2814,60 @@ frequency scaling by applications running on the 
platform.
 It corresponds to the "perf.ref_cpu_cycles" field in the
 *Stats APIs.
 
+=item Sys::Virt::Domain::PERF_PARAM_CPU_CLOCK
+The cpu_clock perf event counter which can be used to
+measure the count of cpu clock time by applications
+running on the platform. It corresponds to the
+"perf.cpu_clock" field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_TASK_CLOCK
+The task_clock perf event counter which can be used to
+measure the count of task clock time by applications
+running on the platform. It corresponds to the
+"perf.task_clock" field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_PAGE_FAULTS
+The page_faults perf event counter which can be used to
+measure the count of page faults by applications running
+on the platform. It corresponds to the "perf.page_faults"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_CONTEXT_SWITCHES
+The context_switches perf event counter which can be used to
+measure the count of context switches by applications running
+on the platform. It corresponds to the "perf.context_switches"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_CPU_MIGRATIONS
+The cpu_migrations perf event counter which can be used to
+measure the count of cpu migrations by applications running
+on the platform. It corresponds to the "perf.cpu_migrations"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_PAGE_FAULTS_MIN
+The page_faults_min perf event counter which can be used to
+measure the count of minor page faults by applications running
+on the platform. It corresponds to the "perf.page_faults_min"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_PAGE_FAULTS_MAJ
+The page_faults_maj perf event counter which can be used to
+measure the count of major page faults by applications running
+on the platform. It corresponds to the "perf.page_faults_maj"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_ALIGNMENT_FAULTS
+The alignment_faults perf event counter which can be used to
+measure the count of alignment faults by applications running
+on the platform. It corresponds to the "perf.alignment_faults"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_EMULATION_FAULTS
+The emulation_faults perf event counter which can be used to
+measure the count of emulation faults by applications running
+on the platform. It corresponds to the "perf.emulation_faults"
+field in the *Stats APIs.
+
 =back
 
 =head2 VC

Re: [libvirt] [Qemu-ppc] Proposal PCI/PCIe device placement on PAPR guests

2017-02-23 Thread David Gibson
On Thu, Feb 23, 2017 at 08:23:50AM +0100, Greg Kurz wrote:
> On Thu, 23 Feb 2017 13:11:52 +1100
> David Gibson  wrote:
> 
> > On Wed, Feb 22, 2017 at 12:08:25PM +0100, Greg Kurz wrote:
> > > David,
> > > 
> > > I don't see the "spapr_pci: Allow PCI-Express devices" patch in your
> > > ppc-for-2.9 tree. Do you still consider merging it ?  
> > 
> > No.  After discussions with Marcel Apfelbaum and others I'm looking at
> > a different approach for PCIe support.
> > 
> 
> Oh, I had missed that... Is it the following thread ?
> 
> https://lists.gnu.org/archive/html/qemu-ppc/2017-02/msg00203.html

That's the one.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [RFC PATCH 05/12] qemu: domain: Add helper to lookup disk by node name

2017-02-23 Thread Eric Blake
On 02/23/2017 01:21 PM, Peter Krempa wrote:
> Looks up a disk and it's corresponding backing chain element by node
> name.
> ---
>  src/qemu/qemu_domain.c | 44 
>  src/qemu/qemu_domain.h |  6 ++
>  2 files changed, 50 insertions(+)
> 

> +virDomainDiskDefPtr
> +qemuDomainDiskLookupByNodename(virDomainDefPtr def,
> +   const char *nodename,
> +   virStorageSourcePtr *src,
> +   unsigned int *idx)
> +{
> +size_t i;
> +unsigned int srcindex;
> +virStorageSourcePtr tmp = NULL;

Sometimes, I find it easier to do:

if (!idx)
idx = &srcindex;

so that later on...

> +
> +if (src)
> +*src = NULL;
> +
> +if (idx)
> +*idx = 0;
> +
> +for (i = 0; i < def->ndisks; i++) {
> +if ((tmp = virStorageSourceFindByNodeName(def->disks[i]->src,
> +  nodename, &srcindex))) {

...I can just pass 'idx' instead of '&srcindex' here...

> +if (src)
> +*src = tmp;
> +
> +if (idx)
> +*idx = srcindex;

...and completely skip this conditional.  But not a show-stopper.

ACK

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [RFC PATCH 04/12] qemu: monitor: Add support for BLOCK_WRITE_THRESHOLD event

2017-02-23 Thread Eric Blake
On 02/23/2017 01:21 PM, Peter Krempa wrote:
> The event is fired when a given block backend node (identified by the
> node name) experiences a write beyond the bound set via
> block-set-write-threshold QMP command. This wires up the monitor code to
> extract the data and allow us receiving the events and the capability.

s/receiving/to receive/

> ---
>  src/qemu/qemu_capabilities.c   |  2 ++
>  src/qemu/qemu_capabilities.h   |  1 +
>  src/qemu/qemu_monitor.c| 18 +++
>  src/qemu/qemu_monitor.h| 14 
>  src/qemu/qemu_monitor_json.c   | 26 
> ++
>  tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml   |  1 +
>  tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml   |  1 +
>  .../caps_2.6.0-gicv2.aarch64.xml   |  1 +
>  .../caps_2.6.0-gicv3.aarch64.xml   |  1 +
>  tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml  |  1 +
>  tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml   |  1 +
>  tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml|  1 +
>  tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml   |  1 +
>  tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml|  1 +
>  tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |  1 +
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  1 +
>  16 files changed, 72 insertions(+)
> 

An all-caps capability name is unusual, but not wrong.

ACK.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [RFC PATCH 03/12] lib: Introduce event for tracking disk backing file write threshold

2017-02-23 Thread Eric Blake
On 02/23/2017 01:21 PM, Peter Krempa wrote:
> When using thin provisioning, management tools need to resize the disk
> in certain cases. To avoid having them to poll disk fillng introduce an

Typo, but a different word sounds better:

s/fillng/usage/

> event whic will be fired when a given offset of the storage is written

s/whic/which/

> by the hypervisor. Together with the API which will be added later, it
> will allow to register thresholds for given storage backing volumes and

s/to register/registering/

> this event will then notify management if the threshold is exceeded.
> ---
>  daemon/remote.c | 43 
>  examples/object-events/event-test.c | 19 
>  include/libvirt/libvirt-domain.h| 31 
>  src/conf/domain_event.c | 97 
> +
>  src/conf/domain_event.h | 15 ++
>  src/libvirt_private.syms|  2 +
>  src/remote/remote_driver.c  | 33 +
>  src/remote/remote_protocol.x| 18 ++-
>  src/remote_protocol-structs |  9 
>  tools/virsh-domain.c| 21 
>  10 files changed, 287 insertions(+), 1 deletion(-)
> 

> +++ b/include/libvirt/libvirt-domain.h
> @@ -4175,6 +4175,36 @@ typedef void 
> (*virConnectDomainEventAgentLifecycleCallback)(virConnectPtr conn,
> 
> 
>  /**
> + * virConnectDomainEventBlockThresholdCallback:
> + * @conn: connection object
> + * @dom: domain on which the event occurred
> + * @dev: name associated with the affected disk or storage backing chain
> + *   element
> + * @path: for local storage, the path of the backing chain element
> + * @threshold: threshold
> + * @excess: WTF

Supposedly, how much beyond the threshold a write was detected at the
time the event was fired.  (For example, if I have an 8M file with a
threshold at 6M, then the guest does a 2M write at offset 5M, threshold
would be 1M, because the write from 5-7M is 1M beyond my threshold of 6M).

> + * @opaque: application specified data
> + *
> + * The callback occurs when the hypervisor detects that the given storage
> + * element was written beyond the point specified by @threshold. The excess
> + * data size written beyond @threshold is reported by @excess (if supported
> + * by the hypervisor, 0 otherwise). The event is useful for thin-provisioned
> + * storage.

This description is better than the WTF above :)

> + *
> + * The threshold size can be set via the virDomainSetBlockThreshold API.

(added later in the series, but documenting now is fine)

Looks okay

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [RFC PATCH 02/12] util: storage: Add preliminary storage for node names into virStorageSource

2017-02-23 Thread Eric Blake
On 02/23/2017 01:21 PM, Peter Krempa wrote:
> ---
>  src/libvirt_private.syms  |  1 +
>  src/util/virstoragefile.c | 37 +
>  src/util/virstoragefile.h |  9 +
>  3 files changed, 47 insertions(+)
> 

ACK

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2 3/3] qemu: properly escape socket path for graphics

2017-02-23 Thread Pavel Hrdina
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1352529

Signed-off-by: Pavel Hrdina 
---
 src/qemu/qemu_command.c  | 6 --
 tests/qemuxml2argvdata/qemuxml2argv-name-escape.args | 5 +++--
 tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml  | 7 ++-
 tests/qemuxml2argvtest.c | 3 ++-
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d5da533e50..41eecfd187 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7495,7 +7495,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr 
cfg,
 switch (glisten->type) {
 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
 virBufferAddLit(&opt, "unix:");
-virQEMUBuildBufferEscapeComma(&opt, glisten->socket);
+virQEMUBuildBufferEscape(&opt, glisten->socket);
 break;
 
 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
@@ -7627,7 +7627,9 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr 
cfg,
 goto error;
 }
 
-virBufferAsprintf(&opt, "unix,addr=%s,", glisten->socket);
+virBufferAddLit(&opt, "unix,addr=");
+virQEMUBuildBufferEscape(&opt, glisten->socket);
+virBufferAddLit(&opt, ",");
 hasInsecure = true;
 break;
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args 
b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
index 9ae50bd455..deb37e09e6 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
@@ -3,7 +3,7 @@ PATH=/bin \
 HOME=/home/test \
 USER=test \
 LOGNAME=test \
-QEMU_AUDIO_DRV=none \
+QEMU_AUDIO_DRV=spice \
 /usr/bin/qemu \
 -name guest=foo=1,,bar=2,debug-threads=on \
 -S \
@@ -20,6 +20,7 @@ bar=2/monitor.sock,server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--vnc unix:/tmp/bar,,foo.sock \
+-vnc 'unix:/tmp/lib/domain--1-foo\=1,,bar\=2/vnc.sock' \
+-spice 'unix,addr=/tmp/lib/domain--1-foo\=1,,bar\=2/spice.sock' \
 -vga cirrus \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml 
b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml
index 5e8c7476fe..604e1453f2 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml
@@ -14,6 +14,11 @@
   destroy
   
 /usr/bin/qemu
-
+
+  
+
+
+  
+
   
 
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index f55b04b057..f3b5648b5c 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2455,7 +2455,8 @@ mymain(void)
 
 DO_TEST("name-escape", QEMU_CAPS_NAME_DEBUG_THREADS,
 QEMU_CAPS_OBJECT_SECRET, QEMU_CAPS_CHARDEV, QEMU_CAPS_VNC,
-QEMU_CAPS_NAME_GUEST, QEMU_CAPS_DEVICE_CIRRUS_VGA);
+QEMU_CAPS_NAME_GUEST, QEMU_CAPS_DEVICE_CIRRUS_VGA,
+QEMU_CAPS_SPICE, QEMU_CAPS_SPICE_UNIX);
 DO_TEST("debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS);
 
 DO_TEST("master-key", QEMU_CAPS_OBJECT_SECRET);
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 1/3] util: virbuffer: introduce virBufferEscapeN

2017-02-23 Thread Pavel Hrdina
Signed-off-by: Pavel Hrdina 
---
 src/libvirt_private.syms |   1 +
 src/util/virbuffer.c | 101 +++
 src/util/virbuffer.h |   2 +
 tests/virbuftest.c   |  41 +++
 4 files changed, 145 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 07a35333b1..28e595fe58 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1286,6 +1286,7 @@ virBufferContentAndReset;
 virBufferCurrentContent;
 virBufferError;
 virBufferEscape;
+virBufferEscapeN;
 virBufferEscapeSexpr;
 virBufferEscapeShell;
 virBufferEscapeString;
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
index d582e7dbec..bd4ae9738c 100644
--- a/src/util/virbuffer.c
+++ b/src/util/virbuffer.c
@@ -33,6 +33,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virerror.h"
+#include "virstring.h"
 
 
 /* If adding more fields, ensure to edit buf.h to match
@@ -588,6 +589,106 @@ virBufferEscape(virBufferPtr buf, char escape, const char 
*toescape,
 VIR_FREE(escaped);
 }
 
+
+struct _virBufferEscapePair {
+char escape;
+char *toescape;
+};
+
+
+/**
+ * virBufferEscapeN:
+ * @buf: the buffer to append to
+ * @format: a printf like format string but with only one %s parameter
+ * @str: the string argument which needs to be escaped
+ * @...: the variable list of arguments composed
+ *
+ * The variable list of arguments @... must be composed of
+ * 'char escape, char *toescape' pairs followed by NULL.
+ *
+ * This has the same functionality as virBufferEscape with the extension
+ * that allows to specify multiple pairs of chars that needs to be escaped.
+ */
+void
+virBufferEscapeN(virBufferPtr buf,
+ const char *format,
+ const char *str,
+ ...)
+{
+int len;
+size_t i;
+char escape;
+char *toescape;
+char *escaped = NULL;
+char *out;
+const char *cur;
+struct _virBufferEscapePair escapeItem;
+struct _virBufferEscapePair *escapeList = NULL;
+size_t nescapeList = 0;
+va_list ap;
+
+if ((format == NULL) || (buf == NULL) || (str == NULL))
+return;
+
+if (buf->error)
+return;
+
+len = strlen(str);
+
+va_start(ap, str);
+
+while ((escape = va_arg(ap, int))) {
+if (!(toescape = va_arg(ap, char *))) {
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+
+if (strcspn(str, toescape) == len)
+continue;
+
+escapeItem.escape = escape;
+escapeItem.toescape = toescape;
+
+if (VIR_APPEND_ELEMENT_QUIET(escapeList, nescapeList, escapeItem) < 0) 
{
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+}
+
+if (nescapeList == 0) {
+virBufferAsprintf(buf, format, str);
+goto cleanup;
+}
+
+if (xalloc_oversized(2, len) ||
+VIR_ALLOC_N_QUIET(escaped, 2 * len + 1) < 0) {
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+
+cur = str;
+out = escaped;
+while (*cur != 0) {
+for (i = 0; i < nescapeList; i++) {
+if (strchr(escapeList[i].toescape, *cur)) {
+*out++ = escapeList[i].escape;
+break;
+}
+}
+*out++ = *cur;
+cur++;
+}
+*out = 0;
+
+virBufferAsprintf(buf, format, escaped);
+
+ cleanup:
+va_end(ap);
+VIR_FREE(escapeList);
+VIR_FREE(escaped);
+}
+
+
 /**
  * virBufferURIEncodeString:
  * @buf: the buffer to append to
diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
index 144a1ba06e..94f14b5b16 100644
--- a/src/util/virbuffer.h
+++ b/src/util/virbuffer.h
@@ -82,6 +82,8 @@ void virBufferStrcat(virBufferPtr buf, ...)
   ATTRIBUTE_SENTINEL;
 void virBufferEscape(virBufferPtr buf, char escape, const char *toescape,
  const char *format, const char *str);
+void virBufferEscapeN(virBufferPtr buf, const char *format,
+  const char *str, ...);
 void virBufferEscapeString(virBufferPtr buf, const char *format,
const char *str);
 void virBufferEscapeSexpr(virBufferPtr buf, const char *format,
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
index 22407ab6a8..34160e6b28 100644
--- a/tests/virbuftest.c
+++ b/tests/virbuftest.c
@@ -376,6 +376,35 @@ testBufEscapeStr(const void *opaque ATTRIBUTE_UNUSED)
 
 
 static int
+testBufEscapeN(const void *opaque)
+{
+const struct testBufAddStrData *data = opaque;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+char *actual;
+int ret = -1;
+
+virBufferEscapeN(&buf, "%s", data->data, '\\', "=", ',', ",", NULL);
+
+if (!(actual = virBufferContentAndReset(&buf))) {
+VIR_TEST_DEBUG("testBufEscapeN: buf is empty");
+goto cleanup;
+}
+
+if (STRNEQ_NULLABLE(actual, data->expect)) {
+VIR_TEST_DEBUG("testBufEscapeN: Strings don't match:\n");
+virTestDifference(stderr, data->e

Re: [libvirt] [RFC PATCH 01/12] util: storage: Split out useful bits of virStorageFileParseChainIndex

2017-02-23 Thread Eric Blake
On 02/23/2017 01:21 PM, Peter Krempa wrote:
> The function has very specific semantics. Split out the part that parses
> the backing store specification string into a separate helper so that it
> can be reused later while keeping the wrapper with existing semantics.
> 
> Note that virStorageFileParseChainIndex is pretty well covered by the
> test suite.
> ---
>  src/libvirt_private.syms  |  1 +
>  src/util/virstoragefile.c | 68 
> +++
>  src/util/virstoragefile.h |  5 
>  3 files changed, 63 insertions(+), 11 deletions(-)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 07a35333b..69d1bc860 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2462,6 +2462,7 @@ virStorageFileGetMetadataInternal;
>  virStorageFileGetRelativeBackingPath;
>  virStorageFileGetSCSIKey;
>  virStorageFileIsClusterFS;
> +virStorageFileParseBackingStoreStr;
>  virStorageFileParseChainIndex;
>  virStorageFileProbeFormat;
>  virStorageFileResize;
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index c9420fdb7..3e711228b 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -1442,32 +1442,78 @@ int virStorageFileGetSCSIKey(const char *path,
>  }
>  #endif
> 
> +
> +/**
> + * virStorageFileParseBackingStoreStr:
> + * @str: backing store specifier string to parse
> + * @target: returns target device portion of the string
> + * @chainIndex: returns the backing store portion of the string
> + *
> + * Parses the backing store specifier string such as vda[1], or sda into
> + * components and returns them via arguments. If the string did not specify 
> an
> + * index 0 is assumed.

grammar nit: s/index/index,/

> + *
> + * Returns 0 on success -1 on error
> + */
> +int
> +virStorageFileParseBackingStoreStr(const char *str,
> +   char **target,
> +   unsigned int *chainIndex)
> +{
> +char **strings = NULL;
> +size_t nstrings;
> +unsigned int idx = 0;
> +char *suffix;
> +int ret = -1;
> +
> +*chainIndex = 0;
> +
> +if (!(strings = virStringSplitCount(str, "[", 2, &nstrings)))
> +return -1;
> +
> +if (nstrings == 2) {
> +if (virStrToLong_uip(strings[1], &suffix, 10, &idx) < 0 ||
> +STRNEQ(suffix, "]"))
> +goto cleanup;
> +}
> +
> +if (target &&
> +VIR_STRDUP(*target, strings[0]) < 0)
> +goto cleanup;
> +
> +*chainIndex = idx;
> +ret = 0;
> +
> + cleanup:
> +virStringListFreeCount(strings, nstrings);
> +return ret;
> +}

I might have gone for a simpler implementation (no need to malloc and
throw away a full-blown string split, when it is easy to do by hand):

char *p = strchr(str, '[');
char *suffix;
int ret = 0;

*chainIndex = 0;
if (!p) {
if (target)
ret = VIR_STRDUP(*target, str);
} else if (virStrToLong_uip(p + 1, &suffix, 10, chainIndex) < 0 ||
   STRNEQ(suffix, "]")) {
return -1;
} else if (target) {
ret = VIR_STRNDUP(*target, str, p - str);
}
return ret;

(well, modulo a tweak to the return value if returning 0 is more
important than returning 1 on success)

I see that you were just moving the pre-existing complexity, though.  At
any rate, it's a nice refactoring, whether or not you also improve the
new helper function to not be so roundabout at computing its results.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2 2/3] util: virqemu: introduce virQEMUBuildBufferEscape

2017-02-23 Thread Pavel Hrdina
This will eventually replace virQEMUBuildBufferEscapeComma, however
it's not possible right now.  Some parts of the code that uses the
old function needs to be refactored.

Signed-off-by: Pavel Hrdina 
---
 src/libvirt_private.syms |  1 +
 src/util/virqemu.c   | 17 +
 src/util/virqemu.h   |  1 +
 3 files changed, 19 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 28e595fe58..dffc1f2a24 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2298,6 +2298,7 @@ virProcessWait;
 
 
 # util/virqemu.h
+virQEMUBuildBufferEscape;
 virQEMUBuildBufferEscapeComma;
 virQEMUBuildCommandLineJSON;
 virQEMUBuildCommandLineJSONArrayBitmap;
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 2e9e65f9ef..f10b356781 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -300,6 +300,23 @@ virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char 
*str)
 
 
 /**
+ * virQEMUBuildBufferEscape:
+ * @buf: buffer to append the escaped string
+ * @str: the string to escape
+ *
+ * Some characters passed as values on the QEMU command line must be escaped.
+ *
+ *  - ',' must by escaped by ','
+ *  - '=' must by escaped by '\'
+ */
+void
+virQEMUBuildBufferEscape(virBufferPtr buf, const char *str)
+{
+virBufferEscapeN(buf, "%s", str, ',', ",", '\\', "=", NULL);
+}
+
+
+/**
  * virQEMUBuildLuksOpts:
  * @buf: buffer to build the string into
  * @enc: pointer to encryption info
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 539d62ab14..10aeb67f4e 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -50,6 +50,7 @@ char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
 char *virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr src);
 
 void virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str);
+void virQEMUBuildBufferEscape(virBufferPtr buf, const char *str);
 void virQEMUBuildLuksOpts(virBufferPtr buf,
   virStorageEncryptionInfoDefPtr enc,
   const char *alias)
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 0/3] introduce virBufferEscapeN and fix escape bug

2017-02-23 Thread Pavel Hrdina
I've dropped the STRCAT patches in v2.  The whole purpose of the STRCAT was
to avoid calling *strcspn* several times but it was probably a bad call.
Now we call that function for each pair but if no escaping is required
we at least don't allocate the structure for that pair and later in the
*virBufferEscapeN* we only iterate over the pairs that will escape at least
one character.

Pavel Hrdina (3):
  util: virbuffer: introduce virBufferEscapeN
  util: virqemu: introduce virQEMUBuildBufferEscape
  qemu: properly escape socket path for graphics

 src/libvirt_private.syms   |   2 +
 src/qemu/qemu_command.c|   6 +-
 src/util/virbuffer.c   | 101 +
 src/util/virbuffer.h   |   2 +
 src/util/virqemu.c |  17 
 src/util/virqemu.h |   1 +
 .../qemuxml2argvdata/qemuxml2argv-name-escape.args |   5 +-
 .../qemuxml2argvdata/qemuxml2argv-name-escape.xml  |   7 +-
 tests/qemuxml2argvtest.c   |   3 +-
 tests/virbuftest.c |  41 +
 10 files changed, 179 insertions(+), 6 deletions(-)

-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 0/3] target-i386: Implement query-cpu-model-expansion

2017-02-23 Thread Eduardo Habkost
On Wed, Feb 22, 2017 at 04:00:26PM -0300, Eduardo Habkost wrote:
> This series implements query-cpu-model-expansion on target-i386.
> 
> Changes v2 -> v3:
> -
> 
> * Rebased on top of my x86-next branch:
>   https://github.com/ehabkost/qemu x86-next
> * Added new patch that will extend type=full expansion to
>   return every (writeable) QOM property from the CPU object
> 
> Git branch for testing:
>   https://github.com/ehabkost/qemu-hacks work/x86-query-cpu-expansion
> 
> libvirt code to use the new feature already exist, and were
> submitted to libvir-list, at:
>   https://www.mail-archive.com/libvir-list@redhat.com/msg142168.html
> 

As v2 was sitting on the list since Jan 16, I plan to include
this on my next pull request before soft freeze if there are no
objections.

-- 
Eduardo

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [RFC PATCH 00/12] Add block write threshold event

2017-02-23 Thread Eric Blake
On 02/23/2017 01:21 PM, Peter Krempa wrote:
> Since I'm a procrastinator and I wanted to do this after full node-name 
> support
> is added I'm kind of late for this release here. Since oVirt is asking for 
> this
> feature for a very long time I would like to deliver it ASAP though.

Thanks for picking up on this. I tried once a long time ago:
https://www.redhat.com/archives/libvir-list/2015-June/msg0.html

and got stalled on node name weirdness, so it never went in.

> 
> This series adds a event which is fired once a guest writes beyond a 
> configured
> offset in the backing file. The threshold offset is configurable via a new 
> API.
> 
> This series is in RFC state since I did not manage to polish few details 
> mostly
> connected to node names:
> 
> - currently only the top level image can be selected
> - some blockjobs may clear the remembered node names and thus break this
>   ( re-detection of the backing chain needs to be connected with node name
> detection )
> - the node name detection code is VERY crude

Indeed, that's where I got stalled, but I think you may already be
further along than my attempt. (It may also be that the QMP side from
qemu is easier to use now than when I first tried)

> - I'm not sure how well it plays with qcow images, since I select only the top
>   level node (qcow protocol) rather than the file backing it

That may be a deal-breaker - my recollection is that you HAVE to use the
node-name of the file backing the qcow2 to get the useful threshold, and
not the node-name of the qcow2 protocol.

> - the documentation probably sucks since I did not proof-read
> 
> Any feedback is welcome.
> 
> Peter Krempa (12):
>   util: storage: Split out useful bits of virStorageFileParseChainIndex
>   util: storage: Add preliminary storage for node names into
> virStorageSource
>   lib: Introduce event for tracking disk backing file write threshold
>   qemu: monitor: Add support for BLOCK_WRITE_THRESHOLD event
>   qemu: domain: Add helper to lookup disk by node name
>   qemu: domain: Add helper to generate indexed backing store names
>   qemu: process: Wire up firing of the
> VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD event
>   lib: Add API for setting the threshold size for
> VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD
>   virsh: Implement 'blockthreshold' command to call
> virDomainSetBlockThreshold
>   qemu: domain: Add helper to look up disk soruce by the backing store
> string
>   qemu: implement qemuDomainSetBlockThreshold
>   qemu: WIP: lookup nodenames

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 17/28] qemu: Get host CPU model from QEMU on x86_64

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:15PM +0100, Jiri Denemark wrote:
> Until now host-model CPU mode tried to enable all CPU features supported
> by the host CPU even if QEMU/KVM did not support them. This caused a
> number of issues and made host-model quite unreliable. Asking QEMU for
> the CPU it can provide and the current host makes host-model much more
> robust.
> 
> This commit fixes the following bugs:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1018251
> https://bugzilla.redhat.com/show_bug.cgi?id=1371617
> https://bugzilla.redhat.com/show_bug.cgi?id=1372581
> https://bugzilla.redhat.com/show_bug.cgi?id=1404627
> https://bugzilla.redhat.com/show_bug.cgi?id=870071
> 
> In addition to that, the following bug should be mostly limited to cases
> when an unsupported feature is explicitly requested:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1335534
> 
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - added #include "cpu/cpu_x86.h" removed in an earlier patch
> - adapted to changes to qemuMonitorCPUModelProperty
> 
> Version 2:
> - no change
> 
>  src/qemu/qemu_capabilities.c   | 77 
> ++
>  .../domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml | 33 +-
>  tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml   | 11 +++-
>  3 files changed, 119 insertions(+), 2 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [RFC PATCH 12/12] qemu: WIP: lookup nodenames

2017-02-23 Thread Peter Krempa
---
 src/qemu/qemu_domain.h   |  1 +
 src/qemu/qemu_monitor.c  | 11 ++-
 src/qemu/qemu_monitor_json.c |  8 +++-
 src/qemu/qemu_process.c  |  1 +
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 705a3ad59..db6e9a75f 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -356,6 +356,7 @@ struct qemuDomainDiskInfo {
 bool tray_open;
 bool empty;
 int io_status;
+char *nodename;
 };

 typedef struct _qemuDomainHostdevPrivate qemuDomainHostdevPrivate;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7caced7fe..42c32bc64 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2147,6 +2147,15 @@ qemuMonitorBlockIOStatusToError(const char *status)
 return -1;
 }

+static void
+qemuDomainDiskInfoFree(void *value, const void *name ATTRIBUTE_UNUSED)
+{
+struct qemuDomainDiskInfo *info = value;
+
+VIR_FREE(info->nodename);
+VIR_FREE(info);
+}
+

 virHashTablePtr
 qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
@@ -2156,7 +2165,7 @@ qemuMonitorGetBlockInfo(qemuMonitorPtr mon)

 QEMU_CHECK_MONITOR_NULL(mon);

-if (!(table = virHashCreate(32, virHashValueFree)))
+if (!(table = virHashCreate(32, qemuDomainDiskInfoFree)))
 return NULL;

 if (mon->json)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 4b8103195..6e65b26d3 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1868,9 +1868,11 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,

 for (i = 0; i < virJSONValueArraySize(devices); i++) {
 virJSONValuePtr dev;
+virJSONValuePtr image;
 struct qemuDomainDiskInfo *info;
 const char *thisdev;
 const char *status;
+const char *nodename;

 if (!(dev = qemuMonitorJSONGetBlockDev(devices, i)))
 goto cleanup;
@@ -1907,8 +1909,12 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
 info->tray = true;

 /* presence of 'inserted' notifies that a medium is in the device */
-if (!virJSONValueObjectGetObject(dev, "inserted"))
+if ((image = virJSONValueObjectGetObject(dev, "inserted"))) {
+if ((nodename = virJSONValueObjectGetString(image, "node-name")))
+ignore_value(VIR_STRDUP(info->nodename, nodename));
+} else {
 info->empty = true;
+}

 /* Missing io-status indicates no error */
 if ((status = virJSONValueObjectGetString(dev, "io-status"))) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index cfe4073de..74409f88a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6735,6 +6735,7 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
 /* fill in additional data */
 diskpriv->removable = info->removable;
 diskpriv->tray = info->tray;
+VIR_STEAL_PTR(disk->src->nodeName, info->nodename);
 }

 ret = 0;
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 11/12] qemu: implement qemuDomainSetBlockThreshold

2017-02-23 Thread Peter Krempa
Add code to call the appropriate monitor command and code to lookup the
given disk backing chain member.
---
 src/qemu/qemu_driver.c   | 64 
 src/qemu/qemu_monitor.c  | 13 +
 src/qemu/qemu_monitor.h  |  5 
 src/qemu/qemu_monitor_json.c | 31 +
 src/qemu/qemu_monitor_json.h |  6 +
 5 files changed, 119 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6e1e3d408..279a0033d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20283,6 +20283,69 @@ qemuDomainSetVcpu(virDomainPtr dom,
 }


+static int
+qemuDomainSetBlockThreshold(virDomainPtr dom,
+const char *dev,
+unsigned long long threshold,
+unsigned int flags)
+{
+virQEMUDriverPtr driver = dom->conn->privateData;
+qemuDomainObjPrivatePtr priv;
+virDomainObjPtr vm = NULL;
+virStorageSourcePtr src;
+char *nodename = NULL;
+int rc;
+int ret = -1;
+
+virCheckFlags(0, -1);
+
+if (!(vm = qemuDomObjFromDomain(dom)))
+goto cleanup;
+
+ priv = vm->privateData;
+
+if (virDomainSetBlockThresholdEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+goto cleanup;
+
+if (!virDomainObjIsActive(vm)) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("domain is not running"));
+goto endjob;
+}
+
+if (!(src = qemuDomainGetStorageSourceByDevstr(dev, vm->def)))
+goto endjob;
+
+if (!src->nodeName) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("threshold currently can't be set for block device 
'%s'"),
+   dev);
+goto endjob;
+}
+
+if (VIR_STRDUP(nodename, src->nodeName) < 0)
+goto endjob;
+
+qemuDomainObjEnterMonitor(driver, vm);
+rc = qemuMonitorSetBlockThreshold(priv->mon, nodename, threshold);
+if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+goto endjob;
+
+ret = 0;
+
+ endjob:
+qemuDomainObjEndJob(driver, vm);
+
+ cleanup:
+VIR_FREE(nodename);
+virDomainObjEndAPI(&vm);
+return ret;
+}
+
+
 static virHypervisorDriver qemuHypervisorDriver = {
 .name = QEMU_DRIVER_NAME,
 .connectOpen = qemuConnectOpen, /* 0.2.0 */
@@ -20497,6 +20560,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
 .domainGetGuestVcpus = qemuDomainGetGuestVcpus, /* 2.0.0 */
 .domainSetGuestVcpus = qemuDomainSetGuestVcpus, /* 2.0.0 */
 .domainSetVcpu = qemuDomainSetVcpu, /* 3.1.0 */
+.domainSetBlockThreshold = qemuDomainSetBlockThreshold /* 3.1.0 */
 };


diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a8e113f94..7caced7fe 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4150,3 +4150,16 @@ qemuMonitorQueryQMPSchema(qemuMonitorPtr mon)

 return qemuMonitorJSONQueryQMPSchema(mon);
 }
+
+
+int
+qemuMonitorSetBlockThreshold(qemuMonitorPtr mon,
+ const char *nodename,
+ unsigned long long threshold)
+{
+VIR_DEBUG("mon=%p, node='%s', threshold=%llu", mon, nodename, threshold);
+
+QEMU_CHECK_MONITOR_JSON(mon);
+
+return qemuMonitorJSONSetBlockThreshold(mon, nodename, threshold);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index a866685e9..ef5c2fdc8 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1047,4 +1047,9 @@ int qemuMonitorGetRTCTime(qemuMonitorPtr mon,

 virHashTablePtr qemuMonitorQueryQMPSchema(qemuMonitorPtr mon);

+int qemuMonitorSetBlockThreshold(qemuMonitorPtr mon,
+ const char *nodename,
+ unsigned long long threshold);
+
+
 #endif /* QEMU_MONITOR_H */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index b69d870d3..4b8103195 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -7434,3 +7434,34 @@ qemuMonitorJSONQueryQMPSchema(qemuMonitorPtr mon)

 return ret;
 }
+
+
+int
+qemuMonitorJSONSetBlockThreshold(qemuMonitorPtr mon,
+ const char *nodename,
+ unsigned long long threshold)
+{
+virJSONValuePtr cmd;
+virJSONValuePtr reply = NULL;
+int ret = -1;
+
+if (!(cmd = qemuMonitorJSONMakeCommand("block-set-write-threshold",
+   "s:node-name", nodename,
+   "U:write-threshold", threshold,
+   NULL)))
+return -1;
+
+if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+goto cleanup;
+
+if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virJSONValueFree(cmd);
+virJSONValueFree(reply);
+
+r

[libvirt] [RFC PATCH 08/12] lib: Add API for setting the threshold size for VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD

2017-02-23 Thread Peter Krempa
The new API can be used to configure the threshold when
VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD should be fired.
---
 include/libvirt/libvirt-domain.h |  5 
 src/driver-hypervisor.h  |  8 +++
 src/libvirt-domain.c | 51 
 src/libvirt_public.syms  |  1 +
 src/remote/remote_driver.c   |  1 +
 src/remote/remote_protocol.x | 17 +-
 src/remote_protocol-structs  |  7 ++
 7 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 892cf2cc5..7752cd38c 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4564,4 +4564,9 @@ int virDomainSetVcpu(virDomainPtr domain,
  int state,
  unsigned int flags);

+int virDomainSetBlockThreshold(virDomainPtr domain,
+   const char *dev,
+   unsigned long long threshold,
+   unsigned int flags);
+
 #endif /* __VIR_LIBVIRT_DOMAIN_H__ */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index b81420aef..3053d7ae8 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1257,6 +1257,13 @@ typedef int
int state,
unsigned int flags);

+typedef int
+(*virDrvDomainSetBlockThreshold)(virDomainPtr domain,
+ const char *dev,
+ unsigned long long threshold,
+ unsigned int flags);
+
+
 typedef struct _virHypervisorDriver virHypervisorDriver;
 typedef virHypervisorDriver *virHypervisorDriverPtr;

@@ -1496,6 +1503,7 @@ struct _virHypervisorDriver {
 virDrvDomainGetGuestVcpus domainGetGuestVcpus;
 virDrvDomainSetGuestVcpus domainSetGuestVcpus;
 virDrvDomainSetVcpu domainSetVcpu;
+virDrvDomainSetBlockThreshold domainSetBlockThreshold;
 };


diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 619a9fccb..93ebe1e86 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11797,3 +11797,54 @@ virDomainSetVcpu(virDomainPtr domain,
 virDispatchError(domain->conn);
 return -1;
 }
+
+
+/**
+ * virDomainSetBlockThreshold:
+ * @domain: pointer to domain object
+ * @dev: string specifying the block device or backing chain element
+ * @threshold: threshold in bytes when to fire the event
+ * @flags: currently unused, callers should pass 0
+ *
+ * Set the threshold level for delivering the
+ * VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD if the device or backing chain element
+ * described by @dev is written beyond the set threshold level. The threshold
+ * level is unset once the event fired. The event may not be delivered at all 
if
+ * libvirtd was not running at the moment when the threshold was reached.
+ *
+ * This event allows to use thin-provisioned storage which needs management
+ * tools to grow it without the need for polling of the data.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+int
+virDomainSetBlockThreshold(virDomainPtr domain,
+   const char *dev,
+   unsigned long long threshold,
+   unsigned int flags)
+{
+VIR_DOMAIN_DEBUG(domain, "dev='%s' threshold=%llu flags=%x",
+ NULLSTR(dev), threshold, flags);
+
+virResetLastError();
+
+virCheckDomainReturn(domain, -1);
+virCheckReadOnlyGoto(domain->conn->flags, error);
+
+virCheckNonNullArgGoto(dev, error);
+
+if (domain->conn->driver->domainSetBlockThreshold) {
+int ret;
+ret = domain->conn->driver->domainSetBlockThreshold(domain, dev,
+threshold, flags);
+if (ret < 0)
+goto error;
+return ret;
+}
+
+virReportUnsupportedError();
+
+ error:
+virDispatchError(domain->conn);
+return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 04ef58021..428cf2e19 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -755,6 +755,7 @@ LIBVIRT_3.0.0 {

 LIBVIRT_3.1.0 {
 global:
+virDomainSetBlockThreshold;
 virDomainSetVcpu;
 } LIBVIRT_3.0.0;

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index efa47beaf..baa5cbab3 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8436,6 +8436,7 @@ static virHypervisorDriver hypervisor_driver = {
 .domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */
 .domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */
 .domainSetVcpu = remoteDomainSetVcpu, /* 3.1.0 */
+.domainSetBlockThreshold = remoteDomainSetBlockThreshold, /* 3.1.0 */
 };

 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 39dd2b728..87b2bd365 100644
--- a/src/remote/remote_p

[libvirt] [RFC PATCH 09/12] virsh: Implement 'blockthreshold' command to call virDomainSetBlockThreshold

2017-02-23 Thread Peter Krempa
Add a simple wrapper which will allow to set the threshold for
delivering the event.
---
 tools/virsh-domain.c | 63 
 tools/virsh.pod  |  8 +++
 2 files changed, 71 insertions(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index ee702f3c4..f70f61b72 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -7097,6 +7097,63 @@ cmdSetvcpu(vshControl *ctl, const vshCmd *cmd)


 /*
+ * "blockthreshold" command
+ */
+static const vshCmdInfo info_blockthreshold[] = {
+{.name = "help",
+ .data = N_("attach/detach vcpu or groups of threads")
+},
+{.name = "desc",
+ .data = N_("Add or remove vcpus")
+},
+{.name = NULL}
+};
+
+static const vshCmdOptDef opts_blockthreshold[] = {
+VIRSH_COMMON_OPT_DOMAIN_FULL,
+{.name = "dev",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("device to set threshold for")
+},
+{.name = "threshold",
+ .type = VSH_OT_INT,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("threshold as a scaled number (by default bytes)")
+},
+{.name = NULL}
+};
+
+static bool
+cmdBlockThreshold(vshControl *ctl, const vshCmd *cmd)
+{
+unsigned long long threshold;
+const char *dev = NULL;
+virDomainPtr dom;
+bool ret = false;
+
+if (vshCommandOptStringReq(ctl, cmd, "dev", &dev))
+return false;
+
+if (vshCommandOptScaledInt(ctl, cmd, "threshold",
+   &threshold, 1, ULLONG_MAX) < 0)
+return false;
+
+if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+return false;
+
+if (virDomainSetBlockThreshold(dom, dev, threshold, 0) < 0)
+goto cleanup;
+
+ret = true;
+
+ cleanup:
+virDomainFree(dom);
+return ret;
+}
+
+
+/*
  * "iothreadinfo" command
  */
 static const vshCmdInfo info_iothreadinfo[] = {
@@ -14060,5 +14117,11 @@ const vshCmdDef domManagementCmds[] = {
  .info = info_setvcpu,
  .flags = 0
 },
+{.name = "blockthreshold",
+ .handler = cmdBlockThreshold,
+ .opts = opts_blockthreshold,
+ .info = info_blockthreshold,
+ .flags = 0
+},
 {.name = NULL}
 };
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 6c06ee029..102aefc0c 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1265,6 +1265,14 @@ I<--bytes> with a scaled value allows to use finer 
granularity. A scaled value
 used without I<--bytes> will be rounded down to MiB/s. Note that the
 I<--bytes> may be unsupported by the hypervisor.

+
+=item B I I I
+
+Set the threshold value for delivering the block-threshold event. I
+specifies the disk device target or backing chain element of given device using
+the 'target[1]' syntax. I is a scaled value of the offset. If the
+block device should write beyond that offset the event will be delivered.
+
 =item B I I I

 Resize a block device of domain while the domain is running, I
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 10/12] qemu: domain: Add helper to look up disk soruce by the backing store string

2017-02-23 Thread Peter Krempa
---
 src/qemu/qemu_domain.c | 37 +
 src/qemu/qemu_domain.h |  3 +++
 2 files changed, 40 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b8a65cfd5..1740a9d80 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8341,3 +8341,40 @@ qemuDomainDiskBackingStoreGetName(virDomainDiskDefPtr 
disk,

 return ret;
 }
+
+
+virStorageSourcePtr
+qemuDomainGetStorageSourceByDevstr(const char *devstr,
+   virDomainDefPtr def)
+{
+virDomainDiskDefPtr disk = NULL;
+virStorageSourcePtr src = NULL;
+char *target = NULL;
+unsigned int idx;
+size_t i;
+
+if (virStorageFileParseBackingStoreStr(devstr, &target, &idx) < 0) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("failed to parse block device '%s'"), devstr);
+return NULL;
+}
+
+for (i = 0; i < def->ndisks; i++) {
+if (STREQ(target, def->disks[i]->dst)) {
+disk = def->disks[i];
+break;
+}
+}
+
+if (!disk) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("failed to find disk '%s"), target);
+goto cleanup;
+}
+
+src = virStorageFileChainLookup(disk->src, NULL, NULL, idx, NULL);
+
+ cleanup:
+VIR_FREE(target);
+return src;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 6e847c7ae..705a3ad59 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -859,4 +859,7 @@ char *qemuDomainDiskBackingStoreGetName(virDomainDiskDefPtr 
disk,
 virStorageSourcePtr src,
 unsigned int idx);

+virStorageSourcePtr qemuDomainGetStorageSourceByDevstr(const char *devstr,
+   virDomainDefPtr def);
+
 #endif /* __QEMU_DOMAIN_H__ */
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 07/12] qemu: process: Wire up firing of the VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD event

2017-02-23 Thread Peter Krempa
Bind it to qemus BLOCK_WRITE_THRESHOLD event. Look up the disk by
nodename and construct the string to return.
---
 src/qemu/qemu_process.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ea10fff45..cfe4073de 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1439,6 +1439,45 @@ qemuProcessHandleAcpiOstInfo(qemuMonitorPtr mon 
ATTRIBUTE_UNUSED,


 static int
+qemuProcessHandleBlockThreshold(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+virDomainObjPtr vm,
+const char *nodename,
+unsigned long long threshold,
+unsigned long long excess,
+void *opaque)
+{
+virQEMUDriverPtr driver = opaque;
+virObjectEventPtr event = NULL;
+virDomainDiskDefPtr disk;
+virStorageSourcePtr src;
+unsigned int idx;
+char *dev = NULL;
+const char *path = NULL;
+
+virObjectLock(vm);
+
+VIR_DEBUG("BLOCK_WRITE_THRESHOLD event for block node '%s' in domain %p 
%s:"
+  "threshold '%llu' exceeded by '%llu'",
+  nodename, vm, vm->def->name, threshold, excess);
+
+if ((disk = qemuDomainDiskLookupByNodename(vm->def, nodename, &src, 
&idx))) {
+if (virStorageSourceIsLocalStorage(src))
+path = src->path;
+
+if ((dev = qemuDomainDiskBackingStoreGetName(disk, src, idx))) {
+event = virDomainEventBlockThresholdNewFromObj(vm, dev, path,
+   threshold, excess);
+}
+}
+
+virObjectUnlock(vm);
+qemuDomainEventQueue(driver, event);
+
+return 0;
+}
+
+
+static int
 qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 virDomainObjPtr vm,
 const char *devAlias,
@@ -1634,6 +1673,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
 .domainMigrationStatus = qemuProcessHandleMigrationStatus,
 .domainMigrationPass = qemuProcessHandleMigrationPass,
 .domainAcpiOstInfo = qemuProcessHandleAcpiOstInfo,
+.domainBlockThreshold = qemuProcessHandleBlockThreshold,
 };

 static void
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 06/12] qemu: domain: Add helper to generate indexed backing store names

2017-02-23 Thread Peter Krempa
The code is currently simple, but if we later add node names, it will be
necessary to generate the names based on the node name. Add a helper so
that there's a central point to fix once we add self-generated node
names.
---
 src/qemu/qemu_domain.c | 22 ++
 src/qemu/qemu_domain.h |  4 
 2 files changed, 26 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4b446f1e8..b8a65cfd5 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8319,3 +8319,25 @@ qemuDomainDiskLookupByNodename(virDomainDefPtr def,

 return NULL;
 }
+
+
+/**
+ * qemuDomainDiskBackingStoreGetName:
+ *
+ * Creates a name using the indexed syntax (vda[1])for the given backing store
+ * entry for a disk.
+ */
+char *
+qemuDomainDiskBackingStoreGetName(virDomainDiskDefPtr disk,
+  virStorageSourcePtr src ATTRIBUTE_UNUSED,
+  unsigned int idx)
+{
+char *ret = NULL;
+
+if (idx)
+ignore_value(virAsprintf(&ret, "%s[%d]", disk->dst, idx));
+else
+ignore_value(VIR_STRDUP(ret, disk->dst));
+
+return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 03377645f..6e847c7ae 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -855,4 +855,8 @@ virDomainDiskDefPtr 
qemuDomainDiskLookupByNodename(virDomainDefPtr def,
virStorageSourcePtr *src,
unsigned int *idx);

+char *qemuDomainDiskBackingStoreGetName(virDomainDiskDefPtr disk,
+virStorageSourcePtr src,
+unsigned int idx);
+
 #endif /* __QEMU_DOMAIN_H__ */
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 05/12] qemu: domain: Add helper to lookup disk by node name

2017-02-23 Thread Peter Krempa
Looks up a disk and it's corresponding backing chain element by node
name.
---
 src/qemu/qemu_domain.c | 44 
 src/qemu/qemu_domain.h |  6 ++
 2 files changed, 50 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c187214dc..4b446f1e8 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8275,3 +8275,47 @@ qemuDomainNamespaceTeardownRNG(virQEMUDriverPtr driver,
  cleanup:
 return ret;
 }
+
+
+/**
+ * qemuDomainDiskLookupByNodename:
+ * @def: domain definition to look for the disk
+ * @nodename: block backend node name to find
+ * @src: filled with the specific backing store element if provided
+ * @idx: index of @src in the backing chain, if provided
+ *
+ * Looks up the disk in the domain via @nodename and returns it's definition.
+ * Optionally fills @src and @idx if provided with the specific backing chain
+ * element which corresponds to the node name.
+ */
+virDomainDiskDefPtr
+qemuDomainDiskLookupByNodename(virDomainDefPtr def,
+   const char *nodename,
+   virStorageSourcePtr *src,
+   unsigned int *idx)
+{
+size_t i;
+unsigned int srcindex;
+virStorageSourcePtr tmp = NULL;
+
+if (src)
+*src = NULL;
+
+if (idx)
+*idx = 0;
+
+for (i = 0; i < def->ndisks; i++) {
+if ((tmp = virStorageSourceFindByNodeName(def->disks[i]->src,
+  nodename, &srcindex))) {
+if (src)
+*src = tmp;
+
+if (idx)
+*idx = srcindex;
+
+return def->disks[i];
+}
+}
+
+return NULL;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 72efa3336..03377645f 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -849,4 +849,10 @@ int qemuDomainNamespaceSetupRNG(virQEMUDriverPtr driver,
 int qemuDomainNamespaceTeardownRNG(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainRNGDefPtr rng);
+
+virDomainDiskDefPtr qemuDomainDiskLookupByNodename(virDomainDefPtr def,
+   const char *nodename,
+   virStorageSourcePtr *src,
+   unsigned int *idx);
+
 #endif /* __QEMU_DOMAIN_H__ */
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 04/12] qemu: monitor: Add support for BLOCK_WRITE_THRESHOLD event

2017-02-23 Thread Peter Krempa
The event is fired when a given block backend node (identified by the
node name) experiences a write beyond the bound set via
block-set-write-threshold QMP command. This wires up the monitor code to
extract the data and allow us receiving the events and the capability.
---
 src/qemu/qemu_capabilities.c   |  2 ++
 src/qemu/qemu_capabilities.h   |  1 +
 src/qemu/qemu_monitor.c| 18 +++
 src/qemu/qemu_monitor.h| 14 
 src/qemu/qemu_monitor_json.c   | 26 ++
 tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml   |  1 +
 .../caps_2.6.0-gicv2.aarch64.xml   |  1 +
 .../caps_2.6.0-gicv3.aarch64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml  |  1 +
 tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml|  1 +
 tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml|  1 +
 tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |  1 +
 tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  1 +
 16 files changed, 72 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5b5e3ac18..927ac49cf 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -358,6 +358,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
   "query-cpu-model-expansion", /* 245 */
   "virtio-net.host_mtu",
   "spice-rendernode",
+  "BLOCK_WRITE_THRESHOLD",
 );


@@ -1535,6 +1536,7 @@ struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
 { "MIGRATION", QEMU_CAPS_MIGRATION_EVENT },
 { "VSERPORT_CHANGE", QEMU_CAPS_VSERPORT_CHANGE },
 { "DEVICE_TRAY_MOVED", QEMU_CAPS_DEVICE_TRAY_MOVED },
+{ "BLOCK_WRITE_THRESHOLD", QEMU_CAPS_BLOCK_WRITE_THRESHOLD },
 };

 struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0f998c473..83fb3acaf 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -394,6 +394,7 @@ typedef enum {
 QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION, /* qmp query-cpu-model-expansion */
 QEMU_CAPS_VIRTIO_NET_HOST_MTU, /* virtio-net-*.host_mtu */
 QEMU_CAPS_SPICE_RENDERNODE, /* -spice rendernode */
+QEMU_CAPS_BLOCK_WRITE_THRESHOLD, /* BLOCK_WRITE_THRESHOLD event */

 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index b15207a69..a8e113f94 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1580,6 +1580,24 @@ qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon,


 int
+qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon,
+  const char *nodename,
+  unsigned long long threshold,
+  unsigned long long excess)
+{
+int ret = -1;
+
+VIR_DEBUG("mon=%p, node-name='%s', threshold='%llu', excess='%llu'",
+  mon, nodename, threshold, excess);
+
+QEMU_MONITOR_CALLBACK(mon, ret, domainBlockThreshold, mon->vm,
+  nodename, threshold, excess);
+
+return ret;
+}
+
+
+int
 qemuMonitorSetCapabilities(qemuMonitorPtr mon)
 {
 QEMU_CHECK_MONITOR(mon);
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8811d8501..a866685e9 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -207,6 +207,14 @@ typedef int 
(*qemuMonitorDomainAcpiOstInfoCallback)(qemuMonitorPtr mon,
 void *opaque);


+typedef int (*qemuMonitorDomainBlockThresholdCallback)(qemuMonitorPtr mon,
+   virDomainObjPtr vm,
+   const char *nodename,
+   unsigned long long 
threshold,
+   unsigned long long 
excess,
+   void *opaque);
+
+
 typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks;
 typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr;
 struct _qemuMonitorCallbacks {
@@ -238,6 +246,7 @@ struct _qemuMonitorCallbacks {
 qemuMonitorDomainMigrationStatusCallback domainMigrationStatus;
 qemuMonitorDomainMigrationPassCallback domainMigrationPass;
 qemuMonitorDomainAcpiOstInfoCallback domainAcpiOstInfo;
+qemuMonitorDomainBlockThresholdCallback domainBlockThreshold;
 };

 char *qemuMonitorEscapeArg(const char *in);
@@ -357,6 +366,11 @@ int qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon,
unsigned int source,
unsigned int status);

+int qemuMon

[libvirt] [RFC PATCH 03/12] lib: Introduce event for tracking disk backing file write threshold

2017-02-23 Thread Peter Krempa
When using thin provisioning, management tools need to resize the disk
in certain cases. To avoid having them to poll disk fillng introduce an
event whic will be fired when a given offset of the storage is written
by the hypervisor. Together with the API which will be added later, it
will allow to register thresholds for given storage backing volumes and
this event will then notify management if the threshold is exceeded.
---
 daemon/remote.c | 43 
 examples/object-events/event-test.c | 19 
 include/libvirt/libvirt-domain.h| 31 
 src/conf/domain_event.c | 97 +
 src/conf/domain_event.h | 15 ++
 src/libvirt_private.syms|  2 +
 src/remote/remote_driver.c  | 33 +
 src/remote/remote_protocol.x| 18 ++-
 src/remote_protocol-structs |  9 
 tools/virsh-domain.c| 21 
 10 files changed, 287 insertions(+), 1 deletion(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index f2b9b9aec..511f499de 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1295,6 +1295,48 @@ remoteRelayDomainEventMetadataChange(virConnectPtr conn,
 }


+static int
+remoteRelayDomainEventBlockThreshold(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *dev,
+ const char *path,
+ unsigned long long threshold,
+ unsigned long long excess,
+ void *opaque)
+{
+daemonClientEventCallbackPtr callback = opaque;
+remote_domain_event_block_threshold_msg data;
+
+if (callback->callbackID < 0 ||
+!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
+return -1;
+
+VIR_DEBUG("Relaying domain block threshold event %s %d %s %s %llu %llu, 
callback %d",
+  dom->name, dom->id, dev, NULLSTR(path), threshold, excess, 
callback->callbackID);
+
+/* build return data */
+memset(&data, 0, sizeof(data));
+data.callbackID = callback->callbackID;
+if (VIR_STRDUP(data.dev, dev) < 0)
+goto error;
+if (VIR_ALLOC(data.path) < 0)
+goto error;
+if (VIR_STRDUP(*(data.path), path) < 0)
+goto error;
+data.threshold = threshold;
+data.excess = excess;
+make_nonnull_domain(&data.dom, dom);
+
+remoteDispatchObjectEventSend(callback->client, remoteProgram,
+  REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD,
+  
(xdrproc_t)xdr_remote_domain_event_block_threshold_msg, &data);
+
+return 0;
+ error:
+VIR_FREE(data.dev);
+return -1;
+}
+

 static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
 VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
@@ -1321,6 +1363,7 @@ static virConnectDomainEventGenericCallback 
domainEventCallbacks[] = {
 VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventJobCompleted),
 VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemovalFailed),
 VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMetadataChange),
+VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockThreshold),
 };

 verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/examples/object-events/event-test.c 
b/examples/object-events/event-test.c
index 55c004f93..12690cac0 100644
--- a/examples/object-events/event-test.c
+++ b/examples/object-events/event-test.c
@@ -15,6 +15,7 @@

 #define ARRAY_CARDINALITY(Array) (sizeof(Array) / sizeof(*(Array)))
 #define STREQ(a, b) (strcmp(a, b) == 0)
+#define NULLSTR(s) ((s) ? (s) : "")

 #ifndef ATTRIBUTE_UNUSED
 # define ATTRIBUTE_UNUSED __attribute__((__unused__))
@@ -925,6 +926,23 @@ myDomainEventBlockJobCallback(virConnectPtr conn 
ATTRIBUTE_UNUSED,


 static int
+myDomainEventBlockThresholdCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+virDomainPtr dom,
+const char *dev,
+const char *path,
+unsigned long long threshold,
+unsigned long long excess,
+void *opaque ATTRIBUTE_UNUSED)
+{
+printf("%s EVENT: Domain %s(%d) block threshold callback dev '%s'(%s), "
+   "threshold: '%llu', excess: '%llu'",
+   __func__, virDomainGetName(dom), virDomainGetID(dom),
+   dev, NULLSTR(path), threshold, excess);
+return 0;
+}
+
+
+static int
 myDomainEventMigrationIterationCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
 virDomainPtr dom,
 int iteration,
@@ -1053,6 +1071,7 @@ struct domainEventData domainEvents[] = {
 DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_JOB_COMPLETED, 
myDomainEve

[libvirt] [RFC PATCH 00/12] Add block write threshold event

2017-02-23 Thread Peter Krempa
Since I'm a procrastinator and I wanted to do this after full node-name support
is added I'm kind of late for this release here. Since oVirt is asking for this
feature for a very long time I would like to deliver it ASAP though.

This series adds a event which is fired once a guest writes beyond a configured
offset in the backing file. The threshold offset is configurable via a new API.

This series is in RFC state since I did not manage to polish few details mostly
connected to node names:

- currently only the top level image can be selected
- some blockjobs may clear the remembered node names and thus break this
  ( re-detection of the backing chain needs to be connected with node name
detection )
- the node name detection code is VERY crude
- I'm not sure how well it plays with qcow images, since I select only the top
  level node (qcow protocol) rather than the file backing it
- the documentation probably sucks since I did not proof-read

Any feedback is welcome.

Peter Krempa (12):
  util: storage: Split out useful bits of virStorageFileParseChainIndex
  util: storage: Add preliminary storage for node names into
virStorageSource
  lib: Introduce event for tracking disk backing file write threshold
  qemu: monitor: Add support for BLOCK_WRITE_THRESHOLD event
  qemu: domain: Add helper to lookup disk by node name
  qemu: domain: Add helper to generate indexed backing store names
  qemu: process: Wire up firing of the
VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD event
  lib: Add API for setting the threshold size for
VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD
  virsh: Implement 'blockthreshold' command to call
virDomainSetBlockThreshold
  qemu: domain: Add helper to look up disk soruce by the backing store
string
  qemu: implement qemuDomainSetBlockThreshold
  qemu: WIP: lookup nodenames

 daemon/remote.c|  43 +
 examples/object-events/event-test.c|  19 
 include/libvirt/libvirt-domain.h   |  36 +++
 src/conf/domain_event.c|  97 +++
 src/conf/domain_event.h|  15 +++
 src/driver-hypervisor.h|   8 ++
 src/libvirt-domain.c   |  51 ++
 src/libvirt_private.syms   |   4 +
 src/libvirt_public.syms|   1 +
 src/qemu/qemu_capabilities.c   |   2 +
 src/qemu/qemu_capabilities.h   |   1 +
 src/qemu/qemu_domain.c | 103 
 src/qemu/qemu_domain.h |  14 +++
 src/qemu/qemu_driver.c |  64 +
 src/qemu/qemu_monitor.c|  42 -
 src/qemu/qemu_monitor.h|  19 
 src/qemu/qemu_monitor_json.c   |  65 -
 src/qemu/qemu_monitor_json.h   |   6 ++
 src/qemu/qemu_process.c|  41 
 src/remote/remote_driver.c |  34 +++
 src/remote/remote_protocol.x   |  33 ++-
 src/remote_protocol-structs|  16 
 src/util/virstoragefile.c  | 105 ++---
 src/util/virstoragefile.h  |  14 +++
 tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml   |   1 +
 tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml   |   1 +
 .../caps_2.6.0-gicv2.aarch64.xml   |   1 +
 .../caps_2.6.0-gicv3.aarch64.xml   |   1 +
 tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml  |   1 +
 tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml   |   1 +
 tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml|   1 +
 tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml   |   1 +
 tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml|   1 +
 tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |   1 +
 tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |   1 +
 tools/virsh-domain.c   |  84 +
 tools/virsh.pod|   8 ++
 37 files changed, 922 insertions(+), 14 deletions(-)

-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 02/12] util: storage: Add preliminary storage for node names into virStorageSource

2017-02-23 Thread Peter Krempa
---
 src/libvirt_private.syms  |  1 +
 src/util/virstoragefile.c | 37 +
 src/util/virstoragefile.h |  9 +
 3 files changed, 47 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 69d1bc860..078cca001 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2476,6 +2476,7 @@ virStorageNetProtocolTypeToString;
 virStorageSourceBackingStoreClear;
 virStorageSourceClear;
 virStorageSourceCopy;
+virStorageSourceFindByNodeName;
 virStorageSourceFree;
 virStorageSourceGetActualType;
 virStorageSourceGetSecurityLabelDef;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 3e711228b..d8f66a8a1 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2012,6 +2012,7 @@ virStorageSourceCopy(const virStorageSource *src,
 VIR_STRDUP(ret->backingStoreRaw, src->backingStoreRaw) < 0 ||
 VIR_STRDUP(ret->snapshot, src->snapshot) < 0 ||
 VIR_STRDUP(ret->configFile, src->configFile) < 0 ||
+VIR_STRDUP(ret->nodeName, src->nodeName) < 0 ||
 VIR_STRDUP(ret->compat, src->compat) < 0)
 goto error;

@@ -2232,6 +2233,8 @@ virStorageSourceClear(virStorageSourcePtr def)
 virStorageNetHostDefFree(def->nhosts, def->hosts);
 virStorageAuthDefFree(def->auth);

+VIR_FREE(def->nodeName);
+
 virStorageSourceBackingStoreClear(def);
 }

@@ -3781,3 +3784,37 @@ virStorageSourceIsRelative(virStorageSourcePtr src)

 return false;
 }
+
+
+/**
+ * virStorageSourceFindByNodeName:
+ * @top: backing chain top
+ * @nodeName: node name to find in backing chain
+ * @index: if provided the index in the backing chain
+ *
+ * Looks up the given storage source in the backing chain and returns the
+ * pointer to it. If @index is passed then it's filled by the index in the
+ * backing chain. On failure NULL is returned and no error is reported.
+ */
+virStorageSourcePtr
+virStorageSourceFindByNodeName(virStorageSourcePtr top,
+   const char *nodeName,
+   unsigned int *index)
+{
+virStorageSourcePtr tmp;
+
+if (index)
+*index = 0;
+
+for (tmp = top; tmp; tmp = tmp->backingStore) {
+if (STREQ_NULLABLE(tmp->nodeName, nodeName))
+return tmp;
+
+if (index)
+(*index)++;
+}
+
+if (index)
+*index = 0;
+return NULL;
+}
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 5f6e41911..ffea60075 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -276,6 +276,9 @@ struct _virStorageSource {
 /* Name of the child backing store recorded in metadata of the
  * current file.  */
 char *backingStoreRaw;
+
+/* metadata that allows identifying given storage source */
+char *nodeName;
 };


@@ -395,4 +398,10 @@ virStorageSourcePtr 
virStorageSourceNewFromBackingAbsolute(const char *path);

 bool virStorageSourceIsRelative(virStorageSourcePtr src);

+virStorageSourcePtr
+virStorageSourceFindByNodeName(virStorageSourcePtr top,
+   const char *nodeName,
+   unsigned int *index)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 #endif /* __VIR_STORAGE_FILE_H__ */
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH 01/12] util: storage: Split out useful bits of virStorageFileParseChainIndex

2017-02-23 Thread Peter Krempa
The function has very specific semantics. Split out the part that parses
the backing store specification string into a separate helper so that it
can be reused later while keeping the wrapper with existing semantics.

Note that virStorageFileParseChainIndex is pretty well covered by the
test suite.
---
 src/libvirt_private.syms  |  1 +
 src/util/virstoragefile.c | 68 +++
 src/util/virstoragefile.h |  5 
 3 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 07a35333b..69d1bc860 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2462,6 +2462,7 @@ virStorageFileGetMetadataInternal;
 virStorageFileGetRelativeBackingPath;
 virStorageFileGetSCSIKey;
 virStorageFileIsClusterFS;
+virStorageFileParseBackingStoreStr;
 virStorageFileParseChainIndex;
 virStorageFileProbeFormat;
 virStorageFileResize;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index c9420fdb7..3e711228b 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1442,32 +1442,78 @@ int virStorageFileGetSCSIKey(const char *path,
 }
 #endif

+
+/**
+ * virStorageFileParseBackingStoreStr:
+ * @str: backing store specifier string to parse
+ * @target: returns target device portion of the string
+ * @chainIndex: returns the backing store portion of the string
+ *
+ * Parses the backing store specifier string such as vda[1], or sda into
+ * components and returns them via arguments. If the string did not specify an
+ * index 0 is assumed.
+ *
+ * Returns 0 on success -1 on error
+ */
+int
+virStorageFileParseBackingStoreStr(const char *str,
+   char **target,
+   unsigned int *chainIndex)
+{
+char **strings = NULL;
+size_t nstrings;
+unsigned int idx = 0;
+char *suffix;
+int ret = -1;
+
+*chainIndex = 0;
+
+if (!(strings = virStringSplitCount(str, "[", 2, &nstrings)))
+return -1;
+
+if (nstrings == 2) {
+if (virStrToLong_uip(strings[1], &suffix, 10, &idx) < 0 ||
+STRNEQ(suffix, "]"))
+goto cleanup;
+}
+
+if (target &&
+VIR_STRDUP(*target, strings[0]) < 0)
+goto cleanup;
+
+*chainIndex = idx;
+ret = 0;
+
+ cleanup:
+virStringListFreeCount(strings, nstrings);
+return ret;
+}
+
+
 int
 virStorageFileParseChainIndex(const char *diskTarget,
   const char *name,
   unsigned int *chainIndex)
 {
-char **strings = NULL;
 unsigned int idx = 0;
-char *suffix;
+char *target = NULL;
 int ret = 0;

 *chainIndex = 0;

-if (name && diskTarget)
-strings = virStringSplit(name, "[", 2);
+if (!name || !diskTarget)
+return 0;

-if (virStringListLength((const char * const *)strings) != 2)
-goto cleanup;
+if (virStorageFileParseBackingStoreStr(name, &target, &idx) < 0)
+return 0;

-if (virStrToLong_uip(strings[1], &suffix, 10, &idx) < 0 ||
-STRNEQ(suffix, "]"))
+if (idx == 0)
 goto cleanup;

-if (STRNEQ(diskTarget, strings[0])) {
+if (STRNEQ(diskTarget, target)) {
 virReportError(VIR_ERR_INVALID_ARG,
_("requested target '%s' does not match target '%s'"),
-   strings[0], diskTarget);
+   target, diskTarget);
 ret = -1;
 goto cleanup;
 }
@@ -1475,7 +1521,7 @@ virStorageFileParseChainIndex(const char *diskTarget,
 *chainIndex = idx;

  cleanup:
-virStringListFree(strings);
+VIR_FREE(target);
 return ret;
 }

diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index bea1c35a2..5f6e41911 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -309,6 +309,11 @@ int virStorageFileParseChainIndex(const char *diskTarget,
   unsigned int *chainIndex)
 ATTRIBUTE_NONNULL(3);

+int virStorageFileParseBackingStoreStr(const char *str,
+   char **target,
+   unsigned int *chainIndex)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+
 virStorageSourcePtr virStorageFileChainLookup(virStorageSourcePtr chain,
   virStorageSourcePtr startFrom,
   const char *name,
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 10/28] cpu_x86: Drop virCPUx86MakeData and use virCPUDataNew

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:08PM +0100, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - no change
> 
> Version 2:
> - no change
> 
>  src/cpu/cpu_x86.c  | 147 
> ++---
>  src/cpu/cpu_x86.h  |   3 -
>  src/libvirt_private.syms   |   1 -
>  src/libxl/libxl_capabilities.c |  18 ++---
>  src/qemu/qemu_monitor_json.c   |  33 -
>  5 files changed, 92 insertions(+), 110 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 09/28] qemu: Probe "max" CPU model in TCG

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:07PM +0100, Jiri Denemark wrote:
> Querying "host" CPU model expansion only makes sense for KVM. QEMU 2.9.0
> introduces a new "max" CPU model which can be used to ask QEMU what the
> best CPU it can provide to a TCG domain is.
> 
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - s/type/virtType/ in virQEMUCapsLoadHostCPUModelInfo as type variable
>   was added in the previous patch
> 
> Version 2:
> - no change
> 
>  src/qemu/qemu_capabilities.c   | 151 -
>  src/qemu/qemu_capabilities.h   |   3 +-
>  src/qemu/qemu_capspriv.h   |   3 +-
>  src/qemu/qemu_command.c|   2 +-
>  src/qemu/qemu_process.c|   5 +-
>  .../qemucapabilitiesdata/caps_2.8.0.s390x.replies  |   8 +
>  tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml|   2 +-
>  .../qemucapabilitiesdata/caps_2.9.0.x86_64.replies | 179 
> +
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   | 172 +++-
>  tests/qemuxml2argvtest.c   |   3 +-
>  10 files changed, 480 insertions(+), 48 deletions(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 0b611c323..f31a9ce6e 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -401,13 +401,15 @@ struct _virQEMUCaps {
>  size_t ngicCapabilities;
>  virGICCapability *gicCapabilities;
>  
> -qemuMonitorCPUModelInfoPtr hostCPUModelInfo;
> +qemuMonitorCPUModelInfoPtr kvmCPUModelInfo;
> +qemuMonitorCPUModelInfoPtr tcgCPUModelInfo;
>  
>  /* Anything below is not stored in the cache since the values are
>   * re-computed from the other fields or external data sources every
>   * time we probe QEMU or load the results from the cache.
>   */
> -virCPUDefPtr hostCPUModel;
> +virCPUDefPtr kvmCPUModel;
> +virCPUDefPtr tcgCPUModel;
>  };
>  
>  struct virQEMUCapsSearchData {
> @@ -2164,12 +2166,20 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr 
> qemuCaps)
>  goto error;
>  }
>  
> -if (qemuCaps->hostCPUModel &&
> -!(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel)))
> +if (qemuCaps->kvmCPUModel &&
> +!(ret->kvmCPUModel = virCPUDefCopy(qemuCaps->kvmCPUModel)))
>  goto error;
>  
> -if (qemuCaps->hostCPUModelInfo &&
> -!(ret->hostCPUModelInfo = 
> qemuMonitorCPUModelInfoCopy(qemuCaps->hostCPUModelInfo)))
> +if (qemuCaps->tcgCPUModel &&
> +!(ret->tcgCPUModel = virCPUDefCopy(qemuCaps->tcgCPUModel)))
> +goto error;
> +
> +if (qemuCaps->kvmCPUModelInfo &&
> +!(ret->kvmCPUModelInfo = 
> qemuMonitorCPUModelInfoCopy(qemuCaps->kvmCPUModelInfo)))
> +goto error;
> +
> +if (qemuCaps->tcgCPUModelInfo &&
> +!(ret->tcgCPUModelInfo = 
> qemuMonitorCPUModelInfoCopy(qemuCaps->tcgCPUModelInfo)))
>  goto error;
>  
>  if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
> @@ -2218,8 +2228,10 @@ void virQEMUCapsDispose(void *obj)
>  
>  VIR_FREE(qemuCaps->gicCapabilities);
>  
> -qemuMonitorCPUModelInfoFree(qemuCaps->hostCPUModelInfo);
> -virCPUDefFree(qemuCaps->hostCPUModel);
> +qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
> +qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
> +virCPUDefFree(qemuCaps->kvmCPUModel);
> +virCPUDefFree(qemuCaps->tcgCPUModel);
>  }
>  
>  void
> @@ -2436,9 +2448,13 @@ virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
>  
>  
>  virCPUDefPtr
> -virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps)
> +virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
> +virDomainVirtType type)
>  {
> -return qemuCaps->hostCPUModel;
> +if (type == VIR_DOMAIN_VIRT_KVM)
> +return qemuCaps->kvmCPUModel;
> +else
> +return qemuCaps->tcgCPUModel;
>  }
>  
>  
> @@ -2456,7 +2472,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
> virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch);
>  
>  case VIR_CPU_MODE_HOST_MODEL:
> -return !!qemuCaps->hostCPUModel;
> +return !!virQEMUCapsGetHostModel(qemuCaps, type);
>  
>  case VIR_CPU_MODE_CUSTOM:
>  if (type == VIR_DOMAIN_VIRT_KVM)
> @@ -2823,14 +2839,24 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr 
> qemuCaps,
>  
>  static int
>  virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
> -   qemuMonitorPtr mon)
> +   qemuMonitorPtr mon,
> +   bool tcg)
>  {
> -if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION) ||
> -!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
> +qemuMonitorCPUModelInfoPtr *modelInfo;
> +const char *model;
> +
> +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
>  retu

[libvirt] [PATCH v2 13/14] qemu: Set up the migrate TLS objects for target

2017-02-23 Thread John Ferlan
Support TLS for a migration is a multistep process. The target guest must
be started using the "-object tls-creds-x509,endpoint=server,...". If that
TLS object requires a passphrase an addition "-object security..." would
also be created.  The alias/id used for the TLS object is "objmigrate_tls0",
while the alias/id used for the security object is "migrate-secret0".

Once the domain is started, the "tls-creds" migration parameter must be
set to the alias/id of the "tls-creds-x509" object.

Once the migration completes, removing the two objects is necessary since
the newly started domain could then become the source of a migration and
thus would not be an endpoint.

Handle the possibility of libvirtd stop/reconnect by saving the fact that
a migration is using TLS was started in a "migrateTLS" boolean.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_domain.c|   7 +-
 src/qemu/qemu_domain.h|   4 ++
 src/qemu/qemu_migration.c | 166 ++
 3 files changed, 176 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 40c9dab..af84aac 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -766,7 +766,7 @@ qemuDomainSecretAESClear(qemuDomainSecretAES secret)
 }
 
 
-static void
+void
 qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo)
 {
 if (!*secinfo)
@@ -1844,6 +1844,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
 virBufferEscapeString(buf, "\n",
   priv->channelTargetDir);
 
+if (priv->migrateTLS)
+virBufferAddLit(buf, "\n");
+
 return 0;
 }
 
@@ -2112,6 +2115,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
 if (qemuDomainSetPrivatePathsOld(driver, vm) < 0)
 goto error;
 
+priv->migrateTLS = virXPathBoolean("boolean(./migrateTLS)", ctxt) == 1;
+
 return 0;
 
  error:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 85f7eb6..9ce8677 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -287,6 +287,7 @@ struct _qemuDomainObjPrivate {
 /* for migration's using TLS with a secret (not to be saved in our */
 /* private XML). */
 qemuDomainSecretInfoPtr migSecinfo;
+bool migrateTLS;
 };
 
 # define QEMU_DOMAIN_PRIVATE(vm)   \
@@ -734,6 +735,9 @@ int qemuDomainMasterKeyCreate(virDomainObjPtr vm);
 
 void qemuDomainMasterKeyRemove(qemuDomainObjPrivatePtr priv);
 
+void qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo)
+ATTRIBUTE_NONNULL(1);
+
 void qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk)
 ATTRIBUTE_NONNULL(1);
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 0db1616..0e95fd9 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1487,6 +1487,145 @@ qemuMigrationEatCookie(virQEMUDriverPtr driver,
 return NULL;
 }
 
+
+/* qemuMigrationCheckSetupTLS
+ * @driver: Pointer to driver
+ * @dconn: Connection pointer
+ * @vm: vm object
+ * @flags: migration flags
+ *
+ * Check if flags desired to use TLS and whether it's configured for the
+ * host it's being run on (src or dst depending on caller). If configured
+ * to use a secret for the TLS config, generate and save the migSecinfo.
+ *
+ * Returns 0 on success (or no TLS)
+ */
+static int
+qemuMigrationCheckSetupTLS(virQEMUDriverPtr driver,
+   virConnectPtr dconn,
+   virDomainObjPtr vm,
+   unsigned int flags)
+{
+int ret = -1;
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virQEMUDriverConfigPtr cfg = NULL;
+
+if (flags & VIR_MIGRATE_TLS) {
+cfg = virQEMUDriverGetConfig(driver);
+
+if (!cfg->migrateTLS) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("migration TLS not enabled for the host"));
+goto cleanup;
+}
+
+priv->migrateTLS = true;
+if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir,
+vm, driver->caps) < 0)
+VIR_WARN("Failed to save migrateTLS for vm %s", vm->def->name);
+
+/* If there's a secret associated with the migrate TLS, then we
+ * need to grab it now while we have the connection. */
+if (cfg->migrateTLSx509secretUUID &&
+qemuDomainSecretMigratePrepare(dconn, priv, "migrate",
+   cfg->migrateTLSx509secretUUID) < 0)
+goto cleanup;
+}
+
+ret = 0;
+
+ cleanup:
+virObjectUnref(cfg);
+return ret;
+}
+
+
+/* qemuMigrationAddTLSObjects
+ * @driver: pointer to qemu driver
+ * @priv: private qemu data
+ * @srcAlias: source alias to be used (migrate or nbd)
+ * @tlsCertDir: where to find certs
+ * @tlsListen: server or client
+ * @tlsVerify: tls verify
+ * @tlsAlias: alias to be generated for TLS object
+ * @secAlias: alias to be generated for a secinfo object
+ * @migParams: migration parameters to set
+ *
+ * 

[libvirt] [PATCH v2 10/14] Add new migration flag VIR_MIGRATE_TLS

2017-02-23 Thread John Ferlan
Signed-off-by: John Ferlan 
---
 include/libvirt/libvirt-domain.h | 8 
 src/qemu/qemu_migration.h| 3 ++-
 tools/virsh-domain.c | 7 +++
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index c0f715d..bca04d3 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -815,6 +815,14 @@ typedef enum {
  * post-copy mode. See virDomainMigrateStartPostCopy for more details.
  */
 VIR_MIGRATE_POSTCOPY  = (1 << 15),
+
+/* Setting the VIR_MIGRATE_TLS flag will cause the migration to attempt
+ * to use the TLS environment configured by the hypervisor in order to
+ * perform the migration. If incorrectly configured on either source or
+ * destination, the migration will fail.
+ */
+VIR_MIGRATE_TLS   = (1 << 16),
+
 } virDomainMigrateFlags;
 
 
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 14c6178..bcebf06 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -45,7 +45,8 @@ typedef qemuMigrationCompression *qemuMigrationCompressionPtr;
  VIR_MIGRATE_ABORT_ON_ERROR |   \
  VIR_MIGRATE_AUTO_CONVERGE |\
  VIR_MIGRATE_RDMA_PIN_ALL | \
- VIR_MIGRATE_POSTCOPY)
+ VIR_MIGRATE_POSTCOPY | \
+ VIR_MIGRATE_TLS)
 
 /* All supported migration parameters and their types. */
 # define QEMU_MIGRATION_PARAMETERS\
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 09a9f82..ebd4b33 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -10222,6 +10222,10 @@ static const vshCmdOptDef opts_migrate[] = {
  .type = VSH_OT_STRING,
  .help = N_("filename containing updated persistent XML for the target")
 },
+{.name = "tls",
+ .type = VSH_OT_BOOL,
+ .help = N_("use TLS for migration")
+},
 {.name = NULL}
 };
 
@@ -10463,6 +10467,9 @@ doMigrate(void *opaque)
 if (vshCommandOptBool(cmd, "postcopy"))
 flags |= VIR_MIGRATE_POSTCOPY;
 
+if (vshCommandOptBool(cmd, "tls"))
+flags |= VIR_MIGRATE_TLS;
+
 if (flags & VIR_MIGRATE_PEER2PEER || vshCommandOptBool(cmd, "direct")) {
 if (virDomainMigrateToURI3(dom, desturi, params, nparams, flags) == 0)
 ret = '0';
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 11/14] qemu: Create #define for TLS configuration setup.

2017-02-23 Thread John Ferlan
Create GET_CONFIG_TLS_CERT to set up the TLS for 'chardev' TLS setting.
Soon to be reused.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_conf.c | 43 +++
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index b5b0645..b75cd54 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -529,22 +529,33 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr 
cfg,
 if (virConfGetValueBool(conf, "spice_auto_unix_socket", 
&cfg->spiceAutoUnixSocket) < 0)
 goto cleanup;
 
-if (virConfGetValueBool(conf, "chardev_tls", &cfg->chardevTLS) < 0)
-goto cleanup;
-if (virConfGetValueString(conf, "chardev_tls_x509_cert_dir", 
&cfg->chardevTLSx509certdir) < 0)
-goto cleanup;
-if ((rv = virConfGetValueBool(conf, "chardev_tls_x509_verify", 
&cfg->chardevTLSx509verify)) < 0)
-goto cleanup;
-if (rv == 0)
-cfg->chardevTLSx509verify = cfg->defaultTLSx509verify;
-if (virConfGetValueString(conf, "chardev_tls_x509_secret_uuid",
-  &cfg->chardevTLSx509secretUUID) < 0)
-goto cleanup;
-if (!cfg->chardevTLSx509secretUUID && cfg->defaultTLSx509secretUUID) {
-if (VIR_STRDUP(cfg->chardevTLSx509secretUUID,
-   cfg->defaultTLSx509secretUUID) < 0)
-goto cleanup;
-}
+#define GET_CONFIG_TLS_CERT(val)\
+do {\
+if (virConfGetValueBool(conf, #val "_tls", &cfg->val## TLS) < 0)\
+goto cleanup;   \
+if ((rv = virConfGetValueBool(conf, #val "_tls_x509_verify",\
+  &cfg->val## TLSx509verify)) < 0)  \
+goto cleanup;   \
+if (rv == 0)\
+cfg->val## TLSx509verify = cfg->defaultTLSx509verify;   \
+if (virConfGetValueString(conf, #val "_tls_x509_cert_dir",  \
+  &cfg->val## TLSx509certdir) < 0)  \
+goto cleanup;   \
+if (virConfGetValueString(conf, \
+  #val "_tls_x509_secret_uuid", \
+  &cfg->val## TLSx509secretUUID) < 0)   \
+goto cleanup;   \
+if (!cfg->val## TLSx509secretUUID &&\
+cfg->defaultTLSx509secretUUID) {\
+if (VIR_STRDUP(cfg->val## TLSx509secretUUID,\
+   cfg->defaultTLSx509secretUUID) < 0)  \
+goto cleanup;   \
+}   \
+} while (false);
+
+GET_CONFIG_TLS_CERT(chardev);
+
+#undef GET_CONFIG_TLS_CERT
 
 if (virConfGetValueUInt(conf, "remote_websocket_port_min", 
&cfg->webSocketPortMin) < 0)
 goto cleanup;
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 08/14] qemu: Introduce qemuDomainGetTLSObjects

2017-02-23 Thread John Ferlan
Split apart and rename qemuDomainGetChardevTLSObjects in order to make a
more generic API that can create the TLS JSON prop objects (secret and
tls-creds-x509) to be used to create the objects

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 55 ++---
 src/qemu/qemu_hotplug.h | 11 ++
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d7a1f1f..9728b43 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1604,40 +1604,34 @@ qemuDomainAddTLSObjects(virQEMUDriverPtr driver,
 }
 
 
-static int
-qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr cfg,
-   qemuDomainObjPrivatePtr priv,
-   virDomainChrSourceDefPtr dev,
-   char *charAlias,
-   virJSONValuePtr *tlsProps,
-   char **tlsAlias,
-   virJSONValuePtr *secProps,
-   char **secAlias)
+int
+qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
+qemuDomainSecretInfoPtr secinfo,
+const char *tlsCertdir,
+bool tlsListen,
+bool tlsVerify,
+const char *srcAlias,
+virJSONValuePtr *tlsProps,
+char **tlsAlias,
+virJSONValuePtr *secProps,
+char **secAlias)
 {
-qemuDomainChrSourcePrivatePtr chrSourcePriv =
-QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev);
-
 /* Add a secret object in order to access the TLS environment.
  * The secinfo will only be created for serial TCP device. */
-if (chrSourcePriv && chrSourcePriv->secinfo) {
-if (qemuBuildSecretInfoProps(chrSourcePriv->secinfo, secProps) < 0)
+if (secinfo) {
+if (qemuBuildSecretInfoProps(secinfo, secProps) < 0)
 return -1;
 
-if (!(*secAlias = qemuDomainGetSecretAESAlias(charAlias, false)))
+if (!(*secAlias = qemuDomainGetSecretAESAlias(srcAlias, false)))
 return -1;
 }
 
-if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
- dev->data.tcp.listen,
- cfg->chardevTLSx509verify,
- *secAlias,
- priv->qemuCaps,
- tlsProps) < 0)
+if (qemuBuildTLSx509BackendProps(tlsCertdir, tlsListen, tlsVerify,
+ *secAlias, qemuCaps, tlsProps) < 0)
 return -1;
 
-if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(charAlias)))
+if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(srcAlias)))
 return -1;
-dev->data.tcp.tlscreds = true;
 
 return 0;
 }
@@ -1656,6 +1650,8 @@ qemuDomainAddChardevTLSObjects(virConnectPtr conn,
 int ret = -1;
 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 qemuDomainObjPrivatePtr priv = vm->privateData;
+qemuDomainChrSourcePrivatePtr chrSourcePriv;
+qemuDomainSecretInfoPtr secinfo = NULL;
 virJSONValuePtr tlsProps = NULL;
 virJSONValuePtr secProps = NULL;
 
@@ -1671,10 +1667,17 @@ qemuDomainAddChardevTLSObjects(virConnectPtr conn,
 if (qemuDomainSecretChardevPrepare(conn, cfg, priv, devAlias, dev) < 0)
 goto cleanup;
 
-if (qemuDomainGetChardevTLSObjects(cfg, priv, dev, charAlias,
-   &tlsProps, tlsAlias,
-   &secProps, secAlias) < 0)
+if ((chrSourcePriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev)))
+secinfo = chrSourcePriv->secinfo;
+
+if (qemuDomainGetTLSObjects(priv->qemuCaps, secinfo,
+cfg->chardevTLSx509certdir,
+dev->data.tcp.listen,
+cfg->chardevTLSx509verify,
+charAlias, &tlsProps, tlsAlias,
+&secProps, secAlias) < 0)
 goto cleanup;
+dev->data.tcp.tlscreds = true;
 
 if (qemuDomainAddTLSObjects(driver, vm, *secAlias, &secProps,
 *tlsAlias, &tlsProps) < 0)
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 24cf033..73f2b1f 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -46,6 +46,17 @@ int qemuDomainAddTLSObjects(virQEMUDriverPtr driver,
 const char *tlsAlias,
 virJSONValuePtr *tlsProps);
 
+int qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
+qemuDomainSecretInfoPtr secinfo,
+const char *tlsCertdir,
+bool tlsListen,
+bool tlsVerify,
+const char *srcAlia

[libvirt] [PATCH v2 09/14] qemu: Add TLS params to _qemuMonitorMigrationParams

2017-02-23 Thread John Ferlan
Add the fields to support setting tls-creds and tls-hostname during
a migration (either source or target)

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_monitor.c  | 11 ---
 src/qemu/qemu_monitor.h  |  3 +++
 src/qemu/qemu_monitor_json.c | 10 ++
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index b15207a..898bbe1 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2504,12 +2504,15 @@ qemuMonitorSetMigrationParams(qemuMonitorPtr mon,
 {
 VIR_DEBUG("compressLevel=%d:%d compressThreads=%d:%d "
   "decompressThreads=%d:%d cpuThrottleInitial=%d:%d "
-  "cpuThrottleIncrement=%d:%d",
+  "cpuThrottleIncrement=%d:%d tlsAlias=%s "
+  "tlsHostname=%s",
   params->compressLevel_set, params->compressLevel,
   params->compressThreads_set, params->compressThreads,
   params->decompressThreads_set, params->decompressThreads,
   params->cpuThrottleInitial_set, params->cpuThrottleInitial,
-  params->cpuThrottleIncrement_set, params->cpuThrottleIncrement);
+  params->cpuThrottleIncrement_set, params->cpuThrottleIncrement,
+  NULLSTR(params->migrateTLSAlias),
+  NULLSTR(params->migrateTLSHostname));
 
 QEMU_CHECK_MONITOR_JSON(mon);
 
@@ -2517,7 +2520,9 @@ qemuMonitorSetMigrationParams(qemuMonitorPtr mon,
 !params->compressThreads_set &&
 !params->decompressThreads_set &&
 !params->cpuThrottleInitial_set &&
-!params->cpuThrottleIncrement_set)
+!params->cpuThrottleIncrement_set &&
+!params->migrateTLSAlias &&
+!params->migrateTLSHostname)
 return 0;
 
 return qemuMonitorJSONSetMigrationParams(mon, params);
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8811d85..b292be5 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -570,6 +570,9 @@ struct _qemuMonitorMigrationParams {
 
 bool cpuThrottleIncrement_set;
 int cpuThrottleIncrement;
+
+char *migrateTLSAlias;
+char *migrateTLSHostname;
 };
 
 int qemuMonitorGetMigrationParams(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7aa9e31..1112d10 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2637,6 +2637,16 @@ qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon,
 
 #undef APPEND
 
+if (params->migrateTLSAlias &&
+virJSONValueObjectAppendString(args, "tls-creds",
+   params->migrateTLSAlias) < 0)
+goto cleanup;
+
+if (params->migrateTLSHostname &&
+virJSONValueObjectAppendString(args, "tls-hostname",
+   params->migrateTLSHostname) < 0)
+goto cleanup;
+
 if (virJSONValueObjectAppend(cmd, "arguments", args) < 0)
 goto cleanup;
 args = NULL;
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 14/14] qemu: Set up the migration TLS objects for source

2017-02-23 Thread John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1300769

Modify the Begin phase to add the checks to determine whether a migration
wishes to use TLS and whether it's configured including adding the secret
into the priv->migSecinfo for the source domain.

Modify the Perform phase in qemuMigrationRun in order to generate the
TLS objects to be used for the migration and set the migration channel
parameters 'tls-creds' and possibly 'tls-hostname' in order to enable TLS.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_migration.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 0e95fd9..4779d23 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3452,6 +3452,9 @@ qemuMigrationBegin(virConnectPtr conn,
 goto endjob;
 }
 
+if (qemuMigrationCheckSetupTLS(driver, conn, vm, flags) < 0)
+goto endjob;
+
 /* Check if there is any ejected media.
  * We don't want to require them on the destination.
  */
@@ -4802,8 +4805,12 @@ qemuMigrationRun(virQEMUDriverPtr driver,
 {
 int ret = -1;
 unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
+virQEMUDriverConfigPtr cfg = NULL;
 qemuDomainObjPrivatePtr priv = vm->privateData;
 qemuMigrationCookiePtr mig = NULL;
+char *tlsAlias = NULL;
+char *tlsHostname = NULL;
+char *secAlias = NULL;
 qemuMigrationIOThreadPtr iothread = NULL;
 int fd = -1;
 unsigned long migrate_speed = resource ? resource : priv->migMaxBandwidth;
@@ -4867,6 +4874,29 @@ qemuMigrationRun(virQEMUDriverPtr driver,
 if (qemuDomainMigrateGraphicsRelocate(driver, vm, mig, graphicsuri) < 0)
 VIR_WARN("unable to provide data for graphics client relocation");
 
+/* If we're using TLS attempt to add the objects */
+if (priv->migrateTLS) {
+cfg = virQEMUDriverGetConfig(driver);
+if (qemuMigrationAddTLSObjects(driver, vm, "migrate",
+   cfg->migrateTLSx509certdir, false,
+   cfg->migrateTLSx509verify,
+   &tlsAlias, &secAlias, migParams) < 0)
+goto cleanup;
+
+/* We need to add the tls-hostname only for special circumstances.
+ * When using "fd:" or "exec:", qemu needs to know the hostname of
+ * the target qemu to correctly validate the x509 certificate
+ * it receives. */
+if (STREQ(spec->dest.host.protocol, "fd") ||
+STREQ(spec->dest.host.protocol, "exec")) {
+if (VIR_STRDUP(tlsHostname, spec->dest.host.name) < 0) {
+qemuDomainDelTLSObjects(driver, vm, secAlias, tlsAlias);
+return -1;
+}
+migParams->migrateTLSHostname = tlsHostname;
+}
+}
+
 if (migrate_flags & (QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
  QEMU_MONITOR_MIGRATE_NON_SHARED_INC)) {
 if (mig->nbd) {
@@ -5047,6 +5077,10 @@ qemuMigrationRun(virQEMUDriverPtr driver,
 ret = -1;
 }
 
+qemuMigrationDelTLSObjects(driver, cfg, vm, &secAlias, &tlsAlias);
+VIR_FREE(tlsHostname);
+virObjectUnref(cfg);
+
 if (spec->fwdType != MIGRATION_FWD_DIRECT) {
 if (iothread && qemuMigrationStopTunnel(iothread, ret < 0) < 0)
 ret = -1;
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 05/14] qemu: Refactor qemuDomainGetChardevTLSObjects to converge code

2017-02-23 Thread John Ferlan
Create a qemuDomainAddChardevTLSObjects which will encapsulate the
qemuDomainGetChardevTLSObjects and qemuDomainAddTLSObjects so that
the callers don't need to worry about the props.

Move the dev->type and haveTLS checks in to the Add function to avoid
an unnecessary call to qemuDomainAddTLSObjects

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 80 ++---
 1 file changed, 43 insertions(+), 37 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index bb90a34..503fb30 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1617,10 +1617,6 @@ qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr 
cfg,
 qemuDomainChrSourcePrivatePtr chrSourcePriv =
 QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev);
 
-if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
-dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES)
-return 0;
-
 /* Add a secret object in order to access the TLS environment.
  * The secinfo will only be created for serial TCP device. */
 if (chrSourcePriv && chrSourcePriv->secinfo) {
@@ -1647,6 +1643,43 @@ qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr 
cfg,
 }
 
 
+static int
+qemuDomainAddChardevTLSObjects(virQEMUDriverPtr driver,
+   virQEMUDriverConfigPtr cfg,
+   virDomainObjPtr vm,
+   virDomainChrSourceDefPtr dev,
+   char *charAlias,
+   char **tlsAlias,
+   char **secAlias)
+{
+int ret = -1;
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virJSONValuePtr tlsProps = NULL;
+virJSONValuePtr secProps = NULL;
+
+if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
+dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES)
+return 0;
+
+if (qemuDomainGetChardevTLSObjects(cfg, priv, dev, charAlias,
+   &tlsProps, tlsAlias,
+   &secProps, secAlias) < 0)
+goto cleanup;
+
+if (qemuDomainAddTLSObjects(driver, vm, *secAlias, &secProps,
+*tlsAlias, &tlsProps) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virJSONValueFree(tlsProps);
+virJSONValueFree(secProps);
+
+return ret;
+}
+
+
 int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -1660,8 +1693,6 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 char *charAlias = NULL;
 char *devstr = NULL;
 bool chardevAdded = false;
-virJSONValuePtr tlsProps = NULL;
-virJSONValuePtr secProps = NULL;
 char *tlsAlias = NULL;
 char *secAlias = NULL;
 bool need_release = false;
@@ -1690,13 +1721,8 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
redirdev->source) < 0)
 goto cleanup;
 
-if (qemuDomainGetChardevTLSObjects(cfg, priv, redirdev->source,
-   charAlias, &tlsProps, &tlsAlias,
-   &secProps, &secAlias) < 0)
-goto cleanup;
-
-if (qemuDomainAddTLSObjects(driver, vm, secAlias, &secProps,
-tlsAlias, &tlsProps) < 0)
+if (qemuDomainAddChardevTLSObjects(driver, cfg, vm, redirdev->source,
+   charAlias, &tlsAlias, &secAlias) < 0)
 goto audit;
 
 qemuDomainObjEnterMonitor(driver, vm);
@@ -1721,9 +1747,7 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 if (ret < 0 && need_release)
 qemuDomainReleaseDeviceAddress(vm, &redirdev->info, NULL);
 VIR_FREE(tlsAlias);
-virJSONValueFree(tlsProps);
 VIR_FREE(secAlias);
-virJSONValueFree(secProps);
 VIR_FREE(charAlias);
 VIR_FREE(devstr);
 virObjectUnref(cfg);
@@ -1919,9 +1943,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 bool chardevAttached = false;
 bool teardowncgroup = false;
 bool teardowndevice = false;
-virJSONValuePtr tlsProps = NULL;
 char *tlsAlias = NULL;
-virJSONValuePtr secProps = NULL;
 char *secAlias = NULL;
 bool need_release = false;
 
@@ -1960,13 +1982,8 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
dev) < 0)
 goto cleanup;
 
-if (qemuDomainGetChardevTLSObjects(cfg, priv, dev, charAlias,
-   &tlsProps, &tlsAlias,
-   &secProps, &secAlias) < 0)
-goto cleanup;
-
-if (qemuDomainAddTLSObjects(driver, vm, secAlias, &secProps,
-tlsAlias, &tlsProps) < 0)
+if (qemuDomainAddChardevTLSObjects(driver, cfg, vm, dev, charAlias,
+   &tlsAlias, &secAlias) < 0)
 goto audit;
 
 qemuDomainObjEn

[libvirt] [PATCH v2 02/14] qemu: Introduce qemuDomainSecretMigratePrepare

2017-02-23 Thread John Ferlan
Introduce API to Prepare a qemuDomainSecretInfoPtr to be
used with a migrate or nbd TLS object

Also alter the error message in ChardevPrepare when UUIDParse fails
to be consistent with the message for MigratePrepare

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_domain.c | 48 ++--
 src/qemu/qemu_domain.h | 85 --
 2 files changed, 94 insertions(+), 39 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b7594b3..40c9dab 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1353,8 +1353,9 @@ qemuDomainSecretChardevPrepare(virConnectPtr conn,
 
 if (virUUIDParse(cfg->chardevTLSx509secretUUID,
  seclookupdef.u.uuid) < 0) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("malformed chardev TLS secret uuid in 
qemu.conf"));
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("malformed TLS secret uuid '%s' in qemu.conf"),
+   cfg->chardevTLSx509secretUUID);
 return -1;
 }
 seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
@@ -1379,6 +1380,47 @@ qemuDomainSecretChardevPrepare(virConnectPtr conn,
 }
 
 
+/* qemuDomainSecretMigratePrepare
+ * @conn: Pointer to connection
+ * @priv: pointer to domain private object
+ * @srcAlias: Alias to use (either migrate or nbd)
+ * @secretUUID: UUID for the secret from the cfg (migrate or nbd)
+ *
+ * Create and prepare the qemuDomainSecretInfoPtr to be used for either
+ * a migration or nbd. Unlike other domain secret prepare functions, this
+ * is only expected to be called for a single object/instance. Theoretically
+ * the object could be reused, although that results in keeping a secret
+ * stored in memory for perhaps longer than expected or necessary.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+qemuDomainSecretMigratePrepare(virConnectPtr conn,
+   qemuDomainObjPrivatePtr priv,
+   const char *srcAlias,
+   const char *secretUUID)
+{
+virSecretLookupTypeDef seclookupdef = {0};
+
+if (virUUIDParse(secretUUID, seclookupdef.u.uuid) < 0) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("malformed TLS secret uuid '%s' in qemu.conf"),
+   secretUUID);
+return -1;
+}
+seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
+
+if (!(priv->migSecinfo =
+  qemuDomainSecretInfoNew(conn, priv, srcAlias,
+  VIR_SECRET_USAGE_TYPE_TLS, NULL,
+  &seclookupdef, false, "TLS X.509")))
+return -1;
+
+return 0;
+}
+
+
+
 /* qemuDomainSecretDestroy:
  * @vm: Domain object
  *
@@ -1643,6 +1685,8 @@ qemuDomainObjPrivateFree(void *data)
 
 VIR_FREE(priv->libDir);
 VIR_FREE(priv->channelTargetDir);
+
+qemuDomainSecretInfoFree(&priv->migSecinfo);
 qemuDomainMasterKeyFree(priv);
 
 VIR_FREE(priv);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 72efa33..85f7eb6 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -175,6 +175,43 @@ VIR_ENUM_DECL(qemuDomainNamespace)
 bool qemuDomainNamespaceEnabled(virDomainObjPtr vm,
 qemuDomainNamespace ns);
 
+/* Type of domain secret */
+typedef enum {
+VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN = 0,
+VIR_DOMAIN_SECRET_INFO_TYPE_AES,  /* utilize GNUTLS_CIPHER_AES_256_CBC */
+
+VIR_DOMAIN_SECRET_INFO_TYPE_LAST
+} qemuDomainSecretInfoType;
+
+typedef struct _qemuDomainSecretPlain qemuDomainSecretPlain;
+typedef struct _qemuDomainSecretPlain *qemuDomainSecretPlainPtr;
+struct _qemuDomainSecretPlain {
+char *username;
+uint8_t *secret;
+size_t secretlen;
+};
+
+# define QEMU_DOMAIN_AES_IV_LEN 16   /* 16 bytes for 128 bit random */
+ /*initialization vector */
+typedef struct _qemuDomainSecretAES qemuDomainSecretAES;
+typedef struct _qemuDomainSecretAES *qemuDomainSecretAESPtr;
+struct _qemuDomainSecretAES {
+char *username;
+char *alias;  /* generated alias for secret */
+char *iv; /* base64 encoded initialization vector */
+char *ciphertext; /* encoded/encrypted secret */
+};
+
+typedef struct _qemuDomainSecretInfo qemuDomainSecretInfo;
+typedef qemuDomainSecretInfo *qemuDomainSecretInfoPtr;
+struct _qemuDomainSecretInfo {
+qemuDomainSecretInfoType type;
+union {
+qemuDomainSecretPlain plain;
+qemuDomainSecretAES aes;
+} s;
+};
+
 typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
 typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
 struct _qemuDomainObjPrivate {
@@ -246,48 +283,15 @@ struct _qemuDomainObjPrivate {
 
 /* note whether memory device alias does not correspond to slot number */
 bool memAliasOrderMismatch;
+
+/* for 

[libvirt] [PATCH v2 06/14] qemu: Move qemuDomainSecretChardevPrepare call

2017-02-23 Thread John Ferlan
Move the call to inside the qemuDomainAddChardevTLSObjects in order to
further converge the code.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 33 +++--
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 503fb30..b59f3ab 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1644,10 +1644,12 @@ qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr 
cfg,
 
 
 static int
-qemuDomainAddChardevTLSObjects(virQEMUDriverPtr driver,
+qemuDomainAddChardevTLSObjects(virConnectPtr conn,
+   virQEMUDriverPtr driver,
virQEMUDriverConfigPtr cfg,
virDomainObjPtr vm,
virDomainChrSourceDefPtr dev,
+   char *devAlias,
char *charAlias,
char **tlsAlias,
char **secAlias)
@@ -1661,6 +1663,9 @@ qemuDomainAddChardevTLSObjects(virQEMUDriverPtr driver,
 dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES)
 return 0;
 
+if (qemuDomainSecretChardevPrepare(conn, cfg, priv, devAlias, dev) < 0)
+goto cleanup;
+
 if (qemuDomainGetChardevTLSObjects(cfg, priv, dev, charAlias,
&tlsProps, tlsAlias,
&secProps, secAlias) < 0)
@@ -1717,12 +1722,9 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 if (VIR_REALLOC_N(def->redirdevs, def->nredirdevs+1) < 0)
 goto cleanup;
 
-if (qemuDomainSecretChardevPrepare(conn, cfg, priv, redirdev->info.alias,
-   redirdev->source) < 0)
-goto cleanup;
-
-if (qemuDomainAddChardevTLSObjects(driver, cfg, vm, redirdev->source,
-   charAlias, &tlsAlias, &secAlias) < 0)
+if (qemuDomainAddChardevTLSObjects(conn, driver, cfg, vm, redirdev->source,
+   redirdev->info.alias, charAlias,
+   &tlsAlias, &secAlias) < 0)
 goto audit;
 
 qemuDomainObjEnterMonitor(driver, vm);
@@ -1978,11 +1980,8 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 if (qemuDomainChrPreInsert(vmdef, chr) < 0)
 goto cleanup;
 
-if (qemuDomainSecretChardevPrepare(conn, cfg, priv, chr->info.alias,
-   dev) < 0)
-goto cleanup;
-
-if (qemuDomainAddChardevTLSObjects(driver, cfg, vm, dev, charAlias,
+if (qemuDomainAddChardevTLSObjects(conn, driver, cfg, vm, dev,
+   chr->info.alias, charAlias,
&tlsAlias, &secAlias) < 0)
 goto audit;
 
@@ -2120,12 +2119,10 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
 goto cleanup;
 
 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) {
-if (qemuDomainSecretChardevPrepare(conn, cfg, priv, rng->info.alias,
-   rng->source.chardev) < 0)
-goto cleanup;
-
-if (qemuDomainAddChardevTLSObjects(driver, cfg, vm, 
rng->source.chardev,
-   charAlias, &tlsAlias, &secAlias) < 
0)
+if (qemuDomainAddChardevTLSObjects(conn, driver, cfg, vm,
+   rng->source.chardev,
+   rng->info.alias, charAlias,
+   &tlsAlias, &secAlias) < 0)
 goto audit;
 }
 
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 12/14] conf: Introduce migrate_tls_x509_cert_dir

2017-02-23 Thread John Ferlan
Add a new TLS X.509 certificate type - "migrate". This will handle the
creation of a TLS certificate capability (and possibly repository) to
be used for migrations. Similar to chardev's, credentials will be handled
via a libvirt secrets.

Signed-off-by: John Ferlan 
---
 src/qemu/libvirtd_qemu.aug |  6 ++
 src/qemu/qemu.conf | 39 ++
 src/qemu/qemu_conf.c   |  2 ++
 src/qemu/qemu_conf.h   |  5 +
 src/qemu/test_libvirtd_qemu.aug.in |  4 
 5 files changed, 56 insertions(+)

diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index 82bae9e..18679c1 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -54,6 +54,11 @@ module Libvirtd_qemu =
  | bool_entry "chardev_tls_x509_verify"
  | str_entry "chardev_tls_x509_secret_uuid"
 
+   let migrate_entry = bool_entry "migrate_tls"
+ | str_entry "migrate_tls_x509_cert_dir"
+ | bool_entry "migrate_tls_x509_verify"
+ | str_entry "migrate_tls_x509_secret_uuid"
+
let nogfx_entry = bool_entry "nographics_allow_host_audio"
 
let remote_display_entry = int_entry "remote_display_port_min"
@@ -116,6 +121,7 @@ module Libvirtd_qemu =
  | vnc_entry
  | spice_entry
  | chardev_entry
+ | migrate_entry
  | nogfx_entry
  | remote_display_entry
  | security_entry
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 9f990c2..c4e228b 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -238,6 +238,45 @@
 #chardev_tls_x509_secret_uuid = "----"
 
 
+# Enable use of TLS encryption for migration
+#
+# It is necessary to setup CA and issue a server certificate
+# before enabling this.
+#
+#migrate_tls = 1
+
+
+# In order to override the default TLS certificate location for migration
+# certificates, supply a valid path to the certificate directory. If the
+# provided path does not exist then the default_tls_x509_cert_dir path
+# will be used.
+#
+#migrate_tls_x509_cert_dir = "/etc/pki/libvirt-migrate"
+
+
+# The default TLS configuration only uses certificates for the server
+# allowing the client to verify the server's identity and establish
+# an encrypted channel.
+#
+# It is possible to use x509 certificates for authentication too, by
+# issuing a x509 certificate to every client who needs to connect.
+#
+# Enabling this option will reject any client who does not have a
+# certificate signed by the CA in /etc/pki/libvirt-migrate/ca-cert.pem
+#
+#migrate_tls_x509_verify = 1
+
+
+# Uncomment and use the following option to override the default secret
+# UUID provided in the default_tls_x509_secret_uuid parameter.
+#
+# NB This default all-zeros UUID will not work. Replace it with the
+# output from the UUID for the TLS secret from a 'virsh secret-list'
+# command and then uncomment the entry
+#
+#migrate_tls_x509_secret_uuid = "----"
+
+
 # By default, if no graphical front end is configured, libvirt will disable
 # QEMU audio output since directly talking to alsa/pulseaudio may not work
 # with various security settings. If you know what you're doing, enable
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index b75cd54..f63d9c2 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -555,6 +555,8 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 
 GET_CONFIG_TLS_CERT(chardev);
 
+GET_CONFIG_TLS_CERT(migrate);
+
 #undef GET_CONFIG_TLS_CERT
 
 if (virConfGetValueUInt(conf, "remote_websocket_port_min", 
&cfg->webSocketPortMin) < 0)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index e585f81..ac7badb 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -137,6 +137,11 @@ struct _virQEMUDriverConfig {
 bool chardevTLSx509verify;
 char *chardevTLSx509secretUUID;
 
+bool migrateTLS;
+char *migrateTLSx509certdir;
+bool migrateTLSx509verify;
+char *migrateTLSx509secretUUID;
+
 unsigned int remotePortMin;
 unsigned int remotePortMax;
 
diff --git a/src/qemu/test_libvirtd_qemu.aug.in 
b/src/qemu/test_libvirtd_qemu.aug.in
index 6f03898..71ddf7d 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -25,6 +25,10 @@ module Test_libvirtd_qemu =
 { "chardev_tls_x509_cert_dir" = "/etc/pki/libvirt-chardev" }
 { "chardev_tls_x509_verify" = "1" }
 { "chardev_tls_x509_secret_uuid" = "----" }
+{ "migrate_tls" = "1" }
+{ "migrate_tls_x509_cert_dir" = "/etc/pki/libvirt-migrate" }
+{ "migrate_tls_x509_verify" = "1" }
+{ "migrate_tls_x509_secret_uuid" = "----" }
 { "nographics_allow_host_audio" = "1" }
 { "remote_display_port_min" = "5900" }
 { "remote_display_port_max" = "65535" }
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
h

[libvirt] [PATCH v2 07/14] qemu: Move qemuDomainPrepareChardevSourceTLS call

2017-02-23 Thread John Ferlan
Move the call to inside the qemuDomainAddChardevTLSObjects in order to
further converge the code.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b59f3ab..d7a1f1f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1646,7 +1646,6 @@ qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr cfg,
 static int
 qemuDomainAddChardevTLSObjects(virConnectPtr conn,
virQEMUDriverPtr driver,
-   virQEMUDriverConfigPtr cfg,
virDomainObjPtr vm,
virDomainChrSourceDefPtr dev,
char *devAlias,
@@ -1655,13 +1654,19 @@ qemuDomainAddChardevTLSObjects(virConnectPtr conn,
char **secAlias)
 {
 int ret = -1;
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virJSONValuePtr tlsProps = NULL;
 virJSONValuePtr secProps = NULL;
 
+/* NB: This may alter haveTLS based on cfg */
+qemuDomainPrepareChardevSourceTLS(dev, cfg);
+
 if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
-dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES)
-return 0;
+dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES) {
+ret = 0;
+goto cleanup;
+}
 
 if (qemuDomainSecretChardevPrepare(conn, cfg, priv, devAlias, dev) < 0)
 goto cleanup;
@@ -1680,6 +1685,7 @@ qemuDomainAddChardevTLSObjects(virConnectPtr conn,
  cleanup:
 virJSONValueFree(tlsProps);
 virJSONValueFree(secProps);
+virObjectUnref(cfg);
 
 return ret;
 }
@@ -1692,7 +1698,6 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 {
 int ret = -1;
 int rc;
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virDomainDefPtr def = vm->def;
 char *charAlias = NULL;
@@ -1703,8 +1708,6 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 bool need_release = false;
 virErrorPtr orig_err;
 
-qemuDomainPrepareChardevSourceTLS(redirdev->source, cfg);
-
 if (qemuAssignDeviceRedirdevAlias(def, redirdev, -1) < 0)
 goto cleanup;
 
@@ -1722,7 +1725,7 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 if (VIR_REALLOC_N(def->redirdevs, def->nredirdevs+1) < 0)
 goto cleanup;
 
-if (qemuDomainAddChardevTLSObjects(conn, driver, cfg, vm, redirdev->source,
+if (qemuDomainAddChardevTLSObjects(conn, driver, vm, redirdev->source,
redirdev->info.alias, charAlias,
&tlsAlias, &secAlias) < 0)
 goto audit;
@@ -1752,7 +1755,6 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 VIR_FREE(secAlias);
 VIR_FREE(charAlias);
 VIR_FREE(devstr);
-virObjectUnref(cfg);
 return ret;
 
  exit_monitor:
@@ -1935,7 +1937,6 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
   virDomainChrDefPtr chr)
 {
 int ret = -1, rc;
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virErrorPtr orig_err;
 virDomainDefPtr vmdef = vm->def;
@@ -1953,8 +1954,6 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 qemuDomainPrepareChannel(chr, priv->channelTargetDir) < 0)
 goto cleanup;
 
-qemuDomainPrepareChardevSourceTLS(dev, cfg);
-
 if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0)
 goto cleanup;
 
@@ -1980,7 +1979,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 if (qemuDomainChrPreInsert(vmdef, chr) < 0)
 goto cleanup;
 
-if (qemuDomainAddChardevTLSObjects(conn, driver, cfg, vm, dev,
+if (qemuDomainAddChardevTLSObjects(conn, driver, vm, dev,
chr->info.alias, charAlias,
&tlsAlias, &secAlias) < 0)
 goto audit;
@@ -2016,7 +2015,6 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 VIR_FREE(secAlias);
 VIR_FREE(charAlias);
 VIR_FREE(devstr);
-virObjectUnref(cfg);
 return ret;
 
  exit_monitor:
@@ -2041,7 +2039,6 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
   virDomainObjPtr vm,
   virDomainRNGDefPtr rng)
 {
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_RNG, { .rng = rng } };
 virErrorPtr orig_err;
@@ -2102,9 +2099,6 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
 goto cleanup;
 teardowncgroup = true;
 
-if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD)
-qemuDomainPrepareChardevSourceTLS(rng->source.chardev, cfg);
-
 /* b

[libvirt] [PATCH v2 03/14] qemu: Move exit monitor calls in failure paths

2017-02-23 Thread John Ferlan
Since qemuDomainObjExitMonitor can also generate error messages,
let's move it inside any error message saving code on error paths
for various hotplug add activities.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 97fb272..9e2f04b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -442,13 +442,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
 ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
 if (encobjAdded)
 ignore_value(qemuMonitorDelObject(priv->mon, encinfo->s.aes.alias));
+if (qemuDomainObjExitMonitor(driver, vm) < 0)
+releaseaddr = false;
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-if (qemuDomainObjExitMonitor(driver, vm) < 0)
-releaseaddr = false;
 
 virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
@@ -728,13 +728,12 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
 ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
 if (encobjAdded)
 ignore_value(qemuMonitorDelObject(priv->mon, encinfo->s.aes.alias));
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-ignore_value(qemuDomainObjExitMonitor(driver, vm));
-
 virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
@@ -822,12 +821,12 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr 
driver,
 VIR_WARN("Unable to remove drive %s (%s) after failed "
  "qemuMonitorAddDevice", drivealias, drivestr);
 }
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-ignore_value(qemuDomainObjExitMonitor(driver, vm));
 virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
@@ -1676,11 +1675,11 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
 if (secobjAdded)
 ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
-ignore_value(qemuDomainObjExitMonitor(driver, vm));
 goto audit;
 }
 
@@ -1970,12 +1969,12 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
 if (secobjAdded)
 ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-ignore_value(qemuDomainObjExitMonitor(driver, vm));
 goto audit;
 }
 
@@ -2156,13 +2155,13 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
 ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
 if (secobjAdded)
 ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
+if (qemuDomainObjExitMonitor(driver, vm) < 0)
+releaseaddr = false;
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-if (qemuDomainObjExitMonitor(driver, vm) < 0)
-releaseaddr = false;
 goto audit;
 }
 
@@ -2276,14 +2275,14 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
 orig_err = virSaveLastError();
 if (objAdded)
 ignore_value(qemuMonitorDelObject(priv->mon, objalias));
-if (orig_err) {
-virSetError(orig_err);
-virFreeError(orig_err);
-}
 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
 mem = NULL;
 goto audit;
 }
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
 
  removedef:
 if ((id = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
@@ -2506,12 +2505,12 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
  "qemuMonitorAddDevice",
  drvstr, devstr);
 }
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-ignore_value(qemuDomainObjExitMonitor(driver, vm));
 virDomainAuditHostdev(vm, hostdev, "attach", false);
 
 goto cleanup;
@@ -2798,14 +2797,14 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver,
 ignore_value(qemuMonitorDelObject(priv->mon, memAlias));
 }
 
+if (qemuDomainObjExitMonitor(driver, vm) < 0)
+release_address = false;
+
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
 
-if (qemuDomainObjExitMonitor(driver, vm) < 0)
-release_address = false;
-
 goto audit;
 }
 
-- 
2.9.3

--
libvir-list mailing list
libv

[libvirt] [PATCH v2 00/14] Add TLS support for migration

2017-02-23 Thread John Ferlan
v1: http://www.redhat.com/archives/libvir-list/2017-February/msg00897.html
v1 cover letter reiterated:

Patches 1, 3 -> 9 are primarily quite a bit of code motion in order to allow
reuse of the "core" of the chardev TLS code.

Theoretically speaking of course, these patches should work - I don't
have a TLS and migration environment to test with, so between following
the qemu command model on Daniel's blog and prior experience with the
chardev TLS would 

I added the saving of a flag to the private qemu domain state, although
I'm not 100% sure it was necessary. At one time I created the source TLS
objects during the Begin phase, but later decided to wait until just
before the migration is run. I think the main reason to have the flag
would be a restart of libvirtd to let 'something' know migration using
TLS was configured. I think it may only be "necessary" in order to
repopulate the migSecinfo after libvirtd restart, but it's not entirely
clear. By the time I started thinking more about while writing this cover
letter it was too late to just remove.

Also rather than create the destination host TLS objects on the fly,
I modified the command line generation. That model could change to adding
the TLS objects once the destination is started and before the params are
set for the migration.

This 'model' is also going to be used for the NBD, but I figured I'd get
this posted now since it was already too long of a series.


v2: Changes

Reorder the patches to put the reused 'chardev' code up front. Most of
these patches were "ok" along the way, but only one was officially ACK'd
(and that was pushed).

Patch1 is new - based off code review comment to create a common New
   function for secinfo allocation
Patch2 is adjusted to use Patch1
Patch3 is new based on review comment and having ExitMonitor outside
   the virSaveLastError ... virSetError
Patch4 mainly follows older logic with adjustments as suggested during
   code review
Patch5 -> Patch8 had minor changes as a result of other suggestions
Patch9 just removed the _set logic
Patch10 fixed the order/placement of VIR_MIGRATE_TLS
Patch11 is the old patch1 w/ the fixed #undef
Patch12 is the old patch2 w/o changes
Patch13 Alters the server logic to create the objects on the fly rather
that via command line. It also introduces 3 helpers to perform the
migration TLS manipulation
Patch14 similarly uses those API's

AFAIU - removal of the objects would remove the migration tls-creds,
tls-hostname settings.

NB:
I left the cfg->migrateTLS in for now - it's very simple to remove, but
there would still need to be a key on something to ensure the migrateTLS
environment has been properly configured since that would mean the default
environment would need to be used/configured. Setting up the default
environment is keyed off having the migrateTLS defined. That's all part
of the qemu_conf reading logic.

John Ferlan (14):
  qemu: Introduce qemuDomainSecretInfoNew
  qemu: Introduce qemuDomainSecretMigratePrepare
  qemu: Move exit monitor calls in failure paths
  qemu: Refactor hotplug to introduce qemuDomain{Add|Del}TLSObjects
  qemu: Refactor qemuDomainGetChardevTLSObjects to converge code
  qemu: Move qemuDomainSecretChardevPrepare call
  qemu: Move qemuDomainPrepareChardevSourceTLS call
  qemu: Introduce qemuDomainGetTLSObjects
  qemu: Add TLS params to _qemuMonitorMigrationParams
  Add new migration flag VIR_MIGRATE_TLS
  qemu: Create #define for TLS configuration setup.
  conf: Introduce migrate_tls_x509_cert_dir
  qemu: Set up the migrate TLS objects for target
  qemu: Set up the migration TLS objects for source

 include/libvirt/libvirt-domain.h   |   8 +
 src/qemu/libvirtd_qemu.aug |   6 +
 src/qemu/qemu.conf |  39 +
 src/qemu/qemu_conf.c   |  45 +++--
 src/qemu/qemu_conf.h   |   5 +
 src/qemu/qemu_domain.c | 195 +
 src/qemu/qemu_domain.h |  89 ++
 src/qemu/qemu_hotplug.c| 343 -
 src/qemu/qemu_hotplug.h|  24 +++
 src/qemu/qemu_migration.c  | 200 +
 src/qemu/qemu_migration.h  |   3 +-
 src/qemu/qemu_monitor.c|  11 +-
 src/qemu/qemu_monitor.h|   3 +
 src/qemu/qemu_monitor_json.c   |  10 ++
 src/qemu/test_libvirtd_qemu.aug.in |   4 +
 tools/virsh-domain.c   |   7 +
 16 files changed, 705 insertions(+), 287 deletions(-)

-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 01/14] qemu: Introduce qemuDomainSecretInfoNew

2017-02-23 Thread John Ferlan
Create a helper which will create the secinfo used for disks, hostdevs,
and chardevs.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_domain.c | 140 ++---
 1 file changed, 74 insertions(+), 66 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c187214..b7594b3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1112,6 +1112,55 @@ qemuDomainSecretSetup(virConnectPtr conn,
 }
 
 
+/* qemuDomainSecretInfoNew:
+ * @conn: Pointer to connection
+ * @priv: pointer to domain private object
+ * @srcAlias: Alias base to use for TLS object
+ * @lookupType: Type of secret lookup
+ * @username: username for plain secrets
+ * @looupdef: lookup def describing secret
+ * @isLuks: boolean for luks lookup
+ * @encFmt: string for error message
+ *
+ * Helper function to create a secinfo to be used for secinfo consumers
+ *
+ * Returns @secinfo on success, NULL on failure. Caller is responsible
+ * to eventually free @secinfo.
+ */
+static qemuDomainSecretInfoPtr
+qemuDomainSecretInfoNew(virConnectPtr conn,
+qemuDomainObjPrivatePtr priv,
+const char *srcAlias,
+virSecretLookupType lookupType,
+const char *username,
+virSecretLookupTypeDefPtr lookupDef,
+bool isLuks,
+const char *encFmt)
+{
+qemuDomainSecretInfoPtr secinfo = NULL;
+
+if (VIR_ALLOC(secinfo) < 0)
+return NULL;
+
+if (qemuDomainSecretSetup(conn, priv, secinfo, srcAlias, lookupType,
+  username, lookupDef, isLuks) < 0)
+goto error;
+
+if (encFmt && secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("%s requires encrypted secrets to be supported"),
+   encFmt);
+goto error;
+}
+
+return secinfo;
+
+ error:
+qemuDomainSecretInfoFree(&secinfo);
+return NULL;
+}
+
+
 /* qemuDomainSecretDiskDestroy:
  * @disk: Pointer to a disk definition
  *
@@ -1171,51 +1220,30 @@ qemuDomainSecretDiskPrepare(virConnectPtr conn,
 {
 virStorageSourcePtr src = disk->src;
 qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
-qemuDomainSecretInfoPtr secinfo = NULL;
 
 if (qemuDomainSecretDiskCapable(src)) {
 virSecretUsageType secretUsageType = VIR_SECRET_USAGE_TYPE_ISCSI;
 
-if (VIR_ALLOC(secinfo) < 0)
-return -1;
-
 if (src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD)
 secretUsageType = VIR_SECRET_USAGE_TYPE_CEPH;
 
-if (qemuDomainSecretSetup(conn, priv, secinfo, disk->info.alias,
-  secretUsageType, src->auth->username,
-  &src->auth->seclookupdef, false) < 0)
-goto error;
-
-diskPriv->secinfo = secinfo;
+if (!(diskPriv->secinfo =
+  qemuDomainSecretInfoNew(conn, priv, disk->info.alias,
+  secretUsageType, src->auth->username,
+  &src->auth->seclookupdef, false, NULL)))
+  return -1;
 }
 
 if (qemuDomainDiskHasEncryptionSecret(src)) {
-
-if (VIR_ALLOC(secinfo) < 0)
-return -1;
-
-if (qemuDomainSecretSetup(conn, priv, secinfo, disk->info.alias,
-  VIR_SECRET_USAGE_TYPE_VOLUME, NULL,
-  &src->encryption->secrets[0]->seclookupdef,
-  true) < 0)
-goto error;
-
-if (secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("luks encryption requires encrypted secrets "
- "to be supported"));
-goto error;
-}
-
-diskPriv->encinfo = secinfo;
+if (!(diskPriv->encinfo =
+  qemuDomainSecretInfoNew(conn, priv, disk->info.alias,
+  VIR_SECRET_USAGE_TYPE_VOLUME, NULL,
+  
&src->encryption->secrets[0]->seclookupdef,
+  true, "luks encryption")))
+  return -1;
 }
 
 return 0;
-
- error:
-qemuDomainSecretInfoFree(&secinfo);
-return -1;
 }
 
 
@@ -1251,8 +1279,6 @@ qemuDomainSecretHostdevPrepare(virConnectPtr conn,
qemuDomainObjPrivatePtr priv,
virDomainHostdevDefPtr hostdev)
 {
-qemuDomainSecretInfoPtr secinfo = NULL;
-
 if (virHostdevIsSCSIDevice(hostdev)) {
 virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
 virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
@@ -1263,24 +1289,17 @@ qemuDomainSecretHostdevPrepare(virConnectPtr conn,

[libvirt] [PATCH v2 04/14] qemu: Refactor hotplug to introduce qemuDomain{Add|Del}TLSObjects

2017-02-23 Thread John Ferlan
Refactor the TLS object adding code to make two separate API's that will
handle the add/remove of the "secret" and "tls-creds-x509" objects including
the Enter/Exit monitor commands.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 165 +++-
 src/qemu/qemu_hotplug.h |  13 
 2 files changed, 107 insertions(+), 71 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9e2f04b..bb90a34 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1525,6 +1525,85 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 }
 
 
+void
+qemuDomainDelTLSObjects(virQEMUDriverPtr driver,
+virDomainObjPtr vm,
+const char *secAlias,
+const char *tlsAlias)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virErrorPtr orig_err;
+
+if (!tlsAlias && !secAlias)
+return;
+
+orig_err = virSaveLastError();
+
+qemuDomainObjEnterMonitor(driver, vm);
+
+if (tlsAlias)
+ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
+
+if (secAlias)
+ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
+
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
+
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
+}
+
+
+int
+qemuDomainAddTLSObjects(virQEMUDriverPtr driver,
+virDomainObjPtr vm,
+const char *secAlias,
+virJSONValuePtr *secProps,
+const char *tlsAlias,
+virJSONValuePtr *tlsProps)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+int rc;
+virErrorPtr orig_err;
+
+if (!tlsAlias && !secAlias)
+return 0;
+
+qemuDomainObjEnterMonitor(driver, vm);
+
+if (secAlias) {
+rc = qemuMonitorAddObject(priv->mon, "secret",
+  secAlias, *secProps);
+*secProps = NULL; /* qemuMonitorAddObject consumes */
+if (rc < 0)
+goto exit_monitor;
+}
+
+if (tlsAlias) {
+rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
+  tlsAlias, *tlsProps);
+*tlsProps = NULL; /* qemuMonitorAddObject consumes */
+if (rc < 0)
+goto exit_monitor;
+}
+
+return qemuDomainObjExitMonitor(driver, vm);
+
+ exit_monitor:
+orig_err = virSaveLastError();
+ignore_value(qemuDomainObjExitMonitor(driver, vm));
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
+qemuDomainDelTLSObjects(driver, vm, secAlias, tlsAlias);
+
+return -1;
+}
+
+
 static int
 qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr cfg,
qemuDomainObjPrivatePtr priv,
@@ -1581,8 +1660,6 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 char *charAlias = NULL;
 char *devstr = NULL;
 bool chardevAdded = false;
-bool tlsobjAdded = false;
-bool secobjAdded = false;
 virJSONValuePtr tlsProps = NULL;
 virJSONValuePtr secProps = NULL;
 char *tlsAlias = NULL;
@@ -1618,25 +1695,11 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
&secProps, &secAlias) < 0)
 goto cleanup;
 
-qemuDomainObjEnterMonitor(driver, vm);
-
-if (secAlias) {
-rc = qemuMonitorAddObject(priv->mon, "secret",
-  secAlias, secProps);
-secProps = NULL;
-if (rc < 0)
-goto exit_monitor;
-secobjAdded = true;
-}
+if (qemuDomainAddTLSObjects(driver, vm, secAlias, &secProps,
+tlsAlias, &tlsProps) < 0)
+goto audit;
 
-if (tlsAlias) {
-rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
-  tlsAlias, tlsProps);
-tlsProps = NULL; /* qemuMonitorAddObject consumes */
-if (rc < 0)
-goto exit_monitor;
-tlsobjAdded = true;
-}
+qemuDomainObjEnterMonitor(driver, vm);
 
 if (qemuMonitorAttachCharDev(priv->mon,
  charAlias,
@@ -1671,15 +1734,12 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 /* detach associated chardev on error */
 if (chardevAdded)
 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
-if (tlsobjAdded)
-ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
-if (secobjAdded)
-ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
 ignore_value(qemuDomainObjExitMonitor(driver, vm));
 if (orig_err) {
 virSetError(orig_err);
 virFreeError(orig_err);
 }
+qemuDomainDelTLSObjects(driver, vm, secAlias, tlsAlias);
 goto audit;
 }
 
@@ -1857,10 +1917,8 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
 virDomainChrSourceDefPtr dev = chr->source;
 ch

[libvirt] [PATCH v2 1/2] tests: Sync tests between qemuxml2argv and qemuxml2xml

2017-02-23 Thread Andrea Bolognani
In some cases, only one of the two transformations was
checked; in other cases, the capabilities set differed.
---
Note that the input file for the "pci-bridge" test case
had to be changed to make it usable for qemuxml2argv.

 .../qemuxml2argvdata/qemuxml2argv-pci-bridge.args  |  90 +
 tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.xml |  97 +++---
 .../qemuxml2argv-vcpu-placement-static.args|  20 ++
 tests/qemuxml2argvtest.c   |  74 ---
 .../qemuxml2xmlout-boot-floppy-q35.xml |  32 +++
 .../qemuxml2xmlout-bootindex-floppy-q35.xml|  32 +++
 .../qemuxml2xmlout-intel-iommu-machine.xml |  26 +++
 .../qemuxml2xmlout-pci-bridge.xml  |  98 --
 .../qemuxml2xmloutdata/qemuxml2xmlout-pci-many.xml | 214 +
 ...qemuxml2xmlout-video-device-pciaddr-default.xml |  51 +
 tests/qemuxml2xmltest.c| 154 +++
 11 files changed, 697 insertions(+), 191 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-vcpu-placement-static.args
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-boot-floppy-q35.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-bootindex-floppy-q35.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-intel-iommu-machine.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-many.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-video-device-pciaddr-default.xml

diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.args 
b/tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.args
new file mode 100644
index 000..d1d51b3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.args
@@ -0,0 +1,90 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/libexec/qemu-kvm \
+-name fdr-br \
+-S \
+-M pc-1.2 \
+-m 2048 \
+-smp 2,sockets=2,cores=1,threads=1 \
+-uuid 3ec6cbe1-b5a2-4515-b800-31a61855df41 \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-fdr-br/monitor.sock,server,nowait \
+-boot c \
+-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x3 \
+-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.0,addr=0x4 \
+-usb \
+-drive file=/var/iso/f18kde.iso,format=raw,if=none,media=cdrom,\
+id=drive-ide0-1-0,readonly=on \
+-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
+-device rtl8139,vlan=0,id=net0,mac=52:54:00:f1:95:51,bus=pci.0,addr=0x5 \
+-net user,vlan=0,name=hostnet0 \
+-device e1000,vlan=1,id=net1,mac=52:54:00:5c:c6:1a,bus=pci.0,addr=0x7 \
+-net user,vlan=1,name=hostnet1 \
+-device e1000,vlan=2,id=net2,mac=52:54:00:39:97:ac,bus=pci.0,addr=0x8 \
+-net user,vlan=2,name=hostnet2 \
+-device e1000,vlan=3,id=net3,mac=52:54:00:45:28:cb,bus=pci.0,addr=0x9 \
+-net user,vlan=3,name=hostnet3 \
+-device e1000,vlan=4,id=net4,mac=52:54:00:ee:b9:a8,bus=pci.0,addr=0xa \
+-net user,vlan=4,name=hostnet4 \
+-device e1000,vlan=5,id=net5,mac=52:54:00:a9:f7:17,bus=pci.0,addr=0xb \
+-net user,vlan=5,name=hostnet5 \
+-device e1000,vlan=6,id=net6,mac=52:54:00:df:2b:f3,bus=pci.0,addr=0xc \
+-net user,vlan=6,name=hostnet6 \
+-device e1000,vlan=7,id=net7,mac=52:54:00:78:94:b4,bus=pci.0,addr=0xd \
+-net user,vlan=7,name=hostnet7 \
+-device e1000,vlan=8,id=net8,mac=52:54:00:6b:9b:06,bus=pci.0,addr=0xe \
+-net user,vlan=8,name=hostnet8 \
+-device e1000,vlan=9,id=net9,mac=52:54:00:17:df:bc,bus=pci.0,addr=0xf \
+-net user,vlan=9,name=hostnet9 \
+-device rtl8139,vlan=10,id=net10,mac=52:54:00:3b:d0:51,bus=pci.0,addr=0x10 \
+-net user,vlan=10,name=hostnet10 \
+-device e1000,vlan=11,id=net11,mac=52:54:00:8d:2d:17,bus=pci.0,addr=0x11 \
+-net user,vlan=11,name=hostnet11 \
+-device e1000,vlan=12,id=net12,mac=52:54:00:a7:66:af,bus=pci.0,addr=0x12 \
+-net user,vlan=12,name=hostnet12 \
+-device e1000,vlan=13,id=net13,mac=52:54:00:54:ab:d7,bus=pci.0,addr=0x13 \
+-net user,vlan=13,name=hostnet13 \
+-device e1000,vlan=14,id=net14,mac=52:54:00:1f:99:90,bus=pci.0,addr=0x14 \
+-net user,vlan=14,name=hostnet14 \
+-device e1000,vlan=15,id=net15,mac=52:54:00:c8:43:87,bus=pci.0,addr=0x15 \
+-net user,vlan=15,name=hostnet15 \
+-device e1000,vlan=16,id=net16,mac=52:54:00:df:22:b2,bus=pci.0,addr=0x16 \
+-net user,vlan=16,name=hostnet16 \
+-device e1000,vlan=17,id=net17,mac=52:54:00:d2:9a:47,bus=pci.0,addr=0x17 \
+-net user,vlan=17,name=hostnet17 \
+-device e1000,vlan=18,id=net18,mac=52:54:00:86:05:e2,bus=pci.0,addr=0x18 \
+-net user,vlan=18,name=hostnet18 \
+-device e1000,vlan=19,id=net19,mac=52:54:00:8c:1c:c2,bus=pci.0,addr=0x19 \
+-net user,vlan=19,name=hostnet19 \
+-device e1000,vlan=20,id=net20,mac=52:54:00:48:58:92,bus=pci.0,addr=0x1a \
+-net user,vlan=20,name=hostnet20 \
+-device e1000,vlan=21,id=net21,mac=52:54:00:99:e5:bf,bus=pci.0,addr=0x1b \
+-net user,vlan=21,name=hostnet21 \
+-device e1000,vlan=22,id=net22,mac=52:54:00:b1:8c:25,bus=pci.0,addr=0x1c \
+-net us

[libvirt] [PATCH v2 2/2] tests: Reduce QEMU_CAPS_DEVICE_{DMI_TO_, }PCI_BRIDGE usage

2017-02-23 Thread Andrea Bolognani
Now that QEMU_CAPS_DEVICE_PCI_BRIDGE is no longer checked
unless a pci-bridge is really part of the configuration,
and most uses of the legacy PCI controller combo have been
dropped from tests that use PCIe machine types, we can
drop the corresponding capabilities from a lot of test
cases.
---
 tests/qemuxml2argvtest.c | 55 
 tests/qemuxml2xmltest.c  | 28 
 2 files changed, 4 insertions(+), 79 deletions(-)

diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 1298ac6..6bae502 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -702,13 +702,9 @@ mymain(void)
 DO_TEST("boot-network", NONE);
 DO_TEST("boot-floppy", NONE);
 DO_TEST("boot-floppy-q35",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_ICH9_AHCI);
 DO_TEST("bootindex-floppy-q35",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_ICH9_AHCI, QEMU_CAPS_BOOT_MENU,
 QEMU_CAPS_BOOTINDEX);
@@ -1392,29 +1388,21 @@ mymain(void)
 DO_TEST_PARSE_ERROR("usb-none-usbtablet",
 QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG);
 DO_TEST("usb-controller-default-q35",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_PCI_OHCI,
 QEMU_CAPS_PIIX3_USB_UHCI,
 QEMU_CAPS_NEC_USB_XHCI);
 DO_TEST_FAILURE("usb-controller-default-unavailable-q35",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_PCI_OHCI,
 QEMU_CAPS_NEC_USB_XHCI);
 DO_TEST("usb-controller-explicit-q35",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_PCI_OHCI,
 QEMU_CAPS_PIIX3_USB_UHCI,
 QEMU_CAPS_NEC_USB_XHCI);
 DO_TEST_FAILURE("usb-controller-explicit-unavailable-q35",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_PCI_OHCI,
 QEMU_CAPS_PIIX3_USB_UHCI);
 DO_TEST("usb-controller-xhci",
@@ -1580,7 +1568,6 @@ mymain(void)
 QEMU_CAPS_OBJECT_MEMORY_FILE);
 DO_TEST("vcpu-placement-static",
 QEMU_CAPS_KVM,
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
 QEMU_CAPS_OBJECT_IOTHREAD);
 
 DO_TEST("numatune-memory", NONE);
@@ -1694,7 +1681,6 @@ mymain(void)
 DO_TEST("video-device-pciaddr-default",
 QEMU_CAPS_KVM,
 QEMU_CAPS_VNC,
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
 QEMU_CAPS_DEVICE_QXL);
 DO_TEST("video-vga-nodevice", QEMU_CAPS_DEVICE_VGA);
@@ -1808,13 +1794,10 @@ mymain(void)
 QEMU_CAPS_DEVICE_CIRRUS_VGA);
 DO_TEST("pci-autofill-addr", QEMU_CAPS_DEVICE_CIRRUS_VGA);
 DO_TEST("pci-many",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_CIRRUS_VGA);
 DO_TEST("pci-bridge-many-disks",
 QEMU_CAPS_DEVICE_PCI_BRIDGE);
 DO_TEST("pcie-root",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_ICH9_AHCI,
 QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
@@ -2029,8 +2012,6 @@ mymain(void)
 QEMU_CAPS_HDA_DUPLEX,
 QEMU_CAPS_USB_REDIR);
 DO_TEST("pcie-root-port",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_ICH9_AHCI,
 QEMU_CAPS_PCI_MULTIFUNCTION,
@@ -2055,8 +2036,6 @@ mymain(void)
 QEMU_CAPS_HDA_DUPLEX);
 
 DO_TEST_PARSE_ERROR("q35-wrong-root",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_ICH9_AHCI,
 QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
@@ -2065,16 +2044,12 @@ mymain(void)
 DO_TEST_PARSE_ERROR("440fx-wrong-root", NONE);
 
 DO_TEST_PARSE_ERROR("pcie-root-port-too-many",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_ICH9_AHCI,
 QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
 QEMU_CAPS_DEVICE_QXL);
 
 DO_TEST("pcie-switch-upstream-port",
-QEMU_CAPS_DEVICE_PCI_BRIDGE,
-QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
 QEMU_CAPS_DEVICE_IOH3420,
 QEMU_CAPS_DEVICE_X3130_UP

[libvirt] [PATCH v2 0/2] tests: Reduce QEMU_CAPS_DEVICE_{DMI_TO_, }PCI_BRIDGE usage

2017-02-23 Thread Andrea Bolognani
Changes from v1:

  * don't drop capabilities for a bunch of test cases,
so that potential regressions will be still caught.

Andrea Bolognani (2):
  tests: Sync tests between qemuxml2argv and qemuxml2xml
  tests: Reduce QEMU_CAPS_DEVICE_{DMI_TO_, }PCI_BRIDGE usage

 .../qemuxml2argvdata/qemuxml2argv-pci-bridge.args  |  90 +
 tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.xml |  97 +++---
 .../qemuxml2argv-vcpu-placement-static.args|  20 ++
 tests/qemuxml2argvtest.c   | 109 +--
 .../qemuxml2xmlout-boot-floppy-q35.xml |  32 +++
 .../qemuxml2xmlout-bootindex-floppy-q35.xml|  32 +++
 .../qemuxml2xmlout-intel-iommu-machine.xml |  26 +++
 .../qemuxml2xmlout-pci-bridge.xml  |  98 --
 .../qemuxml2xmloutdata/qemuxml2xmlout-pci-many.xml | 214 +
 ...qemuxml2xmlout-video-device-pciaddr-default.xml |  51 +
 tests/qemuxml2xmltest.c| 130 +
 11 files changed, 665 insertions(+), 234 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-vcpu-placement-static.args
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-boot-floppy-q35.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-bootindex-floppy-q35.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-intel-iommu-machine.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-many.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-video-device-pciaddr-default.xml

-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/5] util: virbuffer: introduce virBufferEscapeN

2017-02-23 Thread Daniel P. Berrange
On Thu, Feb 23, 2017 at 05:51:21PM +0100, Pavel Hrdina wrote:
> On Thu, Feb 23, 2017 at 04:32:32PM +, Daniel P. Berrange wrote:
> > On Thu, Feb 23, 2017 at 04:26:58PM +0100, Pavel Hrdina wrote:
> > > Signed-off-by: Pavel Hrdina 
> > > ---
> > >  src/libvirt_private.syms |   1 +
> > >  src/util/virbuffer.c | 104 
> > > +++
> > >  src/util/virbuffer.h |   2 +
> > >  tests/virbuftest.c   |  41 +++
> > >  4 files changed, 148 insertions(+)
> > > 
> > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > > index e9c4d73779..6ce32f1101 100644
> > > --- a/src/libvirt_private.syms
> > > +++ b/src/libvirt_private.syms
> > > @@ -1286,6 +1286,7 @@ virBufferContentAndReset;
> > >  virBufferCurrentContent;
> > >  virBufferError;
> > >  virBufferEscape;
> > > +virBufferEscapeN;
> > >  virBufferEscapeSexpr;
> > >  virBufferEscapeShell;
> > >  virBufferEscapeString;
> > > diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
> > > index d582e7dbec..ad6b29951e 100644
> > > --- a/src/util/virbuffer.c
> > > +++ b/src/util/virbuffer.c
> > > @@ -33,6 +33,7 @@
> > >  #include "virbuffer.h"
> > >  #include "viralloc.h"
> > >  #include "virerror.h"
> > > +#include "virstring.h"
> > >  
> > >  
> > >  /* If adding more fields, ensure to edit buf.h to match
> > > @@ -588,6 +589,109 @@ virBufferEscape(virBufferPtr buf, char escape, 
> > > const char *toescape,
> > >  VIR_FREE(escaped);
> > >  }
> > >  
> > > +
> > > +struct _virBufferEscapePair {
> > > +char escape;
> > > +char *toescape;
> > > +};
> > > +
> > > +
> > > +/**
> > > + * virBufferEscapeN:
> > > + * @buf: the buffer to append to
> > > + * @format: a printf like format string but with only one %s parameter
> > > + * @str: the string argument which needs to be escaped
> > > + * @...: the variable list of arguments composed
> > > + *
> > > + * The variable list of arguments @... must be composed of
> > > + * 'char escape, char *toescape' pairs followed by NULL.
> > 
> > So most of the complexity you have here is to deal with the ability
> > to turn a single character into a string of escaped characters. Unless
> > I'm missing something, you don't actually use that ability in practice.
> > If we make it more restrictive so you just have a 1-1 mapping we can
> > simplify the API & implementation. eg
> > 
> >   virBufferEscapeN(virBufferPtr buf,
> >const char *format,
> >const char *str,
> >const char *forbidden,
> >const char *replacements)
> > 
> > with strlen(forbidden) == strlen(replacements);
> 
> The idea was that a group of characters can be escaped with one character,
> so far the usage seems to be really simple.  Currently this would work and
> it would be really simple:
> 
> virBufferEscapeN(buf, "%s", str, ",=", ",\\");
> 
> but imagine this scenario:
> 
> virBufferEscapeN(buf, "%s", str, ",=%&*()", ",");
> 
> virBufferEscapeN(buf, "%s", str, ',', ",", '\\', "=%&*()", NULL);
> 
> I think that the second approach is better and easier for user of
> virBufferEscapeN.

Oh, that's the opposite way around to what I thought you were
doing ! I thought a single character could be escaped to a string
of multiple characters, but you have a string containing a set
of characters that must be escaped to a single character.


Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://entangle-photo.org   -o-http://search.cpan.org/~danberr/ :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/2] qemu: Validate the domain after marking the current domain as transient

2017-02-23 Thread Peter Krempa
On Thu, Feb 23, 2017 at 17:22:44 +0100, Marc Hartmayer wrote:
> On Thu, Feb 23, 2017 at 03:33 PM +0100, Michal Privoznik 
>  wrote:
> > On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
> >> Validate the domain that actually will be started. It's semantically
> >> more clear and also it can detect failures that may have happened in
> >> virDomainObjSetDefTransient().
> >>
> >> Signed-off-by: Marc Hartmayer 
> >> Reviewed-by: Bjoern Walk 
> >> Reviewed-by: Boris Fiuczynski 
> >> ---
> >>  src/qemu/qemu_process.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> >> index a57d136..bd3a8b8 100644
> >> --- a/src/qemu/qemu_process.c
> >> +++ b/src/qemu/qemu_process.c
> >> @@ -4746,9 +4746,6 @@ qemuProcessInit(virQEMUDriverPtr driver,
> >>
> >> vm->def->os.machine)))
> >>  goto cleanup;
> >>
> >> -if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) 
> >> < 0)
> >> -goto cleanup;
> >> -
> >>  /* Do this upfront, so any part of the startup process can add
> >>   * runtime state to vm->def that won't be persisted. This let's us
> >>   * report implicit runtime defaults in the XML, like vnc listen/socket
> >> @@ -4757,6 +4754,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
> >>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
> >>  goto cleanup;
> >>
> >> +if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) 
> >> < 0)
> >> +goto cleanup;
> >> +
> >
> > This needs to be goto stop for the reasons described in the previous e-mail.
> >
> >>  if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
> >>  if (qemuDomainSetPrivatePaths(driver, vm) < 0)
> >>  goto cleanup;
> >>
> >
> > Honestly, I like what we have now better. I mean, SetDefTransient() is
> > very unlikely to fail. It's just doing a copy of domain definition (in a
> > very stupid way, but lets save that for a different discussion).
> > Basically, it will fail on OOM only (which you will not get on a Linux
> > system, unless you really try).
> 
> It's semantically more clear (at least for me) and for example it
> enables us to change some parts of the transient domain before
> validation (affect the transient domain only, not the persistent).

That does not make much sense. If you are changing the definition the
code doing so should make sure that it does not create an invalid
configuration rather than depending on the validation code.


signature.asc
Description: PGP signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 08/28] qemu: Store more types in qemuMonitorCPUModelInfo

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:06PM +0100, Jiri Denemark wrote:
> While query-cpu-model-expansion returns only boolean features on s390,
> but x86_64 reports some integer and string properties which we are
> interested in.
> 
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - change the XML element to
> 
> 
> Version 2:
> - no change
> 
>  src/qemu/qemu_capabilities.c | 100 
> +--
>  src/qemu/qemu_monitor.c  |  25 +-
>  src/qemu/qemu_monitor.h  |  27 +-
>  src/qemu/qemu_monitor_json.c |  42 --
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml |   7 ++
>  5 files changed, 163 insertions(+), 38 deletions(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index e037d5f95..0b611c323 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -3076,14 +3076,16 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
>  cpu->nfeatures = 0;
>  
>  for (i = 0; i < modelInfo->nprops; i++) {
> -if (VIR_STRDUP(cpu->features[i].name, modelInfo->props[i].name) < 0)
> +virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
> +qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
> +
> +if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
> +continue;
> +
> +if (VIR_STRDUP(feature->name, prop->name) < 0)
>  return -1;
> -
> -if (modelInfo->props[i].supported)
> -cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE;
> -else
> -cpu->features[i].policy = VIR_CPU_FEATURE_DISABLE;
> -
> +feature->policy = prop->value.boolean ? VIR_CPU_FEATURE_REQUIRE
> +  : VIR_CPU_FEATURE_DISABLE;
>  cpu->nfeatures++;
>  }
>  
> @@ -3189,30 +3191,59 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsPtr 
> qemuCaps,
>  hostCPU->nprops = n;
>  
>  for (i = 0; i < n; i++) {
> -hostCPU->props[i].name = virXMLPropString(nodes[i], "name");
> -if (!hostCPU->props[i].name) {
> +qemuMonitorCPUPropertyPtr prop = hostCPU->props + i;
> +int type;
> +
> +ctxt->node = nodes[i];
> +
> +if (!(prop->name = virXMLPropString(ctxt->node, "name"))) {
>  virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> _("missing 'name' attribute for a host CPU"
>   " model property in QEMU capabilities 
> cache"));
>  goto cleanup;
>  }
>  
> -if (!(str = virXMLPropString(nodes[i], "value"))) {
> +if (!(str = virXMLPropString(ctxt->node, "type")) ||
> +(type = qemuMonitorCPUPropertyTypeFromString(str)) < 0) {
>  virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> -   _("missing 'value' attribute for a host CPU"
> - " model property in QEMU capabilities 
> cache"));
> -goto cleanup;
> -}
> -if (STREQ(str, "true")) {
> -hostCPU->props[i].supported = true;
> -} else if (STREQ(str, "false")) {
> -hostCPU->props[i].supported = false;
> -} else {
> -virReportError(VIR_ERR_INTERNAL_ERROR,
> -   _("invalid boolean  value: '%s'"), str);
> +   _("missing CPU model property type in QEMU "
> + "capabilities cache"));

There should be a different error message for the case when type is missing
and when the type is unknown.  Or just modify the error message to cover both
cases.

ACK with that fixed.

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 4/4] Add ATTRIBUTE_FALLTHROUGH for switch cases without break

2017-02-23 Thread Daniel P. Berrange
On Thu, Feb 23, 2017 at 09:07:59PM +0400, Roman Bogorodskiy wrote:
>   Daniel P. Berrange wrote:
> 
> > On Wed, Feb 22, 2017 at 05:52:05PM +, Daniel P. Berrange wrote:
> > > In GCC 7 there is a new warning triggered when a switch
> > > case has a conditional statement (eg if ... else...) and
> > > some of the code paths fallthrough to the next switch
> > > statement. e.g.
> > > 
> > > conf/domain_conf.c: In function 'virDomainChrEquals':
> > > conf/domain_conf.c:14926:12: error: this statement may fall through 
> > > [-Werror=implicit-fallthrough=]
> > >  if (src->targetTypeAttr != tgt->targetTypeAttr)
> > > ^
> > > conf/domain_conf.c:14928:5: note: here
> > >  case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
> > >  ^~~~
> > > conf/domain_conf.c: In function 'virDomainChrDefFormat':
> > > conf/domain_conf.c:22143:12: error: this statement may fall through 
> > > [-Werror=implicit-fallthrough=]
> > >  if (def->targetTypeAttr) {
> > > ^
> > > conf/domain_conf.c:22151:5: note: here
> > >  default:
> > >  ^~~
> > > 
> > > GCC introduced a __attribute__((fallthrough)) to let you
> > > indicate that this is intentionale behaviour rather than
> > > a bug.
> > 
> > 
> > BTW, CLang has apparently had an -Wimplicit-fallthrough
> > warning flag for a while, and also seems to have the same
> > __attribute__((fallthrough)), but I've been unable to get
> > CLang to trigger such warnings, and hence did not enable
> > __attribute__((fallthrough)) on CLang. If someone can
> > figure out how to reproduce the warnings on clang we
> > could extend internal.h to surpress them for whichever
> > clang version introduced the warnings. As is, the
> > ATTRIBUTE_FALLTHROUGH turns into a no-op for CLang unless
> > it claims GCC 7.0 compatibility.
> 
> It *looks* like -Wimplicit-fallthrough in clang is only effective for
> C++11:
> 
> http://clang-developers.42468.n3.nabble.com/should-Wimplicit-fallthrough-require-C-11-td4028144.html
> 
> It mentions this commit:
> 
> http://llvm.org/viewvc/llvm-project?revision=167655&view=revision
> 
> And it seems it wasn't changed since than.

Ah I see. So they disabled it for C, because their [[clang::fallthrough]]
magic annotation would not work under C. Hopefully they'll enable it one
day with the more normal  __attribute__((fallthrough)) syntax for C.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://entangle-photo.org   -o-http://search.cpan.org/~danberr/ :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 02/13] conf: Introduce migrate_tls_x509_cert_dir

2017-02-23 Thread John Ferlan


On 02/23/2017 09:19 AM, Jiri Denemark wrote:
> On Thu, Feb 23, 2017 at 08:10:18 -0500, John Ferlan wrote:
>>
>>
>> On 02/21/2017 06:43 AM, Jiri Denemark wrote:
>>> On Mon, Feb 20, 2017 at 14:28:42 -0500, John Ferlan wrote:
 On 02/20/2017 11:03 AM, Jiri Denemark wrote:
> On Fri, Feb 17, 2017 at 14:39:19 -0500, John Ferlan wrote:
>> +# Enable use of TLS encryption for migration
>> +#
>> +# It is necessary to setup CA and issue a server certificate
>> +# before enabling this.
>> +#
>> +#migrate_tls = 1
>
> Actually what is this option supposed to do? It seems it doesn't do
> anything but saying "yes, I configured TLS for migration". The TLS usage
> for migration is turned on by VIR_MIGRATE_TLS flag which suggests the
> configuration option here is useless.

 It more or less follows the same logic for chardev's which got an
 additional 'tls="yes"' to allow one to enable/disable an object in a
 domain on a case by case basis if chardev tls was enabled for the host.

 See: http://libvirt.org/formatdomain.html#elementsConsole

 and search down for 'tls'

 So my feeling while coding was - if I don't supply some sort of way to
 have an option to allow someone to choose to use the configured TLS
 environment for the migration, I'd end up being asked to add one since
 chardev has it.
>>>
>>> The problem is chardevs and migration are quite different. While you can
>>> easily have a default configuration for chardevs and use tls="yes|no" to
>>> override it (no tls attribute will just tell libvirt to use the
>>> default), it's not really possible with migration API. API flags have
>>> not two states (in contrast to three-state boolean attributes in XML).
>>> Setting VIR_MIGRATE_TLS flag turns TLS on and using the flag turns TLS
>>> off. That is the default value is not used anywhere. If VIR_MIGRATE_TLS
>>> flag is used, the code checks migrate_tls is 1. Which translates to
>>> "yes, I configured TLS for migration" semantics of the configuration
>>> option.
>>>
>>> In other words, it makes sense to have the configuration option for
>>> devices defined in the XML, but using it for migration doesn't make any
>>> sense. This would of course mean its parsing would need to be moved out
>>> of the macro introduced in 1/13 and used for chardevs only.
>>>
>>> Jirka
>>>
>>
>> So I've circled back around to this...  It seems like you're advocating
>> the removal of the VIR_MIGRATE_TLS flag - which is fine.  The only
> 
> No. We definitely need VIR_MIGRATE_TLS. I'm advocating the removal of
> the migrate_tls configuration option.
> 
> Jirka
> 

For me it's a consistency thing - whenever TLS is used elsewhere in the
code the qemu.conf variables are referenced. Now for migration we're
going to assume the configuration is set up and can be used.  That just
seems odd, but if that's how it's felt we should proceed, then fine I
can drop the migrate_tls variable, the others would seem to be needed
though.  That just means the first patch is dropped and the second one
removes the migrate_tls, but keeps certDir, verify, and secret uuid.

John

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 07/28] qemu: Prepare for more types in qemuMonitorCPUModelInfo

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:05PM +0100, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - new patch
> 
>  src/qemu/qemu_capabilities.c |  14 +-
>  tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml  |  30 +--
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 322 
> +++
>  3 files changed, 183 insertions(+), 183 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 06/28] qemu: Rename hostCPU/feature element in capabilities cache

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:04PM +0100, Jiri Denemark wrote:
> The element will be generalized in the following commits.
> 
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - s/featureNodes/nodes/
> - drop s/supported/boolean/ change
> 
> Version 2:
> - no change
> 
>  src/qemu/qemu_capabilities.c |  16 +-
>  tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml  |  30 +--
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 322 
> +++
>  3 files changed, 184 insertions(+), 184 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 05/28] docs: Update description of the host-model CPU mode

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:03PM +0100, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - reworded and updated documentation
> 
> Version 2:
> - no change
> 
>  docs/formatdomain.html.in | 37 -
>  1 file changed, 24 insertions(+), 13 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 4/4] Add ATTRIBUTE_FALLTHROUGH for switch cases without break

2017-02-23 Thread Roman Bogorodskiy
  Daniel P. Berrange wrote:

> On Wed, Feb 22, 2017 at 05:52:05PM +, Daniel P. Berrange wrote:
> > In GCC 7 there is a new warning triggered when a switch
> > case has a conditional statement (eg if ... else...) and
> > some of the code paths fallthrough to the next switch
> > statement. e.g.
> > 
> > conf/domain_conf.c: In function 'virDomainChrEquals':
> > conf/domain_conf.c:14926:12: error: this statement may fall through 
> > [-Werror=implicit-fallthrough=]
> >  if (src->targetTypeAttr != tgt->targetTypeAttr)
> > ^
> > conf/domain_conf.c:14928:5: note: here
> >  case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
> >  ^~~~
> > conf/domain_conf.c: In function 'virDomainChrDefFormat':
> > conf/domain_conf.c:22143:12: error: this statement may fall through 
> > [-Werror=implicit-fallthrough=]
> >  if (def->targetTypeAttr) {
> > ^
> > conf/domain_conf.c:22151:5: note: here
> >  default:
> >  ^~~
> > 
> > GCC introduced a __attribute__((fallthrough)) to let you
> > indicate that this is intentionale behaviour rather than
> > a bug.
> 
> 
> BTW, CLang has apparently had an -Wimplicit-fallthrough
> warning flag for a while, and also seems to have the same
> __attribute__((fallthrough)), but I've been unable to get
> CLang to trigger such warnings, and hence did not enable
> __attribute__((fallthrough)) on CLang. If someone can
> figure out how to reproduce the warnings on clang we
> could extend internal.h to surpress them for whichever
> clang version introduced the warnings. As is, the
> ATTRIBUTE_FALLTHROUGH turns into a no-op for CLang unless
> it claims GCC 7.0 compatibility.

It *looks* like -Wimplicit-fallthrough in clang is only effective for
C++11:

http://clang-developers.42468.n3.nabble.com/should-Wimplicit-fallthrough-require-C-11-td4028144.html

It mentions this commit:

http://llvm.org/viewvc/llvm-project?revision=167655&view=revision

And it seems it wasn't changed since than.

Roman Bogorodskiy


signature.asc
Description: PGP signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 03/28] qemu: Refactor virQEMUCapsInitHostCPUModel

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:01PM +0100, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - no change
> 
> Version 2:
> - no change
> 
>  src/qemu/qemu_capabilities.c | 109 
> ++-
>  1 file changed, 55 insertions(+), 54 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] qemuProcessInit: Jump onto correct label in case of error

2017-02-23 Thread Michal Privoznik
On 02/23/2017 05:40 PM, Marc Hartmayer wrote:
> On Thu, Feb 23, 2017 at 05:15 PM +0100, Michal Privoznik 
>  wrote:
>> After eca76884ea in case of error in qemuDomainSetPrivatePaths()
>> in pretended start we jump to stop. I've changed this during
>> review from 'cleanup' which turned out to be correct. Well, sort
>> of. We can't call qemuProcessStop() as it decrements
>> driver->nactive and we did not increment it. However, it calls
>> virDomainObjRemoveTransientDef() which is basically the only
>> function we need to call. So call that function and goto cleanup;
>>
>> Signed-off-by: Michal Privoznik 
>> ---
>>  src/qemu/qemu_process.c | 6 --
>>  1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>> index df1fa0371..9306e0e18 100644
>> --- a/src/qemu/qemu_process.c
>> +++ b/src/qemu/qemu_process.c
>> @@ -4758,8 +4758,10 @@ qemuProcessInit(virQEMUDriverPtr driver,
>>  goto cleanup;
>>
>>  if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
>> -if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>> -goto stop;
>> +if (qemuDomainSetPrivatePaths(driver, vm) < 0) {
>> +virDomainObjRemoveTransientDef(vm);
> 
> I'm not sure if this is needed (I think every caller of qemuProcessInit
> will unref/free @vm/the transient domain in case of returning -1) but at
> least it's not wrong and probably more safe :)

The idea that we try to honour is to whomever allocated the memory,
should be also the one who frees it. I'm not saying that we do it all
the time at all places. In fact I'd say in some areas of the code we are
far from that. But a) we can blame historic reasons, b) sometimes it's
not as easy to follow the idea as 1 2 3.
In general, following this rule means that if a function fails, it
hasn't left any side effects on the object and basically was NO-OP.
But here, none of the above reasons stands. So I think we should free it
here regardless of what caller does afterwards.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/5] util: virbuffer: introduce virBufferEscapeN

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 04:32:32PM +, Daniel P. Berrange wrote:
> On Thu, Feb 23, 2017 at 04:26:58PM +0100, Pavel Hrdina wrote:
> > Signed-off-by: Pavel Hrdina 
> > ---
> >  src/libvirt_private.syms |   1 +
> >  src/util/virbuffer.c | 104 
> > +++
> >  src/util/virbuffer.h |   2 +
> >  tests/virbuftest.c   |  41 +++
> >  4 files changed, 148 insertions(+)
> > 
> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > index e9c4d73779..6ce32f1101 100644
> > --- a/src/libvirt_private.syms
> > +++ b/src/libvirt_private.syms
> > @@ -1286,6 +1286,7 @@ virBufferContentAndReset;
> >  virBufferCurrentContent;
> >  virBufferError;
> >  virBufferEscape;
> > +virBufferEscapeN;
> >  virBufferEscapeSexpr;
> >  virBufferEscapeShell;
> >  virBufferEscapeString;
> > diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
> > index d582e7dbec..ad6b29951e 100644
> > --- a/src/util/virbuffer.c
> > +++ b/src/util/virbuffer.c
> > @@ -33,6 +33,7 @@
> >  #include "virbuffer.h"
> >  #include "viralloc.h"
> >  #include "virerror.h"
> > +#include "virstring.h"
> >  
> >  
> >  /* If adding more fields, ensure to edit buf.h to match
> > @@ -588,6 +589,109 @@ virBufferEscape(virBufferPtr buf, char escape, const 
> > char *toescape,
> >  VIR_FREE(escaped);
> >  }
> >  
> > +
> > +struct _virBufferEscapePair {
> > +char escape;
> > +char *toescape;
> > +};
> > +
> > +
> > +/**
> > + * virBufferEscapeN:
> > + * @buf: the buffer to append to
> > + * @format: a printf like format string but with only one %s parameter
> > + * @str: the string argument which needs to be escaped
> > + * @...: the variable list of arguments composed
> > + *
> > + * The variable list of arguments @... must be composed of
> > + * 'char escape, char *toescape' pairs followed by NULL.
> 
> So most of the complexity you have here is to deal with the ability
> to turn a single character into a string of escaped characters. Unless
> I'm missing something, you don't actually use that ability in practice.
> If we make it more restrictive so you just have a 1-1 mapping we can
> simplify the API & implementation. eg
> 
>   virBufferEscapeN(virBufferPtr buf,
>const char *format,
>const char *str,
>const char *forbidden,
>const char *replacements)
> 
> with strlen(forbidden) == strlen(replacements);

The idea was that a group of characters can be escaped with one character,
so far the usage seems to be really simple.  Currently this would work and
it would be really simple:

virBufferEscapeN(buf, "%s", str, ",=", ",\\");

but imagine this scenario:

virBufferEscapeN(buf, "%s", str, ",=%&*()", ",");

virBufferEscapeN(buf, "%s", str, ',', ",", '\\', "=%&*()", NULL);

I think that the second approach is better and easier for user of
virBufferEscapeN.
 
> > + *
> > + * This has the same functionality as virBufferEscape with the extension
> > + * that allows to specify multiple pairs of chars that needs to be escaped.
> > + */
> > +void
> > +virBufferEscapeN(virBufferPtr buf,
> > + const char *format,
> > + const char *str,
> > + ...)
> > +{
> > +int len;
> > +size_t i;
> > +char escape;
> > +char *toescape;
> > +char *toescapeall = NULL;
> > +char *escaped = NULL;
> > +char *out;
> > +const char *cur;
> > +struct _virBufferEscapePair escapeItem;
> > +struct _virBufferEscapePair *escapeList = NULL;
> > +size_t nescapeList = 0;
> > +va_list ap;
> > +
> > +if ((format == NULL) || (buf == NULL) || (str == NULL))
> > +return;
> > +
> > +if (buf->error)
> > +return;
> > +
> > +va_start(ap, str);
> > +
> > +while ((escape = va_arg(ap, int))) {
> > +if (!(toescape = va_arg(ap, char *))) {
> > +virBufferSetError(buf, errno);
> > +goto cleanup;
> > +}
> > +
> > +escapeItem.escape = escape;
> > +escapeItem.toescape = toescape;
> > +
> > +if (VIR_STRCAT_QUIET(toescapeall, toescape) < 0) {
> > +virBufferSetError(buf, errno);
> > +goto cleanup;
> > +}
> > +
> > +if (VIR_APPEND_ELEMENT_QUIET(escapeList, nescapeList, escapeItem) 
> > < 0) {
> > +virBufferSetError(buf, errno);
> > +goto cleanup;
> > +}
> > +}
> 
> This whole loop would go away with the simpler API contract, which
> nicely avoids doing allocations in the loop body.
> 
> 
> > +len = strlen(str);
> > +if (strcspn(str, toescapeall) == len) {
> > +virBufferAsprintf(buf, format, str);
> > +goto cleanup;
> > +}
> > +
> > +if (xalloc_oversized(2, len) ||
> > +VIR_ALLOC_N_QUIET(escaped, 2 * len + 1) < 0) {
> > +virBufferSetError(buf, errno);
> > +goto cleanup;
> > +}
> > +
> > +cur = str;
> > +out = e

Re: [libvirt] [PATCH] qemuProcessInit: Jump onto correct label in case of error

2017-02-23 Thread Marc Hartmayer
On Thu, Feb 23, 2017 at 05:15 PM +0100, Michal Privoznik  
wrote:
> After eca76884ea in case of error in qemuDomainSetPrivatePaths()
> in pretended start we jump to stop. I've changed this during
> review from 'cleanup' which turned out to be correct. Well, sort
> of. We can't call qemuProcessStop() as it decrements
> driver->nactive and we did not increment it. However, it calls
> virDomainObjRemoveTransientDef() which is basically the only
> function we need to call. So call that function and goto cleanup;
>
> Signed-off-by: Michal Privoznik 
> ---
>  src/qemu/qemu_process.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index df1fa0371..9306e0e18 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4758,8 +4758,10 @@ qemuProcessInit(virQEMUDriverPtr driver,
>  goto cleanup;
>
>  if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
> -if (qemuDomainSetPrivatePaths(driver, vm) < 0)
> -goto stop;
> +if (qemuDomainSetPrivatePaths(driver, vm) < 0) {
> +virDomainObjRemoveTransientDef(vm);

I'm not sure if this is needed (I think every caller of qemuProcessInit
will unref/free @vm/the transient domain in case of returning -1) but at
least it's not wrong and probably more safe :)

> +}
>  } else {
>  vm->def->id = qemuDriverAllocateID(driver);
>  qemuDomainSetFakeReboot(driver, vm, false);
> --
> 2.11.0
>

Beste Grüße / Kind regards
   Marc Hartmayer

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/5] util: virstring: introduce virStrcat and VIR_STRCAT

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 05:25:38PM +0100, Martin Kletzander wrote:
> On Thu, Feb 23, 2017 at 05:15:12PM +0100, Pavel Hrdina wrote:
> >On Thu, Feb 23, 2017 at 05:06:53PM +0100, Martin Kletzander wrote:
> >> On Thu, Feb 23, 2017 at 04:26:56PM +0100, Pavel Hrdina wrote:
> >> >Signed-off-by: Pavel Hrdina 
> >> >---
> >> > cfg.mk   |  2 +-
> >> > src/libvirt_private.syms |  2 ++
> >> > src/util/virstring.c | 70 
> >> > 
> >> > src/util/virstring.h | 27 +++
> >> > tests/virstringtest.c| 49 +
> >> > 5 files changed, 149 insertions(+), 1 deletion(-)
> >> >
> >> >diff --git a/cfg.mk b/cfg.mk
> >> >index aaba61f1dc..22c655eac6 100644
> >> >--- a/cfg.mk
> >> >+++ b/cfg.mk
> >> >@@ -1147,7 +1147,7 @@ exclude_file_name_regexp--sc_prohibit_fork_wrappers 
> >> >= \
> >> > exclude_file_name_regexp--sc_prohibit_gethostname = 
> >> > ^src/util/virutil\.c$$
> >> >
> >> > exclude_file_name_regexp--sc_prohibit_internal_functions = \
> >> >-  ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
> >> >+  ^src/(util/(viralloc|virutil|virfile|virstring)\.[hc]|esx/esx_vi\.c)$$
> >> >
> >> > exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
> >> >   ^src/rpc/gendispatch\.pl$$
> >> >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> >> >index 07a35333b1..e9c4d73779 100644
> >> >--- a/src/libvirt_private.syms
> >> >+++ b/src/libvirt_private.syms
> >> >@@ -2502,6 +2502,8 @@ virAsprintfInternal;
> >> > virSkipSpaces;
> >> > virSkipSpacesAndBackslash;
> >> > virSkipSpacesBackwards;
> >> >+virStrcat;
> >> >+virStrcatInplace;
> >> > virStrcpy;
> >> > virStrdup;
> >> > virStringBufferIsPrintable;
> >> >diff --git a/src/util/virstring.c b/src/util/virstring.c
> >> >index 69abc267bf..bc15ce7e9e 100644
> >> >--- a/src/util/virstring.c
> >> >+++ b/src/util/virstring.c
> >> >@@ -837,6 +837,76 @@ virStrndup(char **dest,
> >> > }
> >> >
> >> >
> >> >+/**
> >> >+ * virStrcat
> >> >+ * @dest: where to store concatenated string
> >> >+ * @src: the source string to append to @dest
> >> >+ * @inPlace: false if we should expand the allocated memory before 
> >> >moving,
> >> >+ *   true if we should assume someone else has already done that.
> >>
> >> This is here probably from some work in progress version.
> >>
> >> >+ * @report: whether to report OOM error, if there is one
> >> >+ * @domcode: error domain code
> >> >+ * @filename: caller's filename
> >> >+ * @funcname: caller's funcname
> >> >+ * @linenr: caller's line number
> >> >+ *
> >> >+ * Wrapper over strcat, which reports OOM error if told so,
> >> >+ * in which case callers wants to pass @domcode, @filename,
> >> >+ * @funcname and @linenr which should represent location in
> >> >+ * caller's body where virStrcat is called from. Consider
> >> >+ * using VIR_STRCAT which sets these automatically.
> >> >+ *
> >> >+ * Returns: 0 for NULL src, 1 on successful concatenate, -1 otherwise.
> >> >+ */
> >> >+int
> >> >+virStrcat(char **dest,
> >> >+  const char *src,
> >> >+  bool report,
> >> >+  int domcode,
> >> >+  const char *filename,
> >> >+  const char *funcname,
> >> >+  size_t linenr)
> >> >+{
> >> >+size_t dest_len = 0;
> >> >+size_t src_len = 0;
> >> >+
> >> >+if (!src)
> >> >+return 0;
> >> >+
> >> >+if (*dest)
> >> >+dest_len = strlen(*dest);
> >> >+src_len = strlen(src);
> >> >+
> >> >+if (virReallocN(dest, sizeof(*dest), dest_len + src_len + 1,
> >> >+report, domcode, filename, funcname, linenr) < 0)
> >> >+return -1;
> >> >+
> >> >+strcat(*dest, src);
> >> >+
> >> >+return 1;
> >> >+}
> >> >+
> >> >+
> >> >+/**
> >> >+ * virStrcat
> >> >+ * @dest: where to store concatenated string
> >> >+ * @src: the source string to append to @dest
> >> >+ *
> >> >+ * Wrapper over strcat, which properly handles if @src is NULL.
> >> >+ *
> >> >+ * Returns: 0 for NULL src, 1 on successful concatenate.
> >> >+ */
> >>
> >> Really?  This whole wrapper just for checking NULL?  So instead of:
> >>
> >> if (x) strcat (y, x)
> >>
> >> I should do:
> >>
> >> VIR_STRCAT_INPLACE(y, x) now?  It's not even saving any characters.
> >>
> >> Plus, is there *really* any occurrence of strcat that might be called
> >> with NULL?  I would say that such code has more logic problems in that
> >> case.
> >
> >The reason is to forbid using strcat directly and force to use the wrappers.
> >I had two options in my mind, one that will use the virStrcatInplace function
> >with return values 0 and 1 to determine whether something actually happened 
> >or
> >only the "if (x) strcat (y, x)" as a macro without any return value.
> >
> 
> I get the idea, but my point was that I don't get why we should forbid
> using strcat() by itself.

Developers may not know that we already have a helper for it and they would
want to reallocate the d

Re: [libvirt] [PATCH 2/2] qemu: Validate the domain after marking the current domain as transient

2017-02-23 Thread Daniel P. Berrange
On Thu, Feb 23, 2017 at 05:22:44PM +0100, Marc Hartmayer wrote:
> On Thu, Feb 23, 2017 at 03:33 PM +0100, Michal Privoznik 
>  wrote:
> > On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
> >> Validate the domain that actually will be started. It's semantically
> >> more clear and also it can detect failures that may have happened in
> >> virDomainObjSetDefTransient().
> >>
> >> Signed-off-by: Marc Hartmayer 
> >> Reviewed-by: Bjoern Walk 
> >> Reviewed-by: Boris Fiuczynski 
> >> ---
> >>  src/qemu/qemu_process.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> >> index a57d136..bd3a8b8 100644
> >> --- a/src/qemu/qemu_process.c
> >> +++ b/src/qemu/qemu_process.c
> >> @@ -4746,9 +4746,6 @@ qemuProcessInit(virQEMUDriverPtr driver,
> >>
> >> vm->def->os.machine)))
> >>  goto cleanup;
> >>
> >> -if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) 
> >> < 0)
> >> -goto cleanup;
> >> -
> >>  /* Do this upfront, so any part of the startup process can add
> >>   * runtime state to vm->def that won't be persisted. This let's us
> >>   * report implicit runtime defaults in the XML, like vnc listen/socket
> >> @@ -4757,6 +4754,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
> >>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
> >>  goto cleanup;
> >>
> >> +if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) 
> >> < 0)
> >> +goto cleanup;
> >> +
> >
> > This needs to be goto stop for the reasons described in the previous e-mail.
> >
> >>  if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
> >>  if (qemuDomainSetPrivatePaths(driver, vm) < 0)
> >>  goto cleanup;
> >>
> >
> > Honestly, I like what we have now better. I mean, SetDefTransient() is
> > very unlikely to fail. It's just doing a copy of domain definition (in a
> > very stupid way, but lets save that for a different discussion).
> > Basically, it will fail on OOM only (which you will not get on a Linux
> > system, unless you really try).
> 
> It's semantically more clear (at least for me) and for example it
> enables us to change some parts of the transient domain before
> validation (affect the transient domain only, not the persistent).

What are you planning to change in the config before validation ?

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://entangle-photo.org   -o-http://search.cpan.org/~danberr/ :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/5] util: virbuffer: introduce virBufferEscapeN

2017-02-23 Thread Daniel P. Berrange
On Thu, Feb 23, 2017 at 04:26:58PM +0100, Pavel Hrdina wrote:
> Signed-off-by: Pavel Hrdina 
> ---
>  src/libvirt_private.syms |   1 +
>  src/util/virbuffer.c | 104 
> +++
>  src/util/virbuffer.h |   2 +
>  tests/virbuftest.c   |  41 +++
>  4 files changed, 148 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index e9c4d73779..6ce32f1101 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1286,6 +1286,7 @@ virBufferContentAndReset;
>  virBufferCurrentContent;
>  virBufferError;
>  virBufferEscape;
> +virBufferEscapeN;
>  virBufferEscapeSexpr;
>  virBufferEscapeShell;
>  virBufferEscapeString;
> diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
> index d582e7dbec..ad6b29951e 100644
> --- a/src/util/virbuffer.c
> +++ b/src/util/virbuffer.c
> @@ -33,6 +33,7 @@
>  #include "virbuffer.h"
>  #include "viralloc.h"
>  #include "virerror.h"
> +#include "virstring.h"
>  
>  
>  /* If adding more fields, ensure to edit buf.h to match
> @@ -588,6 +589,109 @@ virBufferEscape(virBufferPtr buf, char escape, const 
> char *toescape,
>  VIR_FREE(escaped);
>  }
>  
> +
> +struct _virBufferEscapePair {
> +char escape;
> +char *toescape;
> +};
> +
> +
> +/**
> + * virBufferEscapeN:
> + * @buf: the buffer to append to
> + * @format: a printf like format string but with only one %s parameter
> + * @str: the string argument which needs to be escaped
> + * @...: the variable list of arguments composed
> + *
> + * The variable list of arguments @... must be composed of
> + * 'char escape, char *toescape' pairs followed by NULL.

So most of the complexity you have here is to deal with the ability
to turn a single character into a string of escaped characters. Unless
I'm missing something, you don't actually use that ability in practice.
If we make it more restrictive so you just have a 1-1 mapping we can
simplify the API & implementation. eg

  virBufferEscapeN(virBufferPtr buf,
   const char *format,
   const char *str,
   const char *forbidden,
   const char *replacements)

with strlen(forbidden) == strlen(replacements);


> + *
> + * This has the same functionality as virBufferEscape with the extension
> + * that allows to specify multiple pairs of chars that needs to be escaped.
> + */
> +void
> +virBufferEscapeN(virBufferPtr buf,
> + const char *format,
> + const char *str,
> + ...)
> +{
> +int len;
> +size_t i;
> +char escape;
> +char *toescape;
> +char *toescapeall = NULL;
> +char *escaped = NULL;
> +char *out;
> +const char *cur;
> +struct _virBufferEscapePair escapeItem;
> +struct _virBufferEscapePair *escapeList = NULL;
> +size_t nescapeList = 0;
> +va_list ap;
> +
> +if ((format == NULL) || (buf == NULL) || (str == NULL))
> +return;
> +
> +if (buf->error)
> +return;
> +
> +va_start(ap, str);
> +
> +while ((escape = va_arg(ap, int))) {
> +if (!(toescape = va_arg(ap, char *))) {
> +virBufferSetError(buf, errno);
> +goto cleanup;
> +}
> +
> +escapeItem.escape = escape;
> +escapeItem.toescape = toescape;
> +
> +if (VIR_STRCAT_QUIET(toescapeall, toescape) < 0) {
> +virBufferSetError(buf, errno);
> +goto cleanup;
> +}
> +
> +if (VIR_APPEND_ELEMENT_QUIET(escapeList, nescapeList, escapeItem) < 
> 0) {
> +virBufferSetError(buf, errno);
> +goto cleanup;
> +}
> +}

This whole loop would go away with the simpler API contract, which
nicely avoids doing allocations in the loop body.


> +len = strlen(str);
> +if (strcspn(str, toescapeall) == len) {
> +virBufferAsprintf(buf, format, str);
> +goto cleanup;
> +}
> +
> +if (xalloc_oversized(2, len) ||
> +VIR_ALLOC_N_QUIET(escaped, 2 * len + 1) < 0) {
> +virBufferSetError(buf, errno);
> +goto cleanup;
> +}
> +
> +cur = str;
> +out = escaped;
> +while (*cur != 0) {
> +for (i = 0; i < nescapeList; i++) {
> +if (strchr(escapeList[i].toescape, *cur)) {
> +*out++ = escapeList[i].escape;
> +break;
> +}
> +}
> +*out++ = *cur;
> +cur++;
> +}
> +*out = 0;
> +
> +virBufferAsprintf(buf, format, escaped);
> +
> + cleanup:
> +va_end(ap);
> +VIR_FREE(toescapeall);
> +VIR_FREE(escapeList);
> +VIR_FREE(escaped);
> +}

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://entangle-photo.org   -o-http://search.cpan.org/~danberr/ :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/ma

Re: [libvirt] [PATCH 2/5] util: use VIR_STRCAT instead of strcat

2017-02-23 Thread Daniel P. Berrange
On Thu, Feb 23, 2017 at 05:15:37PM +0100, Martin Kletzander wrote:
> On Thu, Feb 23, 2017 at 04:26:57PM +0100, Pavel Hrdina wrote:
> > Signed-off-by: Pavel Hrdina 
> > ---
> > cfg.mk| 14 --
> > src/storage/storage_backend_logical.c |  6 +++---
> > src/test/test_driver.c|  2 +-
> > src/util/vircgroup.c  |  4 +---
> > src/xen/xend_internal.c   |  2 +-
> > 5 files changed, 14 insertions(+), 14 deletions(-)
> > 
> > diff --git a/cfg.mk b/cfg.mk
> > index 22c655eac6..6646509206 100644
> > --- a/cfg.mk
> > +++ b/cfg.mk
> > @@ -390,6 +390,11 @@ sc_prohibit_strdup:
> > halt='use VIR_STRDUP, not strdup'   \
> >   $(_sc_search_regexp)
> > 
> > +sc_prohibit_strcat:
> > +   @prohibit='\ *\('\
> > +   halt='use VIR_STRCAT, not strcat'   \
> > + $(_sc_search_regexp)
> > +
> > # Prefer virSetUIDGID.
> > sc_prohibit_setuid:
> > @prohibit='\ *\('  \
> > @@ -994,12 +999,6 @@ sc_prohibit_not_streq:
> > halt='Use STRNEQ instead of !STREQ and STREQ instead of !STRNEQ'
> > \
> >   $(_sc_search_regexp)
> > 
> > -sc_prohibit_verbose_strcat:
> > -   @prohibit='strncat\([^,]*,\s+([^,]*),\s+strlen\(\1\)\)' \
> > -   in_vc_files='\.[ch]$$'  \
> > -   halt='Use strcat(a, b) instead of strncat(a, b, strlen(b))' \
> > - $(_sc_search_regexp)
> > -
> > # Ensure that each .c file containing a "main" function also
> > # calls virGettextInitialize
> > sc_gettext_init:
> > @@ -1134,6 +1133,9 @@ exclude_file_name_regexp--sc_prohibit_asprintf = \
> > exclude_file_name_regexp--sc_prohibit_strdup = \
> >   
> > ^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c$$)
> > 
> > +exclude_file_name_regexp--sc_prohibit_strcat = \
> > +  ^(docs/|src/util/virstring\.c|tests/virstringtest\.c)$$
> 
> why virstringtest.c?
> 
> > +
> > exclude_file_name_regexp--sc_prohibit_close = \
> >   
> > (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir.+mock\.c)$$)
> > 
> > diff --git a/src/storage/storage_backend_logical.c 
> > b/src/storage/storage_backend_logical.c
> > index 756c62e908..5e006a980a 100644
> > --- a/src/storage/storage_backend_logical.c
> > +++ b/src/storage/storage_backend_logical.c
> > @@ -201,11 +201,11 @@ 
> > virStorageBackendLogicalParseVolExtents(virStorageVolDefPtr vol,
> > /* Allocate space for 'nextents' regex_unit strings plus a comma for 
> > each */
> > if (VIR_ALLOC_N(regex, nextents * (strlen(regex_unit) + 1) + 1) < 0)
> > goto cleanup;
> > -strcat(regex, regex_unit);
> > +VIR_STRCAT_INPLACE(regex, regex_unit);
> > for (i = 1; i < nextents; i++) {
> > /* "," is the separator of "devices" field */
> > -strcat(regex, ",");
> > -strcat(regex, regex_unit);
> > +VIR_STRCAT_INPLACE(regex, ",");
> > +VIR_STRCAT_INPLACE(regex, regex_unit);
> > }
> > 
> > if (VIR_ALLOC(reg) < 0)
> > diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> > index 5fef3f10b9..be887ec1bb 100644
> > --- a/src/test/test_driver.c
> > +++ b/src/test/test_driver.c
> > @@ -699,7 +699,7 @@ static char *testBuildFilename(const char *relativeTo,
> > VIR_FREE(absFile);
> > return NULL;
> > }
> > -strcat(absFile, filename);
> > +ignore_value(VIR_STRCAT_INPLACE(absFile, filename));
> > return absFile;
> > } else {
> > ignore_value(VIR_STRDUP(ret, filename));
> > diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
> > index 5aa1db5b14..e8210ca6eb 100644
> > --- a/src/util/vircgroup.c
> > +++ b/src/util/vircgroup.c
> > @@ -1299,10 +1299,8 @@ virCgroupSetPartitionSuffix(const char *path, char 
> > **res)
> >  */
> > if (STRNEQ(tokens[i], "") &&
> > !strchr(tokens[i], '.')) {
> > -if (VIR_REALLOC_N(tokens[i],
> > -  strlen(tokens[i]) + strlen(".partition") + 
> > 1) < 0)
> > +if (VIR_STRCAT(tokens[i], ".partition") < 0)
> > goto cleanup;
> > -strcat(tokens[i], ".partition");
> 
> Not counting the rest of your patches, just for now, is this the only
> place the VIR_STRCAT adds value?  This makes me even more cautious about
> the patches.

That code could be rewritten with virAsprintf for clarity eg

   char *part;
   if (virAsprintf(&part, "%s.partition", tokens[i]) < 0)
goto cleanup;
   VIR_FREE(tokens[i]);
   tokens[i] = part;

No, it doesn't make it shorter, but I think it makes it clearer as
to what we're actually doing here.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://entangle-photo.org

Re: [libvirt] [PATCH 1/5] util: virstring: introduce virStrcat and VIR_STRCAT

2017-02-23 Thread Martin Kletzander

On Thu, Feb 23, 2017 at 05:15:12PM +0100, Pavel Hrdina wrote:

On Thu, Feb 23, 2017 at 05:06:53PM +0100, Martin Kletzander wrote:

On Thu, Feb 23, 2017 at 04:26:56PM +0100, Pavel Hrdina wrote:
>Signed-off-by: Pavel Hrdina 
>---
> cfg.mk   |  2 +-
> src/libvirt_private.syms |  2 ++
> src/util/virstring.c | 70 
> src/util/virstring.h | 27 +++
> tests/virstringtest.c| 49 +
> 5 files changed, 149 insertions(+), 1 deletion(-)
>
>diff --git a/cfg.mk b/cfg.mk
>index aaba61f1dc..22c655eac6 100644
>--- a/cfg.mk
>+++ b/cfg.mk
>@@ -1147,7 +1147,7 @@ exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
> exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$
>
> exclude_file_name_regexp--sc_prohibit_internal_functions = \
>-  ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
>+  ^src/(util/(viralloc|virutil|virfile|virstring)\.[hc]|esx/esx_vi\.c)$$
>
> exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
>   ^src/rpc/gendispatch\.pl$$
>diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
>index 07a35333b1..e9c4d73779 100644
>--- a/src/libvirt_private.syms
>+++ b/src/libvirt_private.syms
>@@ -2502,6 +2502,8 @@ virAsprintfInternal;
> virSkipSpaces;
> virSkipSpacesAndBackslash;
> virSkipSpacesBackwards;
>+virStrcat;
>+virStrcatInplace;
> virStrcpy;
> virStrdup;
> virStringBufferIsPrintable;
>diff --git a/src/util/virstring.c b/src/util/virstring.c
>index 69abc267bf..bc15ce7e9e 100644
>--- a/src/util/virstring.c
>+++ b/src/util/virstring.c
>@@ -837,6 +837,76 @@ virStrndup(char **dest,
> }
>
>
>+/**
>+ * virStrcat
>+ * @dest: where to store concatenated string
>+ * @src: the source string to append to @dest
>+ * @inPlace: false if we should expand the allocated memory before moving,
>+ *   true if we should assume someone else has already done that.

This is here probably from some work in progress version.

>+ * @report: whether to report OOM error, if there is one
>+ * @domcode: error domain code
>+ * @filename: caller's filename
>+ * @funcname: caller's funcname
>+ * @linenr: caller's line number
>+ *
>+ * Wrapper over strcat, which reports OOM error if told so,
>+ * in which case callers wants to pass @domcode, @filename,
>+ * @funcname and @linenr which should represent location in
>+ * caller's body where virStrcat is called from. Consider
>+ * using VIR_STRCAT which sets these automatically.
>+ *
>+ * Returns: 0 for NULL src, 1 on successful concatenate, -1 otherwise.
>+ */
>+int
>+virStrcat(char **dest,
>+  const char *src,
>+  bool report,
>+  int domcode,
>+  const char *filename,
>+  const char *funcname,
>+  size_t linenr)
>+{
>+size_t dest_len = 0;
>+size_t src_len = 0;
>+
>+if (!src)
>+return 0;
>+
>+if (*dest)
>+dest_len = strlen(*dest);
>+src_len = strlen(src);
>+
>+if (virReallocN(dest, sizeof(*dest), dest_len + src_len + 1,
>+report, domcode, filename, funcname, linenr) < 0)
>+return -1;
>+
>+strcat(*dest, src);
>+
>+return 1;
>+}
>+
>+
>+/**
>+ * virStrcat
>+ * @dest: where to store concatenated string
>+ * @src: the source string to append to @dest
>+ *
>+ * Wrapper over strcat, which properly handles if @src is NULL.
>+ *
>+ * Returns: 0 for NULL src, 1 on successful concatenate.
>+ */

Really?  This whole wrapper just for checking NULL?  So instead of:

if (x) strcat (y, x)

I should do:

VIR_STRCAT_INPLACE(y, x) now?  It's not even saving any characters.

Plus, is there *really* any occurrence of strcat that might be called
with NULL?  I would say that such code has more logic problems in that
case.


The reason is to forbid using strcat directly and force to use the wrappers.
I had two options in my mind, one that will use the virStrcatInplace function
with return values 0 and 1 to determine whether something actually happened or
only the "if (x) strcat (y, x)" as a macro without any return value.



I get the idea, but my point was that I don't get why we should forbid
using strcat() by itself.


The reallocating strcat makes sense, but the name is *really* confusing
for people who are used to what strcat/strncat does.  So while I see how


In that case it would be nice to provide some alternative :).



virStringAppend?


that might be useful, we also have a buffer for more interesting dynamic
string modifications and I'm not sure this is something that will help a
lot.


Yes we have buffer, but this macro will be used in the buffer code itself
and I guess it would be strange to use a buffer inside a buffer function.



Since that will not be changing the input data, it might be safer to
just sacrifice few bytes of memory and do virAsprintf() into new
buffer.  But if you like this approach more, feel free to use it.


Pavel





--
libvir-list mailing list
libvir-list@redhat.com
htt

Re: [libvirt] [PATCH 2/2] qemu: Validate the domain after marking the current domain as transient

2017-02-23 Thread Marc Hartmayer
On Thu, Feb 23, 2017 at 03:33 PM +0100, Michal Privoznik  
wrote:
> On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
>> Validate the domain that actually will be started. It's semantically
>> more clear and also it can detect failures that may have happened in
>> virDomainObjSetDefTransient().
>>
>> Signed-off-by: Marc Hartmayer 
>> Reviewed-by: Bjoern Walk 
>> Reviewed-by: Boris Fiuczynski 
>> ---
>>  src/qemu/qemu_process.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>> index a57d136..bd3a8b8 100644
>> --- a/src/qemu/qemu_process.c
>> +++ b/src/qemu/qemu_process.c
>> @@ -4746,9 +4746,6 @@ qemuProcessInit(virQEMUDriverPtr driver,
>>vm->def->os.machine)))
>>  goto cleanup;
>>
>> -if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 
>> 0)
>> -goto cleanup;
>> -
>>  /* Do this upfront, so any part of the startup process can add
>>   * runtime state to vm->def that won't be persisted. This let's us
>>   * report implicit runtime defaults in the XML, like vnc listen/socket
>> @@ -4757,6 +4754,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
>>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
>>  goto cleanup;
>>
>> +if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 
>> 0)
>> +goto cleanup;
>> +
>
> This needs to be goto stop for the reasons described in the previous e-mail.
>
>>  if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
>>  if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>>  goto cleanup;
>>
>
> Honestly, I like what we have now better. I mean, SetDefTransient() is
> very unlikely to fail. It's just doing a copy of domain definition (in a
> very stupid way, but lets save that for a different discussion).
> Basically, it will fail on OOM only (which you will not get on a Linux
> system, unless you really try).

It's semantically more clear (at least for me) and for example it
enables us to change some parts of the transient domain before
validation (affect the transient domain only, not the persistent).

> However, the StartValidate() just reads some data without any
> allocation. Thus, from memory management POV, should your domain be
> unable to start we don't allocate any memory just to find that out.

Is this point that important? It's likely that our
'virDomainObjSetDefTransient -> virDomainDefCopy -> virDomainDefFormat
and virDomainDefParseString' does something wrong and this way we could
detect this.


--
Beste Grüße / Kind regards
   Marc Hartmayer

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 2/5] util: use VIR_STRCAT instead of strcat

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 05:15:37PM +0100, Martin Kletzander wrote:
> On Thu, Feb 23, 2017 at 04:26:57PM +0100, Pavel Hrdina wrote:
> >Signed-off-by: Pavel Hrdina 
> >---
> > cfg.mk| 14 --
> > src/storage/storage_backend_logical.c |  6 +++---
> > src/test/test_driver.c|  2 +-
> > src/util/vircgroup.c  |  4 +---
> > src/xen/xend_internal.c   |  2 +-
> > 5 files changed, 14 insertions(+), 14 deletions(-)
> >
> >diff --git a/cfg.mk b/cfg.mk
> >index 22c655eac6..6646509206 100644
> >--- a/cfg.mk
> >+++ b/cfg.mk
> >@@ -390,6 +390,11 @@ sc_prohibit_strdup:
> > halt='use VIR_STRDUP, not strdup'   \
> >   $(_sc_search_regexp)
> >
> >+sc_prohibit_strcat:
> >+@prohibit='\ *\('\
> >+halt='use VIR_STRCAT, not strcat'   \
> >+  $(_sc_search_regexp)
> >+
> > # Prefer virSetUIDGID.
> > sc_prohibit_setuid:
> > @prohibit='\ *\('  \
> >@@ -994,12 +999,6 @@ sc_prohibit_not_streq:
> > halt='Use STRNEQ instead of !STREQ and STREQ instead of !STRNEQ'
> > \
> >   $(_sc_search_regexp)
> >
> >-sc_prohibit_verbose_strcat:
> >-@prohibit='strncat\([^,]*,\s+([^,]*),\s+strlen\(\1\)\)' \
> >-in_vc_files='\.[ch]$$'  \
> >-halt='Use strcat(a, b) instead of strncat(a, b, strlen(b))' \
> >-  $(_sc_search_regexp)
> >-
> > # Ensure that each .c file containing a "main" function also
> > # calls virGettextInitialize
> > sc_gettext_init:
> >@@ -1134,6 +1133,9 @@ exclude_file_name_regexp--sc_prohibit_asprintf = \
> > exclude_file_name_regexp--sc_prohibit_strdup = \
> >   
> > ^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c$$)
> >
> >+exclude_file_name_regexp--sc_prohibit_strcat = \
> >+  ^(docs/|src/util/virstring\.c|tests/virstringtest\.c)$$
> 
> why virstringtest.c?

I'll remove it, nice catch.

> >+
> > exclude_file_name_regexp--sc_prohibit_close = \
> >   
> > (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir.+mock\.c)$$)
> >
> >diff --git a/src/storage/storage_backend_logical.c 
> >b/src/storage/storage_backend_logical.c
> >index 756c62e908..5e006a980a 100644
> >--- a/src/storage/storage_backend_logical.c
> >+++ b/src/storage/storage_backend_logical.c
> >@@ -201,11 +201,11 @@ 
> >virStorageBackendLogicalParseVolExtents(virStorageVolDefPtr vol,
> > /* Allocate space for 'nextents' regex_unit strings plus a comma for 
> > each */
> > if (VIR_ALLOC_N(regex, nextents * (strlen(regex_unit) + 1) + 1) < 0)
> > goto cleanup;
> >-strcat(regex, regex_unit);
> >+VIR_STRCAT_INPLACE(regex, regex_unit);
> > for (i = 1; i < nextents; i++) {
> > /* "," is the separator of "devices" field */
> >-strcat(regex, ",");
> >-strcat(regex, regex_unit);
> >+VIR_STRCAT_INPLACE(regex, ",");
> >+VIR_STRCAT_INPLACE(regex, regex_unit);
> > }
> >
> > if (VIR_ALLOC(reg) < 0)
> >diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> >index 5fef3f10b9..be887ec1bb 100644
> >--- a/src/test/test_driver.c
> >+++ b/src/test/test_driver.c
> >@@ -699,7 +699,7 @@ static char *testBuildFilename(const char *relativeTo,
> > VIR_FREE(absFile);
> > return NULL;
> > }
> >-strcat(absFile, filename);
> >+ignore_value(VIR_STRCAT_INPLACE(absFile, filename));
> > return absFile;
> > } else {
> > ignore_value(VIR_STRDUP(ret, filename));
> >diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
> >index 5aa1db5b14..e8210ca6eb 100644
> >--- a/src/util/vircgroup.c
> >+++ b/src/util/vircgroup.c
> >@@ -1299,10 +1299,8 @@ virCgroupSetPartitionSuffix(const char *path, char 
> >**res)
> >  */
> > if (STRNEQ(tokens[i], "") &&
> > !strchr(tokens[i], '.')) {
> >-if (VIR_REALLOC_N(tokens[i],
> >-  strlen(tokens[i]) + strlen(".partition") + 1) 
> >< 0)
> >+if (VIR_STRCAT(tokens[i], ".partition") < 0)
> > goto cleanup;
> >-strcat(tokens[i], ".partition");
> 
> Not counting the rest of your patches, just for now, is this the only
> place the VIR_STRCAT adds value?  This makes me even more cautious about
> the patches.

Yes, the VIR_STRCAT was introduced solely for the following patch and since
there was code using strcat I though that it would be nice to switch to
VIR_STRCAT.

It definitely doesn't hurt if we have this helper and who knows, someone may
use it some day :).

Pavel

> > }
> >
> > if (virCgroupPartitionEscape(&(tokens[i])) < 0)
> >diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
> >index 605c3cdccf..1f9d4c6959 100644
> >--- a/src/xen/xend_internal.c
> >+++ b/src/xen/xend_internal.c
> >@@ -1824,7 +1824,7 @@ xenDaemonDomainPinVcpu(virConnectPtr con

[libvirt] [PATCH] qemuProcessInit: Jump onto correct label in case of error

2017-02-23 Thread Michal Privoznik
After eca76884ea in case of error in qemuDomainSetPrivatePaths()
in pretended start we jump to stop. I've changed this during
review from 'cleanup' which turned out to be correct. Well, sort
of. We can't call qemuProcessStop() as it decrements
driver->nactive and we did not increment it. However, it calls
virDomainObjRemoveTransientDef() which is basically the only
function we need to call. So call that function and goto cleanup;

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_process.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index df1fa0371..9306e0e18 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4758,8 +4758,10 @@ qemuProcessInit(virQEMUDriverPtr driver,
 goto cleanup;
 
 if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
-if (qemuDomainSetPrivatePaths(driver, vm) < 0)
-goto stop;
+if (qemuDomainSetPrivatePaths(driver, vm) < 0) {
+virDomainObjRemoveTransientDef(vm);
+goto cleanup;
+}
 } else {
 vm->def->id = qemuDriverAllocateID(driver);
 qemuDomainSetFakeReboot(driver, vm, false);
-- 
2.11.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/5] util: virstring: introduce virStrcat and VIR_STRCAT

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 05:06:53PM +0100, Martin Kletzander wrote:
> On Thu, Feb 23, 2017 at 04:26:56PM +0100, Pavel Hrdina wrote:
> >Signed-off-by: Pavel Hrdina 
> >---
> > cfg.mk   |  2 +-
> > src/libvirt_private.syms |  2 ++
> > src/util/virstring.c | 70 
> > 
> > src/util/virstring.h | 27 +++
> > tests/virstringtest.c| 49 +
> > 5 files changed, 149 insertions(+), 1 deletion(-)
> >
> >diff --git a/cfg.mk b/cfg.mk
> >index aaba61f1dc..22c655eac6 100644
> >--- a/cfg.mk
> >+++ b/cfg.mk
> >@@ -1147,7 +1147,7 @@ exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
> > exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$
> >
> > exclude_file_name_regexp--sc_prohibit_internal_functions = \
> >-  ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
> >+  ^src/(util/(viralloc|virutil|virfile|virstring)\.[hc]|esx/esx_vi\.c)$$
> >
> > exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
> >   ^src/rpc/gendispatch\.pl$$
> >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> >index 07a35333b1..e9c4d73779 100644
> >--- a/src/libvirt_private.syms
> >+++ b/src/libvirt_private.syms
> >@@ -2502,6 +2502,8 @@ virAsprintfInternal;
> > virSkipSpaces;
> > virSkipSpacesAndBackslash;
> > virSkipSpacesBackwards;
> >+virStrcat;
> >+virStrcatInplace;
> > virStrcpy;
> > virStrdup;
> > virStringBufferIsPrintable;
> >diff --git a/src/util/virstring.c b/src/util/virstring.c
> >index 69abc267bf..bc15ce7e9e 100644
> >--- a/src/util/virstring.c
> >+++ b/src/util/virstring.c
> >@@ -837,6 +837,76 @@ virStrndup(char **dest,
> > }
> >
> >
> >+/**
> >+ * virStrcat
> >+ * @dest: where to store concatenated string
> >+ * @src: the source string to append to @dest
> >+ * @inPlace: false if we should expand the allocated memory before moving,
> >+ *   true if we should assume someone else has already done that.
> 
> This is here probably from some work in progress version.
> 
> >+ * @report: whether to report OOM error, if there is one
> >+ * @domcode: error domain code
> >+ * @filename: caller's filename
> >+ * @funcname: caller's funcname
> >+ * @linenr: caller's line number
> >+ *
> >+ * Wrapper over strcat, which reports OOM error if told so,
> >+ * in which case callers wants to pass @domcode, @filename,
> >+ * @funcname and @linenr which should represent location in
> >+ * caller's body where virStrcat is called from. Consider
> >+ * using VIR_STRCAT which sets these automatically.
> >+ *
> >+ * Returns: 0 for NULL src, 1 on successful concatenate, -1 otherwise.
> >+ */
> >+int
> >+virStrcat(char **dest,
> >+  const char *src,
> >+  bool report,
> >+  int domcode,
> >+  const char *filename,
> >+  const char *funcname,
> >+  size_t linenr)
> >+{
> >+size_t dest_len = 0;
> >+size_t src_len = 0;
> >+
> >+if (!src)
> >+return 0;
> >+
> >+if (*dest)
> >+dest_len = strlen(*dest);
> >+src_len = strlen(src);
> >+
> >+if (virReallocN(dest, sizeof(*dest), dest_len + src_len + 1,
> >+report, domcode, filename, funcname, linenr) < 0)
> >+return -1;
> >+
> >+strcat(*dest, src);
> >+
> >+return 1;
> >+}
> >+
> >+
> >+/**
> >+ * virStrcat
> >+ * @dest: where to store concatenated string
> >+ * @src: the source string to append to @dest
> >+ *
> >+ * Wrapper over strcat, which properly handles if @src is NULL.
> >+ *
> >+ * Returns: 0 for NULL src, 1 on successful concatenate.
> >+ */
> 
> Really?  This whole wrapper just for checking NULL?  So instead of:
> 
> if (x) strcat (y, x)
> 
> I should do:
> 
> VIR_STRCAT_INPLACE(y, x) now?  It's not even saving any characters.
> 
> Plus, is there *really* any occurrence of strcat that might be called
> with NULL?  I would say that such code has more logic problems in that
> case.

The reason is to forbid using strcat directly and force to use the wrappers.
I had two options in my mind, one that will use the virStrcatInplace function
with return values 0 and 1 to determine whether something actually happened or
only the "if (x) strcat (y, x)" as a macro without any return value.

> The reallocating strcat makes sense, but the name is *really* confusing
> for people who are used to what strcat/strncat does.  So while I see how

In that case it would be nice to provide some alternative :).

> that might be useful, we also have a buffer for more interesting dynamic
> string modifications and I'm not sure this is something that will help a
> lot.

Yes we have buffer, but this macro will be used in the buffer code itself
and I guess it would be strange to use a buffer inside a buffer function.

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 2/5] util: use VIR_STRCAT instead of strcat

2017-02-23 Thread Martin Kletzander

On Thu, Feb 23, 2017 at 04:26:57PM +0100, Pavel Hrdina wrote:

Signed-off-by: Pavel Hrdina 
---
cfg.mk| 14 --
src/storage/storage_backend_logical.c |  6 +++---
src/test/test_driver.c|  2 +-
src/util/vircgroup.c  |  4 +---
src/xen/xend_internal.c   |  2 +-
5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/cfg.mk b/cfg.mk
index 22c655eac6..6646509206 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -390,6 +390,11 @@ sc_prohibit_strdup:
halt='use VIR_STRDUP, not strdup'   \
  $(_sc_search_regexp)

+sc_prohibit_strcat:
+   @prohibit='\ *\('  \
+   halt='use VIR_STRCAT, not strcat'   \
+ $(_sc_search_regexp)
+
# Prefer virSetUIDGID.
sc_prohibit_setuid:
@prohibit='\ *\('\
@@ -994,12 +999,6 @@ sc_prohibit_not_streq:
halt='Use STRNEQ instead of !STREQ and STREQ instead of !STRNEQ'
\
  $(_sc_search_regexp)

-sc_prohibit_verbose_strcat:
-   @prohibit='strncat\([^,]*,\s+([^,]*),\s+strlen\(\1\)\)' \
-   in_vc_files='\.[ch]$$'  \
-   halt='Use strcat(a, b) instead of strncat(a, b, strlen(b))' \
- $(_sc_search_regexp)
-
# Ensure that each .c file containing a "main" function also
# calls virGettextInitialize
sc_gettext_init:
@@ -1134,6 +1133,9 @@ exclude_file_name_regexp--sc_prohibit_asprintf = \
exclude_file_name_regexp--sc_prohibit_strdup = \
  
^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c$$)

+exclude_file_name_regexp--sc_prohibit_strcat = \
+  ^(docs/|src/util/virstring\.c|tests/virstringtest\.c)$$


why virstringtest.c?


+
exclude_file_name_regexp--sc_prohibit_close = \
  
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir.+mock\.c)$$)

diff --git a/src/storage/storage_backend_logical.c 
b/src/storage/storage_backend_logical.c
index 756c62e908..5e006a980a 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -201,11 +201,11 @@ 
virStorageBackendLogicalParseVolExtents(virStorageVolDefPtr vol,
/* Allocate space for 'nextents' regex_unit strings plus a comma for each */
if (VIR_ALLOC_N(regex, nextents * (strlen(regex_unit) + 1) + 1) < 0)
goto cleanup;
-strcat(regex, regex_unit);
+VIR_STRCAT_INPLACE(regex, regex_unit);
for (i = 1; i < nextents; i++) {
/* "," is the separator of "devices" field */
-strcat(regex, ",");
-strcat(regex, regex_unit);
+VIR_STRCAT_INPLACE(regex, ",");
+VIR_STRCAT_INPLACE(regex, regex_unit);
}

if (VIR_ALLOC(reg) < 0)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 5fef3f10b9..be887ec1bb 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -699,7 +699,7 @@ static char *testBuildFilename(const char *relativeTo,
VIR_FREE(absFile);
return NULL;
}
-strcat(absFile, filename);
+ignore_value(VIR_STRCAT_INPLACE(absFile, filename));
return absFile;
} else {
ignore_value(VIR_STRDUP(ret, filename));
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5aa1db5b14..e8210ca6eb 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1299,10 +1299,8 @@ virCgroupSetPartitionSuffix(const char *path, char **res)
 */
if (STRNEQ(tokens[i], "") &&
!strchr(tokens[i], '.')) {
-if (VIR_REALLOC_N(tokens[i],
-  strlen(tokens[i]) + strlen(".partition") + 1) < 
0)
+if (VIR_STRCAT(tokens[i], ".partition") < 0)
goto cleanup;
-strcat(tokens[i], ".partition");


Not counting the rest of your patches, just for now, is this the only
place the VIR_STRCAT adds value?  This makes me even more cautious about
the patches.


}

if (virCgroupPartitionEscape(&(tokens[i])) < 0)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 605c3cdccf..1f9d4c6959 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -1824,7 +1824,7 @@ xenDaemonDomainPinVcpu(virConnectPtr conn,
for (i = 0; i < maplen; i++) for (j = 0; j < 8; j++)
 if (cpumap[i] & (1 << j)) {
snprintf(buf, sizeof(buf), "%zu,", (8 * i) + j);
-strcat(mapstr, buf);
+VIR_STRCAT_INPLACE(mapstr, buf);
}
mapstr[strlen(mapstr) - 1] = 0;

--
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/5] util: virstring: introduce virStrcat and VIR_STRCAT

2017-02-23 Thread Martin Kletzander

On Thu, Feb 23, 2017 at 04:26:56PM +0100, Pavel Hrdina wrote:

Signed-off-by: Pavel Hrdina 
---
cfg.mk   |  2 +-
src/libvirt_private.syms |  2 ++
src/util/virstring.c | 70 
src/util/virstring.h | 27 +++
tests/virstringtest.c| 49 +
5 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/cfg.mk b/cfg.mk
index aaba61f1dc..22c655eac6 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1147,7 +1147,7 @@ exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$

exclude_file_name_regexp--sc_prohibit_internal_functions = \
-  ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
+  ^src/(util/(viralloc|virutil|virfile|virstring)\.[hc]|esx/esx_vi\.c)$$

exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
  ^src/rpc/gendispatch\.pl$$
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 07a35333b1..e9c4d73779 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2502,6 +2502,8 @@ virAsprintfInternal;
virSkipSpaces;
virSkipSpacesAndBackslash;
virSkipSpacesBackwards;
+virStrcat;
+virStrcatInplace;
virStrcpy;
virStrdup;
virStringBufferIsPrintable;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 69abc267bf..bc15ce7e9e 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -837,6 +837,76 @@ virStrndup(char **dest,
}


+/**
+ * virStrcat
+ * @dest: where to store concatenated string
+ * @src: the source string to append to @dest
+ * @inPlace: false if we should expand the allocated memory before moving,
+ *   true if we should assume someone else has already done that.


This is here probably from some work in progress version.


+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
+ *
+ * Wrapper over strcat, which reports OOM error if told so,
+ * in which case callers wants to pass @domcode, @filename,
+ * @funcname and @linenr which should represent location in
+ * caller's body where virStrcat is called from. Consider
+ * using VIR_STRCAT which sets these automatically.
+ *
+ * Returns: 0 for NULL src, 1 on successful concatenate, -1 otherwise.
+ */
+int
+virStrcat(char **dest,
+  const char *src,
+  bool report,
+  int domcode,
+  const char *filename,
+  const char *funcname,
+  size_t linenr)
+{
+size_t dest_len = 0;
+size_t src_len = 0;
+
+if (!src)
+return 0;
+
+if (*dest)
+dest_len = strlen(*dest);
+src_len = strlen(src);
+
+if (virReallocN(dest, sizeof(*dest), dest_len + src_len + 1,
+report, domcode, filename, funcname, linenr) < 0)
+return -1;
+
+strcat(*dest, src);
+
+return 1;
+}
+
+
+/**
+ * virStrcat
+ * @dest: where to store concatenated string
+ * @src: the source string to append to @dest
+ *
+ * Wrapper over strcat, which properly handles if @src is NULL.
+ *
+ * Returns: 0 for NULL src, 1 on successful concatenate.
+ */


Really?  This whole wrapper just for checking NULL?  So instead of:

if (x) strcat (y, x)

I should do:

VIR_STRCAT_INPLACE(y, x) now?  It's not even saving any characters.

Plus, is there *really* any occurrence of strcat that might be called
with NULL?  I would say that such code has more logic problems in that
case.

The reallocating strcat makes sense, but the name is *really* confusing
for people who are used to what strcat/strncat does.  So while I see how
that might be useful, we also have a buffer for more interesting dynamic
string modifications and I'm not sure this is something that will help a
lot.


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/2] qemu: Fix incorrect jump labels in error paths

2017-02-23 Thread Michal Privoznik
On 02/23/2017 04:57 PM, Marc Hartmayer wrote:
> On Thu, Feb 23, 2017 at 03:33 PM +0100, Michal Privoznik 
>  wrote:
>> On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
>>> Fix incorrect jump labels in error paths as the stop jump is only
>>> needed if the driver has already changed the state. For example
>>> 'virAtomicIntInc(&driver->nactive)' will be 'reverted' in the
>>> qemuProcessStop call.
>>>
>>> Signed-off-by: Marc Hartmayer 
>>> Reviewed-by: Boris Fiuczynski 
>>> ---
>>>  src/qemu/qemu_process.c | 13 -
>>>  1 file changed, 8 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>>> index ea10fff..a57d136 100644
>>> --- a/src/qemu/qemu_process.c
>>> +++ b/src/qemu/qemu_process.c
>>> @@ -4755,9 +4755,12 @@ qemuProcessInit(virQEMUDriverPtr driver,
>>>   */
>>>  VIR_DEBUG("Setting current domain def as transient");
>>>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
>>> -goto stop;
>>> +goto cleanup;
>>>
>>> -if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) {
>>> +if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
>>> +if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>>> +goto cleanup;
>>
>> This should have been goto stop; After SetDefTransien() succeeds,
>> everything must goto stop in order to call qemuProcessStop which undoes
>> the SetDefTransient(). I will fix it before pushing.
> 
> Hmm why? In qemuProcessStop() the driver->nactive will be decreased and
> I think that is definitely not what we want if we haven't increased
> that value... (for the VIR_QEMU_PROCESS_START_PRETEND path)

Ah, that's a good point. On the other hand, we need to call
virDomainObjRemoveTransientDef(). So I guess the proper solution is to:

if (qemuDomainSetPrivatePaths(driver, vm) < 0) {
  virDomainObjRemoveTransientDef(vm);
  goto cleanup;
}

I'll post the patch shortly.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] qemu: Fix incorrect jump labels in error paths

2017-02-23 Thread Marc Hartmayer
On Thu, Feb 23, 2017 at 03:33 PM +0100, Michal Privoznik  
wrote:
> On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
>> Fix incorrect jump labels in error paths as the stop jump is only
>> needed if the driver has already changed the state. For example
>> 'virAtomicIntInc(&driver->nactive)' will be 'reverted' in the
>> qemuProcessStop call.
>>
>> Signed-off-by: Marc Hartmayer 
>> Reviewed-by: Boris Fiuczynski 
>> ---
>>  src/qemu/qemu_process.c | 13 -
>>  1 file changed, 8 insertions(+), 5 deletions(-)
>>
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>> index ea10fff..a57d136 100644
>> --- a/src/qemu/qemu_process.c
>> +++ b/src/qemu/qemu_process.c
>> @@ -4755,9 +4755,12 @@ qemuProcessInit(virQEMUDriverPtr driver,
>>   */
>>  VIR_DEBUG("Setting current domain def as transient");
>>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
>> -goto stop;
>> +goto cleanup;
>>
>> -if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) {
>> +if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
>> +if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>> +goto cleanup;
>
> This should have been goto stop; After SetDefTransien() succeeds,
> everything must goto stop in order to call qemuProcessStop which undoes
> the SetDefTransient(). I will fix it before pushing.

Hmm why? In qemuProcessStop() the driver->nactive will be decreased and
I think that is definitely not what we want if we haven't increased
that value... (for the VIR_QEMU_PROCESS_START_PRETEND path)

>
>> +} else {
>>  vm->def->id = qemuDriverAllocateID(driver);
>>  qemuDomainSetFakeReboot(driver, vm, false);
>>  virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, 
>> VIR_DOMAIN_PAUSED_STARTING_UP);
>> @@ -4770,10 +4773,10 @@ qemuProcessInit(virQEMUDriverPtr driver,
>>   VIR_HOOK_QEMU_OP_PREPARE,
>>   VIR_HOOK_SUBOP_BEGIN) < 0)
>>  goto stop;
>> -}
>>
>> -if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>> -goto cleanup;
>> +if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>> +goto stop;
>> +}
>>
>>  ret = 0;
>>
>>
>
> ACKed and pushed.
>
> Michal
>
--
Beste Grüße / Kind regards
   Marc Hartmayer

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 02/28] domaincapstest: Add test data for QEMU 2.9.0

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:15:00PM +0100, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Version 3:
> - no change
> 
> Version 2:
> - no change
> 
>  .../domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml | 116 
> +
>  tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml   | 116 
> +
>  tests/domaincapstest.c |   8 ++
>  3 files changed, 240 insertions(+)
>  create mode 100644 tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml
>  create mode 100644 tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 01/28] qemucapstest: Update test data for QEMU 2.9.0

2017-02-23 Thread Pavel Hrdina
On Thu, Feb 23, 2017 at 03:14:59PM +0100, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark 
> ---
> 
> Notes:
> Generated from Eduardo's work/x86-query-cpu-expansion-full branch
> rebased on current QEMU master.
> 
> Version 3:
> - regenerated with a rebased QEMU to avoid conflicts with existing
>   caps_2.9.0.x86_64.replies file
> - summary changed from "qemucapstest: Add test data for QEMU 2.9.0"
> 
> Version 2:
> - no change
> 
>  .../qemucapabilitiesdata/caps_2.9.0.x86_64.replies | 224 
> -
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   | 170 +++-
>  2 files changed, 391 insertions(+), 3 deletions(-)

ACK

Pavel


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] 1GB huge pages and incompatible VM memory size

2017-02-23 Thread Michal Privoznik
On 02/23/2017 03:26 PM, Matt Fleming wrote:
> On Tue, 21 Feb, at 11:23:52AM, Michal Privoznik wrote:
>>
>> Jim,
>>
>> what is the actual problem? I've tried to reproduce this by running vm
>> with 3.5G RAM backed by 1GB huge pages and the guest runs just fine. I
>> mean kvm guest. This is because at the cmd line level there is aligned
>> value:
>>
>> -m size=4194304k,slots=16,maxmem=8388608k
>>
>> This is result of qemuDomainAlignMemorySizes(). So perhaps there's a bug
>> somewhere in the function?
> 
> Quite possibly. Some memory values work fine and appear to be rounded
> to the next gigabyte boundary. One KiB values that fails for me is,
> 
>   52428801
>   52428801
> 
> Which results in qemu-kvm ... -m 51201

I currently don't have access to a host with 50+GB of RAM, so I start small:

  3145739
  3145739
  

  

  


 -m 3073


And this works just fine. One thing that I've noticed is that we don't
take into account sizes of huge pages in qemuDomainAlignMemorySizes().
But then again - what is the scenario you're seeing? What's the error
message?

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 4/5] util: virqemu: introduce virQEMUBuildBufferEscape

2017-02-23 Thread Pavel Hrdina
This will eventually replace virQEMUBuildBufferEscapeComma, however
it's not possible right now.  Some parts of the code that uses the
old function needs to be refactored.

Signed-off-by: Pavel Hrdina 
---
 src/libvirt_private.syms |  1 +
 src/util/virqemu.c   | 17 +
 src/util/virqemu.h   |  1 +
 3 files changed, 19 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6ce32f1101..3fb123751a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2298,6 +2298,7 @@ virProcessWait;
 
 
 # util/virqemu.h
+virQEMUBuildBufferEscape;
 virQEMUBuildBufferEscapeComma;
 virQEMUBuildCommandLineJSON;
 virQEMUBuildCommandLineJSONArrayBitmap;
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 2e9e65f9ef..f10b356781 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -300,6 +300,23 @@ virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char 
*str)
 
 
 /**
+ * virQEMUBuildBufferEscape:
+ * @buf: buffer to append the escaped string
+ * @str: the string to escape
+ *
+ * Some characters passed as values on the QEMU command line must be escaped.
+ *
+ *  - ',' must by escaped by ','
+ *  - '=' must by escaped by '\'
+ */
+void
+virQEMUBuildBufferEscape(virBufferPtr buf, const char *str)
+{
+virBufferEscapeN(buf, "%s", str, ',', ",", '\\', "=", NULL);
+}
+
+
+/**
  * virQEMUBuildLuksOpts:
  * @buf: buffer to build the string into
  * @enc: pointer to encryption info
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 539d62ab14..10aeb67f4e 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -50,6 +50,7 @@ char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
 char *virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr src);
 
 void virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str);
+void virQEMUBuildBufferEscape(virBufferPtr buf, const char *str);
 void virQEMUBuildLuksOpts(virBufferPtr buf,
   virStorageEncryptionInfoDefPtr enc,
   const char *alias)
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 5/5] qemu: properly escape socket path for graphics

2017-02-23 Thread Pavel Hrdina
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1352529

Signed-off-by: Pavel Hrdina 
---
 src/qemu/qemu_command.c  | 6 --
 tests/qemuxml2argvdata/qemuxml2argv-name-escape.args | 5 +++--
 tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml  | 7 ++-
 tests/qemuxml2argvtest.c | 3 ++-
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d5da533e50..41eecfd187 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7495,7 +7495,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr 
cfg,
 switch (glisten->type) {
 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
 virBufferAddLit(&opt, "unix:");
-virQEMUBuildBufferEscapeComma(&opt, glisten->socket);
+virQEMUBuildBufferEscape(&opt, glisten->socket);
 break;
 
 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
@@ -7627,7 +7627,9 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr 
cfg,
 goto error;
 }
 
-virBufferAsprintf(&opt, "unix,addr=%s,", glisten->socket);
+virBufferAddLit(&opt, "unix,addr=");
+virQEMUBuildBufferEscape(&opt, glisten->socket);
+virBufferAddLit(&opt, ",");
 hasInsecure = true;
 break;
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args 
b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
index 9ae50bd455..deb37e09e6 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
@@ -3,7 +3,7 @@ PATH=/bin \
 HOME=/home/test \
 USER=test \
 LOGNAME=test \
-QEMU_AUDIO_DRV=none \
+QEMU_AUDIO_DRV=spice \
 /usr/bin/qemu \
 -name guest=foo=1,,bar=2,debug-threads=on \
 -S \
@@ -20,6 +20,7 @@ bar=2/monitor.sock,server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--vnc unix:/tmp/bar,,foo.sock \
+-vnc 'unix:/tmp/lib/domain--1-foo\=1,,bar\=2/vnc.sock' \
+-spice 'unix,addr=/tmp/lib/domain--1-foo\=1,,bar\=2/spice.sock' \
 -vga cirrus \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml 
b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml
index 5e8c7476fe..604e1453f2 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.xml
@@ -14,6 +14,11 @@
   destroy
   
 /usr/bin/qemu
-
+
+  
+
+
+  
+
   
 
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index f55b04b057..f3b5648b5c 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2455,7 +2455,8 @@ mymain(void)
 
 DO_TEST("name-escape", QEMU_CAPS_NAME_DEBUG_THREADS,
 QEMU_CAPS_OBJECT_SECRET, QEMU_CAPS_CHARDEV, QEMU_CAPS_VNC,
-QEMU_CAPS_NAME_GUEST, QEMU_CAPS_DEVICE_CIRRUS_VGA);
+QEMU_CAPS_NAME_GUEST, QEMU_CAPS_DEVICE_CIRRUS_VGA,
+QEMU_CAPS_SPICE, QEMU_CAPS_SPICE_UNIX);
 DO_TEST("debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS);
 
 DO_TEST("master-key", QEMU_CAPS_OBJECT_SECRET);
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 2/5] util: use VIR_STRCAT instead of strcat

2017-02-23 Thread Pavel Hrdina
Signed-off-by: Pavel Hrdina 
---
 cfg.mk| 14 --
 src/storage/storage_backend_logical.c |  6 +++---
 src/test/test_driver.c|  2 +-
 src/util/vircgroup.c  |  4 +---
 src/xen/xend_internal.c   |  2 +-
 5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/cfg.mk b/cfg.mk
index 22c655eac6..6646509206 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -390,6 +390,11 @@ sc_prohibit_strdup:
halt='use VIR_STRDUP, not strdup'   \
  $(_sc_search_regexp)
 
+sc_prohibit_strcat:
+   @prohibit='\ *\('\
+   halt='use VIR_STRCAT, not strcat'   \
+ $(_sc_search_regexp)
+
 # Prefer virSetUIDGID.
 sc_prohibit_setuid:
@prohibit='\ *\('  \
@@ -994,12 +999,6 @@ sc_prohibit_not_streq:
halt='Use STRNEQ instead of !STREQ and STREQ instead of !STRNEQ'
\
  $(_sc_search_regexp)
 
-sc_prohibit_verbose_strcat:
-   @prohibit='strncat\([^,]*,\s+([^,]*),\s+strlen\(\1\)\)' \
-   in_vc_files='\.[ch]$$'  \
-   halt='Use strcat(a, b) instead of strncat(a, b, strlen(b))' \
- $(_sc_search_regexp)
-
 # Ensure that each .c file containing a "main" function also
 # calls virGettextInitialize
 sc_gettext_init:
@@ -1134,6 +1133,9 @@ exclude_file_name_regexp--sc_prohibit_asprintf = \
 exclude_file_name_regexp--sc_prohibit_strdup = \
   
^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c$$)
 
+exclude_file_name_regexp--sc_prohibit_strcat = \
+  ^(docs/|src/util/virstring\.c|tests/virstringtest\.c)$$
+
 exclude_file_name_regexp--sc_prohibit_close = \
   
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir.+mock\.c)$$)
 
diff --git a/src/storage/storage_backend_logical.c 
b/src/storage/storage_backend_logical.c
index 756c62e908..5e006a980a 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -201,11 +201,11 @@ 
virStorageBackendLogicalParseVolExtents(virStorageVolDefPtr vol,
 /* Allocate space for 'nextents' regex_unit strings plus a comma for each 
*/
 if (VIR_ALLOC_N(regex, nextents * (strlen(regex_unit) + 1) + 1) < 0)
 goto cleanup;
-strcat(regex, regex_unit);
+VIR_STRCAT_INPLACE(regex, regex_unit);
 for (i = 1; i < nextents; i++) {
 /* "," is the separator of "devices" field */
-strcat(regex, ",");
-strcat(regex, regex_unit);
+VIR_STRCAT_INPLACE(regex, ",");
+VIR_STRCAT_INPLACE(regex, regex_unit);
 }
 
 if (VIR_ALLOC(reg) < 0)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 5fef3f10b9..be887ec1bb 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -699,7 +699,7 @@ static char *testBuildFilename(const char *relativeTo,
 VIR_FREE(absFile);
 return NULL;
 }
-strcat(absFile, filename);
+ignore_value(VIR_STRCAT_INPLACE(absFile, filename));
 return absFile;
 } else {
 ignore_value(VIR_STRDUP(ret, filename));
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5aa1db5b14..e8210ca6eb 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1299,10 +1299,8 @@ virCgroupSetPartitionSuffix(const char *path, char **res)
  */
 if (STRNEQ(tokens[i], "") &&
 !strchr(tokens[i], '.')) {
-if (VIR_REALLOC_N(tokens[i],
-  strlen(tokens[i]) + strlen(".partition") + 1) < 
0)
+if (VIR_STRCAT(tokens[i], ".partition") < 0)
 goto cleanup;
-strcat(tokens[i], ".partition");
 }
 
 if (virCgroupPartitionEscape(&(tokens[i])) < 0)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 605c3cdccf..1f9d4c6959 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -1824,7 +1824,7 @@ xenDaemonDomainPinVcpu(virConnectPtr conn,
 for (i = 0; i < maplen; i++) for (j = 0; j < 8; j++)
  if (cpumap[i] & (1 << j)) {
 snprintf(buf, sizeof(buf), "%zu,", (8 * i) + j);
-strcat(mapstr, buf);
+VIR_STRCAT_INPLACE(mapstr, buf);
 }
 mapstr[strlen(mapstr) - 1] = 0;
 
-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 3/5] util: virbuffer: introduce virBufferEscapeN

2017-02-23 Thread Pavel Hrdina
Signed-off-by: Pavel Hrdina 
---
 src/libvirt_private.syms |   1 +
 src/util/virbuffer.c | 104 +++
 src/util/virbuffer.h |   2 +
 tests/virbuftest.c   |  41 +++
 4 files changed, 148 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e9c4d73779..6ce32f1101 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1286,6 +1286,7 @@ virBufferContentAndReset;
 virBufferCurrentContent;
 virBufferError;
 virBufferEscape;
+virBufferEscapeN;
 virBufferEscapeSexpr;
 virBufferEscapeShell;
 virBufferEscapeString;
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
index d582e7dbec..ad6b29951e 100644
--- a/src/util/virbuffer.c
+++ b/src/util/virbuffer.c
@@ -33,6 +33,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virerror.h"
+#include "virstring.h"
 
 
 /* If adding more fields, ensure to edit buf.h to match
@@ -588,6 +589,109 @@ virBufferEscape(virBufferPtr buf, char escape, const char 
*toescape,
 VIR_FREE(escaped);
 }
 
+
+struct _virBufferEscapePair {
+char escape;
+char *toescape;
+};
+
+
+/**
+ * virBufferEscapeN:
+ * @buf: the buffer to append to
+ * @format: a printf like format string but with only one %s parameter
+ * @str: the string argument which needs to be escaped
+ * @...: the variable list of arguments composed
+ *
+ * The variable list of arguments @... must be composed of
+ * 'char escape, char *toescape' pairs followed by NULL.
+ *
+ * This has the same functionality as virBufferEscape with the extension
+ * that allows to specify multiple pairs of chars that needs to be escaped.
+ */
+void
+virBufferEscapeN(virBufferPtr buf,
+ const char *format,
+ const char *str,
+ ...)
+{
+int len;
+size_t i;
+char escape;
+char *toescape;
+char *toescapeall = NULL;
+char *escaped = NULL;
+char *out;
+const char *cur;
+struct _virBufferEscapePair escapeItem;
+struct _virBufferEscapePair *escapeList = NULL;
+size_t nescapeList = 0;
+va_list ap;
+
+if ((format == NULL) || (buf == NULL) || (str == NULL))
+return;
+
+if (buf->error)
+return;
+
+va_start(ap, str);
+
+while ((escape = va_arg(ap, int))) {
+if (!(toescape = va_arg(ap, char *))) {
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+
+escapeItem.escape = escape;
+escapeItem.toescape = toescape;
+
+if (VIR_STRCAT_QUIET(toescapeall, toescape) < 0) {
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+
+if (VIR_APPEND_ELEMENT_QUIET(escapeList, nescapeList, escapeItem) < 0) 
{
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+}
+
+len = strlen(str);
+if (strcspn(str, toescapeall) == len) {
+virBufferAsprintf(buf, format, str);
+goto cleanup;
+}
+
+if (xalloc_oversized(2, len) ||
+VIR_ALLOC_N_QUIET(escaped, 2 * len + 1) < 0) {
+virBufferSetError(buf, errno);
+goto cleanup;
+}
+
+cur = str;
+out = escaped;
+while (*cur != 0) {
+for (i = 0; i < nescapeList; i++) {
+if (strchr(escapeList[i].toescape, *cur)) {
+*out++ = escapeList[i].escape;
+break;
+}
+}
+*out++ = *cur;
+cur++;
+}
+*out = 0;
+
+virBufferAsprintf(buf, format, escaped);
+
+ cleanup:
+va_end(ap);
+VIR_FREE(toescapeall);
+VIR_FREE(escapeList);
+VIR_FREE(escaped);
+}
+
+
 /**
  * virBufferURIEncodeString:
  * @buf: the buffer to append to
diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
index 144a1ba06e..94f14b5b16 100644
--- a/src/util/virbuffer.h
+++ b/src/util/virbuffer.h
@@ -82,6 +82,8 @@ void virBufferStrcat(virBufferPtr buf, ...)
   ATTRIBUTE_SENTINEL;
 void virBufferEscape(virBufferPtr buf, char escape, const char *toescape,
  const char *format, const char *str);
+void virBufferEscapeN(virBufferPtr buf, const char *format,
+  const char *str, ...);
 void virBufferEscapeString(virBufferPtr buf, const char *format,
const char *str);
 void virBufferEscapeSexpr(virBufferPtr buf, const char *format,
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
index 22407ab6a8..34160e6b28 100644
--- a/tests/virbuftest.c
+++ b/tests/virbuftest.c
@@ -376,6 +376,35 @@ testBufEscapeStr(const void *opaque ATTRIBUTE_UNUSED)
 
 
 static int
+testBufEscapeN(const void *opaque)
+{
+const struct testBufAddStrData *data = opaque;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+char *actual;
+int ret = -1;
+
+virBufferEscapeN(&buf, "%s", data->data, '\\', "=", ',', ",", NULL);
+
+if (!(actual = virBufferContentAndReset(&buf))) {
+VIR_TEST_DEBUG("testBufEscapeN: buf is empty");
+goto cleanup;
+}
+
+if (ST

[libvirt] [PATCH 1/5] util: virstring: introduce virStrcat and VIR_STRCAT

2017-02-23 Thread Pavel Hrdina
Signed-off-by: Pavel Hrdina 
---
 cfg.mk   |  2 +-
 src/libvirt_private.syms |  2 ++
 src/util/virstring.c | 70 
 src/util/virstring.h | 27 +++
 tests/virstringtest.c| 49 +
 5 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/cfg.mk b/cfg.mk
index aaba61f1dc..22c655eac6 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1147,7 +1147,7 @@ exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
 exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$
 
 exclude_file_name_regexp--sc_prohibit_internal_functions = \
-  ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
+  ^src/(util/(viralloc|virutil|virfile|virstring)\.[hc]|esx/esx_vi\.c)$$
 
 exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
   ^src/rpc/gendispatch\.pl$$
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 07a35333b1..e9c4d73779 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2502,6 +2502,8 @@ virAsprintfInternal;
 virSkipSpaces;
 virSkipSpacesAndBackslash;
 virSkipSpacesBackwards;
+virStrcat;
+virStrcatInplace;
 virStrcpy;
 virStrdup;
 virStringBufferIsPrintable;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 69abc267bf..bc15ce7e9e 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -837,6 +837,76 @@ virStrndup(char **dest,
 }
 
 
+/**
+ * virStrcat
+ * @dest: where to store concatenated string
+ * @src: the source string to append to @dest
+ * @inPlace: false if we should expand the allocated memory before moving,
+ *   true if we should assume someone else has already done that.
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
+ *
+ * Wrapper over strcat, which reports OOM error if told so,
+ * in which case callers wants to pass @domcode, @filename,
+ * @funcname and @linenr which should represent location in
+ * caller's body where virStrcat is called from. Consider
+ * using VIR_STRCAT which sets these automatically.
+ *
+ * Returns: 0 for NULL src, 1 on successful concatenate, -1 otherwise.
+ */
+int
+virStrcat(char **dest,
+  const char *src,
+  bool report,
+  int domcode,
+  const char *filename,
+  const char *funcname,
+  size_t linenr)
+{
+size_t dest_len = 0;
+size_t src_len = 0;
+
+if (!src)
+return 0;
+
+if (*dest)
+dest_len = strlen(*dest);
+src_len = strlen(src);
+
+if (virReallocN(dest, sizeof(*dest), dest_len + src_len + 1,
+report, domcode, filename, funcname, linenr) < 0)
+return -1;
+
+strcat(*dest, src);
+
+return 1;
+}
+
+
+/**
+ * virStrcat
+ * @dest: where to store concatenated string
+ * @src: the source string to append to @dest
+ *
+ * Wrapper over strcat, which properly handles if @src is NULL.
+ *
+ * Returns: 0 for NULL src, 1 on successful concatenate.
+ */
+int
+virStrcatInplace(char *dest, const char *src)
+{
+if (!src)
+return 0;
+
+strcat(dest, src);
+
+return 1;
+}
+
+
 size_t virStringListLength(const char * const *strings)
 {
 size_t i = 0;
diff --git a/src/util/virstring.h b/src/util/virstring.h
index a5550e30d2..79d2f23c80 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -131,6 +131,13 @@ int virStrdup(char **dest, const char *src, bool report, 
int domcode,
 int virStrndup(char **dest, const char *src, ssize_t n, bool report, int 
domcode,
const char *filename, const char *funcname, size_t linenr)
 ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+
+int virStrcat(char **dest, const char *src, bool report, int domcode,
+  const char *filename, const char *funcname, size_t linenr)
+ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+int virStrcatInplace(char *dest, const char *src)
+ATTRIBUTE_NONNULL(1);
+
 int virAsprintfInternal(bool report, int domcode, const char *filename,
 const char *funcname, size_t linenr, char **strp,
 const char *fmt, ...)
@@ -209,6 +216,26 @@ int virVasprintfInternal(bool report, int domcode, const 
char *filename,
 # define VIR_STRNDUP_QUIET(dst, src, n) virStrndup(&(dst), src, n, false, \
0, NULL, NULL, 0)
 
+/**
+ * VIR_STRCAT:
+ * @dst: variable to hold result (char*, not char**)
+ * @src: string to concatenate to @dst
+ *
+ * Concatenate @src string into @dst string, @dst may be NULL.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
+ * VIR_STRCAT_INPLACE expect the @dst to be already allocated to hold
+ * the result.
+ *
+ * Returns -1 on failure, 0 if @src was NULL, 1 if @src was concatenated.
+ */
+# define VIR_STRCAT(dst, src) virStrcat(&(dst), src, true, VIR_FROM_THIS, \

[libvirt] [PATCH 0/5] virstring and virbuffer improvements and bug fix

2017-02-23 Thread Pavel Hrdina
Pavel Hrdina (5):
  util: virstring: introduce virStrcat and VIR_STRCAT
  util: use VIR_STRCAT instead of strcat
  util: virbuffer: introduce virBufferEscapeN
  util: virqemu: introduce virQEMUBuildBufferEscape
  qemu: properly escape socket path for graphics

 cfg.mk |  16 ++--
 src/libvirt_private.syms   |   4 +
 src/qemu/qemu_command.c|   6 +-
 src/storage/storage_backend_logical.c  |   6 +-
 src/test/test_driver.c |   2 +-
 src/util/virbuffer.c   | 104 +
 src/util/virbuffer.h   |   2 +
 src/util/vircgroup.c   |   4 +-
 src/util/virqemu.c |  17 
 src/util/virqemu.h |   1 +
 src/util/virstring.c   |  70 ++
 src/util/virstring.h   |  27 ++
 src/xen/xend_internal.c|   2 +-
 .../qemuxml2argvdata/qemuxml2argv-name-escape.args |   5 +-
 .../qemuxml2argvdata/qemuxml2argv-name-escape.xml  |   7 +-
 tests/qemuxml2argvtest.c   |   3 +-
 tests/virbuftest.c |  41 
 tests/virstringtest.c  |  49 ++
 18 files changed, 345 insertions(+), 21 deletions(-)

-- 
2.11.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] 1GB huge pages and incompatible VM memory size

2017-02-23 Thread Matt Fleming
On Tue, 21 Feb, at 11:23:52AM, Michal Privoznik wrote:
> 
> Jim,
> 
> what is the actual problem? I've tried to reproduce this by running vm
> with 3.5G RAM backed by 1GB huge pages and the guest runs just fine. I
> mean kvm guest. This is because at the cmd line level there is aligned
> value:
> 
> -m size=4194304k,slots=16,maxmem=8388608k
> 
> This is result of qemuDomainAlignMemorySizes(). So perhaps there's a bug
> somewhere in the function?

Quite possibly. Some memory values work fine and appear to be rounded
to the next gigabyte boundary. One KiB values that fails for me is,

  52428801
  52428801

Which results in qemu-kvm ... -m 51201

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 04/14] qemu: Introduce QEMU_CAPS_DEVICE_NVDIMM

2017-02-23 Thread Michal Privoznik
On 02/23/2017 10:02 AM, Michal Privoznik wrote:
> Introduce a qemu capability for -device nvdimm.
> 
> Signed-off-by: Michal Privoznik 
> ---
>  src/qemu/qemu_capabilities.c | 2 ++
>  src/qemu/qemu_capabilities.h | 1 +
>  tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 +
>  tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 +
>  tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 +
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 +
>  6 files changed, 7 insertions(+)

Based on the conversation under 05/14 you can assume the following is squashed 
in:

diff --git i/src/qemu/qemu_capabilities.c w/src/qemu/qemu_capabilities.c
index 0e3f74de5..466931890 100644
--- i/src/qemu/qemu_capabilities.c
+++ w/src/qemu/qemu_capabilities.c
@@ -4356,6 +4356,13 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 virQEMUCapsProbeQMPGICCapabilities(qemuCaps, mon) < 0)
 goto cleanup;
 
+/* Prealloc on NVDIMMs is broken on older QEMUs leading to
+ * user data corruption. If we are dealing with such version
+ * of QEMU pretend we don't know how to NVDIMM. */
+if (qemuCaps->version < 2009000 &&
+virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
+virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);
+
 ret = 0;
  cleanup:
 return ret;


Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 10/10] news: Update the news.xml about perf events added

2017-02-23 Thread Nitesh Konkar
Signed-off-by: Nitesh Konkar 
---
 docs/news.xml | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/docs/news.xml b/docs/news.xml
index 74dfe9a..9a5f4c5 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -130,6 +130,17 @@
   driver with all backends which may pull in too many dependencies.
 
   
+  
+
+  perf: Add more perf statistics
+
+
+  Add support to get the count of cpu clock time, task clock time,
+  page faults, context switches, cpu migrations, minor page faults,
+  major page faults, alignment faults, emulation faults by
+  applications running on the platform.
+
+  
 
 
   
-- 
1.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 08/10] perf: add alignment_faults software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the alignment_faults perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  8 
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 10 ++
 src/libvirt-domain.c|  3 +++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  6 +-
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3d94441..3761a5d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1943,6 +1943,7 @@
   
   
   
+  
 
 ...
 
@@ -2071,6 +2072,13 @@
   applications running on the platform
   perf.page_faults_maj
 
+
+  alignment_faults
+  the count of alignment faults, that is when
+  the load or store is not aligned properly, by
+  applications running on the platform
+  perf.alignment_faults
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 82327c6..1f0c729 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -440,6 +440,7 @@
   cpu_migrations
   page_faults_min
   page_faults_maj
+  alignment_faults
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index f6e5c5a..0c0fb18 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2260,6 +2260,16 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_PAGE_FAULTS_MAJ  "page_faults_maj"
 
+/**
+ * VIR_PERF_PARAM_ALIGNMENT_FAULTS:
+ *
+ * Macro for typed parameter name that represents alignment_faults
+ * perf event which can be used to measure the count of alignment
+ * faults by applications running on the platform. It corresponds
+ * to the "perf.alignment_faults" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_ALIGNMENT_FAULTS  "alignment_faults"
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 21f91de..336e172 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11269,6 +11269,9 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * "perf.page_faults_maj" - The count of major page faults as unsigned
  *  long long. It is produced by the
  *  page_faults_maj perf event.
+ * "perf.alignment_faults" - The count of alignment faults as unsigned
+ *   long long. It is produced by the
+ *   alignment_faults perf event
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5448119..c58c7b0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9576,6 +9576,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_CPU_MIGRATIONS, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_PAGE_FAULTS_MIN, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_PAGE_FAULTS_MAJ, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_ALIGNMENT_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index b3dd5c7..3f01596 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -46,7 +46,8 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "stalled_cycles_backend", "ref_cpu_cycles",
   "cpu_clock", "task_clock", "page_faults",
   "context_switches", "cpu_migrations",
-  "page_faults_min", "page_faults_maj");
+  "page_faults_min", "page_faults_maj",
+  "alignment_faults");
 
 struct virPerfEvent {
 int type;
@@ -136,6 +137,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_PAGE_FAULTS_MAJ,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_PAGE_FAULTS_MAJ},
+{.type = VIR_PERF_EVENT_ALIGNMENT_FAULTS,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_ALIGNMENT_FAULTS},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 

[libvirt] [PATCH v2 07/10] perf: add page_faults_maj software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the page_faults_maj perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  9 +
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 10 ++
 src/libvirt-domain.c|  3 +++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  5 -
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0d2834b..3d94441 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1942,6 +1942,7 @@
   
   
   
+  
 
 ...
 
@@ -2062,6 +2063,14 @@
   applications running on the platform
   perf.page_faults_min
 
+
+  page_faults_maj
+  the count of major page faults, that is, where the
+  page was not present in the page cache, and
+  therefore had to be fetched from storage, by
+  applications running on the platform
+  perf.page_faults_maj
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index b8914d5..82327c6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -439,6 +439,7 @@
   context_switches
   cpu_migrations
   page_faults_min
+  page_faults_maj
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index b7e6c71..f6e5c5a 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2250,6 +2250,16 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_PAGE_FAULTS_MIN  "page_faults_min"
 
+/**
+ * VIR_PERF_PARAM_PAGE_FAULTS_MAJ:
+ *
+ * Macro for typed parameter name that represents page_faults_maj
+ * perf event which can be used to measure the count of major page
+ * faults by applications running on the platform. It corresponds
+ * to the "perf.page_faults_maj" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_PAGE_FAULTS_MAJ  "page_faults_maj"
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 2e95532..21f91de 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11266,6 +11266,9 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * "perf.page_faults_min" - The count of minor page faults as unsigned
  *  long long. It is produced by the
  *  page_faults_min perf event.
+ * "perf.page_faults_maj" - The count of major page faults as unsigned
+ *  long long. It is produced by the
+ *  page_faults_maj perf event.
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8523e1f..5448119 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9575,6 +9575,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_CONTEXT_SWITCHES, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_CPU_MIGRATIONS, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_PAGE_FAULTS_MIN, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_PAGE_FAULTS_MAJ, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 9e41df9..b3dd5c7 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -46,7 +46,7 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "stalled_cycles_backend", "ref_cpu_cycles",
   "cpu_clock", "task_clock", "page_faults",
   "context_switches", "cpu_migrations",
-  "page_faults_min");
+  "page_faults_min", "page_faults_maj");
 
 struct virPerfEvent {
 int type;
@@ -133,6 +133,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_PAGE_FAULTS_MIN,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_PAGE_FAULTS_MIN},
+{.type = VIR_PERF_EVENT_PAGE_FAULTS_MAJ,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_PAGE_FAULTS_MAJ},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 
dif

[libvirt] [PATCH v2 06/10] perf: add page_faults_min software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the page_faults_min perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  9 +
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 10 ++
 src/libvirt-domain.c|  3 +++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  6 +-
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 49f1e5e..0d2834b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1941,6 +1941,7 @@
   
   
   
+  
 
 ...
 
@@ -2053,6 +2054,14 @@
   applications running on the platform
   perf.cpu_migrations
 
+
+  page_faults_min
+  the count of minor page faults, that is, where the
+  page was present in the page cache, and therefore
+  the fault avoided loading it from storage, by
+  applications running on the platform
+  perf.page_faults_min
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a14b18a..b8914d5 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -438,6 +438,7 @@
   page_faults
   context_switches
   cpu_migrations
+  page_faults_min
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 7e24f50..b7e6c71 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2240,6 +2240,16 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_CPU_MIGRATIONS "cpu_migrations"
 
+/**
+ * VIR_PERF_PARAM_PAGE_FAULTS_MIN:
+ *
+ * Macro for typed parameter name that represents page_faults_min
+ * perf event which can be used to measure the count of minor page
+ * faults by applications running on the platform. It corresponds
+ * to the "perf.page_faults_min" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_PAGE_FAULTS_MIN  "page_faults_min"
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 27be5cd..2e95532 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11263,6 +11263,9 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * processor to another, as unsigned long
  * long. It is produced by the cpu_migrations
  * perf event.
+ * "perf.page_faults_min" - The count of minor page faults as unsigned
+ *  long long. It is produced by the
+ *  page_faults_min perf event.
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 640d06b..8523e1f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9574,6 +9574,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_PAGE_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_CONTEXT_SWITCHES, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_CPU_MIGRATIONS, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_PAGE_FAULTS_MIN, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 0127c82..9e41df9 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -45,7 +45,8 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "bus_cycles", "stalled_cycles_frontend",
   "stalled_cycles_backend", "ref_cpu_cycles",
   "cpu_clock", "task_clock", "page_faults",
-  "context_switches", "cpu_migrations");
+  "context_switches", "cpu_migrations",
+  "page_faults_min");
 
 struct virPerfEvent {
 int type;
@@ -129,6 +130,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_CPU_MIGRATIONS,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_CPU_MIGRATIONS},
+{.type = VIR_PERF_EVENT_PAGE_FAULTS_MIN,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_PAGE_FAULTS_MIN},
 };
 typedef struct virPerfEven

[libvirt] [PATCH v2 09/10] perf: add emulation_faults software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the emulation_faults perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  9 +
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 10 ++
 src/libvirt-domain.c|  3 +++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  5 -
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3761a5d..8891ed9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1944,6 +1944,7 @@
   
   
   
+  
 
 ...
 
@@ -2079,6 +2080,14 @@
   applications running on the platform
   perf.alignment_faults
 
+
+  emulation_faults
+  the count of emulation faults, that is when
+  the kernel traps on unimplemented instrucions
+  and emulates them for user space, by
+  applications running on the platform
+  perf.emulation_faults
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1f0c729..1860f90 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -441,6 +441,7 @@
   page_faults_min
   page_faults_maj
   alignment_faults
+  emulation_faults
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 0c0fb18..c490d71 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2270,6 +2270,16 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_ALIGNMENT_FAULTS  "alignment_faults"
 
+/**
+ * VIR_PERF_PARAM_EMULATION_FAULTS:
+ *
+ * Macro for typed parameter name that represents emulation_faults
+ * perf event which can be used to measure the count of emulation
+ * faults by applications running on the platform. It corresponds
+ * to the "perf.emulation_faults" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_EMULATION_FAULTS  "emulation_faults"
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 336e172..5088f47 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11272,6 +11272,9 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * "perf.alignment_faults" - The count of alignment faults as unsigned
  *   long long. It is produced by the
  *   alignment_faults perf event
+ * "perf.emulation_faults" - The count of emulation faults as unsigned
+ *   long long. It is produced by the
+ *   emulation_faults perf event
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c58c7b0..51d0b5f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9577,6 +9577,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_PAGE_FAULTS_MIN, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_PAGE_FAULTS_MAJ, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_ALIGNMENT_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_EMULATION_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 3f01596..e39cebb 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -47,7 +47,7 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "cpu_clock", "task_clock", "page_faults",
   "context_switches", "cpu_migrations",
   "page_faults_min", "page_faults_maj",
-  "alignment_faults");
+  "alignment_faults", "emulation_faults");
 
 struct virPerfEvent {
 int type;
@@ -140,6 +140,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_ALIGNMENT_FAULTS,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_ALIGNMENT_FAULTS},
+{.type = VIR_PERF_EVENT_EMULATION_FAULTS,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_EMULATION_FAULTS},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPt

[libvirt] [PATCH v2 05/10] perf: add cpu_migrations software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the cpu_migrations perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   | 8 
 docs/schemas/domaincommon.rng   | 1 +
 include/libvirt/libvirt-domain.h| 9 +
 src/libvirt-domain.c| 4 
 src/qemu/qemu_driver.c  | 1 +
 src/util/virperf.c  | 5 -
 src/util/virperf.h  | 1 +
 tests/genericxml2xmlindata/generic-perf.xml | 1 +
 tools/virsh.pod | 3 +++
 9 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index bff699f..49f1e5e 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1940,6 +1940,7 @@
   
   
   
+  
 
 ...
 
@@ -2045,6 +2046,13 @@
   the platform
   perf.context_switches
 
+
+  cpu_migrations
+  the count of cpu migrations, that is, where the process
+  moved from one logical processor to another, by
+  applications running on the platform
+  perf.cpu_migrations
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1a4b6cb..a14b18a 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -437,6 +437,7 @@
   task_clock
   page_faults
   context_switches
+  cpu_migrations
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index f7e4cd2..7e24f50 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2230,6 +2230,15 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_CONTEXT_SWITCHES "context_switches"
 
+/**
+ * VIR_PERF_PARAM_CPU_MIGRATIONS:
+ *
+ * Macro for typed parameter name that represents cpu_migrations
+ * perf event which can be used to measure the count of cpu
+ * migrations by applications running on the platform. It corresponds
+ * to the "perf.cpu_migrations" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_CPU_MIGRATIONS "cpu_migrations"
 
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 6b29d14..27be5cd 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11259,6 +11259,10 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * "perf.context_switches" - The count of context switches as unsigned long
  *   long. It is produced by the context_switches
  *   perf event.
+ * "perf.cpu_migrations" - The count of cpu migrations, from one logical
+ * processor to another, as unsigned long
+ * long. It is produced by the cpu_migrations
+ * perf event.
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8d6df1a..640d06b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9573,6 +9573,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_TASK_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_PAGE_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_CONTEXT_SWITCHES, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_CPU_MIGRATIONS, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index ba81e08..0127c82 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -45,7 +45,7 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "bus_cycles", "stalled_cycles_frontend",
   "stalled_cycles_backend", "ref_cpu_cycles",
   "cpu_clock", "task_clock", "page_faults",
-  "context_switches");
+  "context_switches", "cpu_migrations");
 
 struct virPerfEvent {
 int type;
@@ -126,6 +126,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_CONTEXT_SWITCHES,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_CONTEXT_SWITCHES},
+{.type = VIR_PERF_EVENT_CPU_MIGRATIONS,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_CPU_MIGRATIONS},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 
diff --git a/src/util/virperf.h b/src/util/virperf.h
index 2adc549..90ae007 100644
--- a/s

[libvirt] [PATCH v2 04/10] perf: add context_switches software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the context_switches perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  7 +++
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 10 ++
 src/libvirt-domain.c|  3 +++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  6 +-
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 72d33fa..bff699f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1939,6 +1939,7 @@
   
   
   
+  
 
 ...
 
@@ -2038,6 +2039,12 @@
   types of page faults
   perf.page_faults
 
+
+  context_switches
+  the count of context switches by applications running on
+  the platform
+  perf.context_switches
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 856a2f7..1a4b6cb 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -436,6 +436,7 @@
   cpu_clock
   task_clock
   page_faults
+  context_switches
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 1a6cb19..f7e4cd2 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2220,6 +2220,16 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
 */
 # define VIR_PERF_PARAM_PAGE_FAULTS "page_faults"
 
+/**
+ * VIR_PERF_PARAM_CONTEXT_SWITCHES:
+ *
+ * Macro for typed parameter name that represents context_switches
+ * perf event which can be used to measure the count of context
+ * switches by applications running on the platform. It corresponds
+ * to the "perf.context_switches" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_CONTEXT_SWITCHES "context_switches"
+
 
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 77c6e8a..6b29d14 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11256,6 +11256,9 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * It is produced by the task_clock perf event.
  * "perf.page_faults" - The count of page faults as unsigned long long.
  *  It is produced by the page_faults perf event
+ * "perf.context_switches" - The count of context switches as unsigned long
+ *   long. It is produced by the context_switches
+ *   perf event.
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 10d4e59..8d6df1a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9572,6 +9572,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_CPU_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_TASK_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_PAGE_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_CONTEXT_SWITCHES, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 4ae13af..ba81e08 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -44,7 +44,8 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "branch_instructions", "branch_misses",
   "bus_cycles", "stalled_cycles_frontend",
   "stalled_cycles_backend", "ref_cpu_cycles",
-  "cpu_clock", "task_clock", "page_faults");
+  "cpu_clock", "task_clock", "page_faults",
+  "context_switches");
 
 struct virPerfEvent {
 int type;
@@ -122,6 +123,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_PAGE_FAULTS,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_PAGE_FAULTS},
+{.type = VIR_PERF_EVENT_CONTEXT_SWITCHES,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_CONTEXT_SWITCHES},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 
diff --git a/src/util/virperf.h b/src/util/virperf.h
index 182a9ec..2adc549 100644
--- a/src/util/virperf.h
+++ b/src/util/virperf.h
@@ -50,6 +50,7 @@ typedef

[libvirt] [PATCH v2 03/10] perf: add page_faults software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation
for the page_faults perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  8 
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 11 +++
 src/libvirt-domain.c|  2 ++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  5 -
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 2840e3c..72d33fa 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1938,6 +1938,7 @@
   
   
   
+  
 
 ...
 
@@ -2030,6 +2031,13 @@
   is run by applications running on the platform
   perf.task_clock
 
+
+  page_faults
+  the count of page faults by applications running on the
+  platform. This includes minor, major, invalid and other
+  types of page faults
+  perf.page_faults
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 64b5bfc..856a2f7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -435,6 +435,7 @@
   ref_cpu_cycles
   cpu_clock
   task_clock
+  page_faults
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 2495c90..1a6cb19 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2210,6 +2210,17 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_TASK_CLOCK "task_clock"
 
+/**
+* VIR_PERF_PARAM_PAGE_FAULTS:
+*
+* Macro for typed parameter name that represents page_faults
+* perf event which can be used to measure the count of page
+* faults by applications running on the platform. It corresponds
+* to the "perf.page_faults" field in the *Stats APIs.
+*/
+# define VIR_PERF_PARAM_PAGE_FAULTS "page_faults"
+
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index c3db338..77c6e8a 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11254,6 +11254,8 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  *It is produced by the cpu_clock perf event.
  * "perf.task_clock" - The count of task clock time as unsigned long long.
  * It is produced by the task_clock perf event.
+ * "perf.page_faults" - The count of page faults as unsigned long long.
+ *  It is produced by the page_faults perf event
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index fdbb84b..10d4e59 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9571,6 +9571,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_REF_CPU_CYCLES, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_CPU_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_TASK_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_PAGE_FAULTS, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 16301fd..4ae13af 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -44,7 +44,7 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "branch_instructions", "branch_misses",
   "bus_cycles", "stalled_cycles_frontend",
   "stalled_cycles_backend", "ref_cpu_cycles",
-  "cpu_clock", "task_clock");
+  "cpu_clock", "task_clock", "page_faults");
 
 struct virPerfEvent {
 int type;
@@ -119,6 +119,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_TASK_CLOCK,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_TASK_CLOCK},
+{.type = VIR_PERF_EVENT_PAGE_FAULTS,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_PAGE_FAULTS},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 
diff --git a/src/util/virperf.h b/src/util/virperf.h
index bfff8fc..182a9ec 100644
--- a/src/util/virperf.h
+++ b/src/util/virperf.h
@@ -49,6 +49,7 @@ typedef enum {
 VIR_PERF_EVENT_REF_CPU

[libvirt] [PATCH v2 02/10] perf: add task_clock software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation for
the task_clock perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  8 
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 11 +++
 src/libvirt-domain.c|  2 ++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  5 -
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 403932b..2840e3c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1937,6 +1937,7 @@
   
   
   
+  
 
 ...
 
@@ -2022,6 +2023,13 @@
   the platform
   perf.cpu_clock
 
+
+  task_clock
+  the count of task clock time, as measured by a monotonic
+  high-resolution CPU timer, specific to the task that
+  is run by applications running on the platform
+  perf.task_clock
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8f52830..64b5bfc 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -434,6 +434,7 @@
   stalled_cycles_backend
   ref_cpu_cycles
   cpu_clock
+  task_clock
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index d594121..2495c90 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2199,6 +2199,17 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_CPU_CLOCK "cpu_clock"
 
+/**
+ * VIR_PERF_PARAM_TASK_CLOCK:
+ *
+ * Macro for typed parameter name that represents task_clock
+ * perf event which can be used to measure the count of task
+ * clock time by applications running on the platform. It
+ * corresponds to the "perf.task_clock" field in the *Stats
+ * APIs.
+ */
+# define VIR_PERF_PARAM_TASK_CLOCK "task_clock"
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 427101f..c3db338 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11252,6 +11252,8 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * ref_cpu_cycles perf event.
  * "perf.cpu_clock" - The count of cpu clock time as unsigned long long.
  *It is produced by the cpu_clock perf event.
+ * "perf.task_clock" - The count of task clock time as unsigned long long.
+ * It is produced by the task_clock perf event.
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d64db3f..fdbb84b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9570,6 +9570,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_STALLED_CYCLES_BACKEND, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_REF_CPU_CYCLES, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_CPU_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_TASK_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 2d6cbbb..16301fd 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -44,7 +44,7 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "branch_instructions", "branch_misses",
   "bus_cycles", "stalled_cycles_frontend",
   "stalled_cycles_backend", "ref_cpu_cycles",
-  "cpu_clock");
+  "cpu_clock", "task_clock");
 
 struct virPerfEvent {
 int type;
@@ -116,6 +116,9 @@ static struct virPerfEventAttr attrs[] = {
 {.type = VIR_PERF_EVENT_CPU_CLOCK,
  .attrType = PERF_TYPE_SOFTWARE,
  .attrConfig = PERF_COUNT_SW_CPU_CLOCK},
+{.type = VIR_PERF_EVENT_TASK_CLOCK,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_TASK_CLOCK},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 
diff --git a/src/util/virperf.h b/src/util/virperf.h
index 8a7270c..bfff8fc 100644
--- a/src/util/virperf.h
+++ b/src/util/virperf.h
@@ -48,6 +48,7 @@ typedef enum {
   pr

[libvirt] [PATCH v2 01/10] perf: add cpu_clock software perf event support

2017-02-23 Thread Nitesh Konkar
This patch adds support and documentation for
the cpu_clock perf event.

Signed-off-by: Nitesh Konkar 
---
 docs/formatdomain.html.in   |  8 
 docs/schemas/domaincommon.rng   |  1 +
 include/libvirt/libvirt-domain.h| 11 +++
 src/libvirt-domain.c|  2 ++
 src/qemu/qemu_driver.c  |  1 +
 src/util/virperf.c  |  6 +-
 src/util/virperf.h  |  1 +
 tests/genericxml2xmlindata/generic-perf.xml |  1 +
 tools/virsh.pod |  3 +++
 9 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 02ce792..403932b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1936,6 +1936,7 @@
   
   
   
+  
 
 ...
 
@@ -2014,6 +2015,13 @@
  by applications running on the platform
   perf.ref_cpu_cycles
 
+
+  cpu_clock
+  the count of cpu clock time, as measured by a monotonic
+  high-resolution per-CPU timer, by applications running on
+  the platform
+  perf.cpu_clock
+
   
 
 Devices
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index c64544a..8f52830 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -433,6 +433,7 @@
   stalled_cycles_frontend
   stalled_cycles_backend
   ref_cpu_cycles
+  cpu_clock
 
   
   
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index c0f715d..d594121 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2188,6 +2188,17 @@ void 
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
  */
 # define VIR_PERF_PARAM_REF_CPU_CYCLES "ref_cpu_cycles"
 
+/**
+ * VIR_PERF_PARAM_CPU_CLOCK:
+ *
+ * Macro for typed parameter name that represents cpu_clock
+ * perf event which can be used to measure the count of cpu
+ * clock time by applications running on the platform. It
+ * corresponds to the "perf.cpu_clock" field in the *Stats
+ * APIs.
+ */
+# define VIR_PERF_PARAM_CPU_CLOCK "cpu_clock"
+
 int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 619a9fc..427101f 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11250,6 +11250,8 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * CPU frequency scaling by applications running
  * as unsigned long long. It is produced by the
  * ref_cpu_cycles perf event.
+ * "perf.cpu_clock" - The count of cpu clock time as unsigned long long.
+ *It is produced by the cpu_clock perf event.
  *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6e1e3d4..d64db3f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9569,6 +9569,7 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_STALLED_CYCLES_BACKEND, 
VIR_TYPED_PARAM_BOOLEAN,
VIR_PERF_PARAM_REF_CPU_CYCLES, 
VIR_TYPED_PARAM_BOOLEAN,
+   VIR_PERF_PARAM_CPU_CLOCK, 
VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
 return -1;
 
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 4493608..2d6cbbb 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -43,7 +43,8 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
   "cache_references", "cache_misses",
   "branch_instructions", "branch_misses",
   "bus_cycles", "stalled_cycles_frontend",
-  "stalled_cycles_backend", "ref_cpu_cycles");
+  "stalled_cycles_backend", "ref_cpu_cycles",
+  "cpu_clock");
 
 struct virPerfEvent {
 int type;
@@ -112,6 +113,9 @@ static struct virPerfEventAttr attrs[] = {
  .attrConfig = 0,
 # endif
 },
+{.type = VIR_PERF_EVENT_CPU_CLOCK,
+ .attrType = PERF_TYPE_SOFTWARE,
+ .attrConfig = PERF_COUNT_SW_CPU_CLOCK},
 };
 typedef struct virPerfEventAttr *virPerfEventAttrPtr;
 
diff --git a/src/util/virperf.h b/src/util/virperf.h
index 1f43c92..8a7270c 100644
--- a/src/util/virperf.h
+++ b/src/util/virperf.h
@@ -47,6 +47,7 @@ typedef enum {
   

[libvirt] [PATCH v2 00/10] perf: Add software perf events

2017-02-23 Thread Nitesh Konkar
This patch series adds software perf events.
The perl and go patches shall follow shortly.

Nitesh Konkar (10):
  perf: add cpu_clock software perf event support
  perf: add task_clock software perf event support
  perf: add page_faults software perf event support
  perf: add context_switches software perf event support
  perf: add cpu_migrations software perf event support
  perf: add page_faults_min software perf event support
  perf: add page_faults_maj software perf event support
  perf: add alignment_faults software perf event support
  perf: add emulation_faults software perf event support
  news: Update the news.xml about perf events added

 docs/formatdomain.html.in   | 74 +++
 docs/news.xml   | 11 
 docs/schemas/domaincommon.rng   |  9 +++
 include/libvirt/libvirt-domain.h| 92 +
 src/libvirt-domain.c| 25 
 src/qemu/qemu_driver.c  |  9 +++
 src/util/virperf.c  | 33 ++-
 src/util/virperf.h  |  9 +++
 tests/genericxml2xmlindata/generic-perf.xml |  9 +++
 tools/virsh.pod | 27 +
 10 files changed, 297 insertions(+), 1 deletion(-)

-- 
1.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] qemu: Fix incorrect jump labels in error paths

2017-02-23 Thread Michal Privoznik
On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
> Fix incorrect jump labels in error paths as the stop jump is only
> needed if the driver has already changed the state. For example
> 'virAtomicIntInc(&driver->nactive)' will be 'reverted' in the
> qemuProcessStop call.
> 
> Signed-off-by: Marc Hartmayer 
> Reviewed-by: Boris Fiuczynski 
> ---
>  src/qemu/qemu_process.c | 13 -
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index ea10fff..a57d136 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4755,9 +4755,12 @@ qemuProcessInit(virQEMUDriverPtr driver,
>   */
>  VIR_DEBUG("Setting current domain def as transient");
>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
> -goto stop;
> +goto cleanup;
>  
> -if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) {
> +if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
> +if (qemuDomainSetPrivatePaths(driver, vm) < 0)
> +goto cleanup;

This should have been goto stop; After SetDefTransien() succeeds,
everything must goto stop in order to call qemuProcessStop which undoes
the SetDefTransient(). I will fix it before pushing.

> +} else {
>  vm->def->id = qemuDriverAllocateID(driver);
>  qemuDomainSetFakeReboot(driver, vm, false);
>  virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, 
> VIR_DOMAIN_PAUSED_STARTING_UP);
> @@ -4770,10 +4773,10 @@ qemuProcessInit(virQEMUDriverPtr driver,
>   VIR_HOOK_QEMU_OP_PREPARE,
>   VIR_HOOK_SUBOP_BEGIN) < 0)
>  goto stop;
> -}
>  
> -if (qemuDomainSetPrivatePaths(driver, vm) < 0)
> -goto cleanup;
> +if (qemuDomainSetPrivatePaths(driver, vm) < 0)
> +goto stop;
> +}
>  
>  ret = 0;
>  
> 

ACKed and pushed.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/2] qemu: Validate the domain after marking the current domain as transient

2017-02-23 Thread Michal Privoznik
On 02/23/2017 10:44 AM, Marc Hartmayer wrote:
> Validate the domain that actually will be started. It's semantically
> more clear and also it can detect failures that may have happened in
> virDomainObjSetDefTransient().
> 
> Signed-off-by: Marc Hartmayer 
> Reviewed-by: Bjoern Walk 
> Reviewed-by: Boris Fiuczynski 
> ---
>  src/qemu/qemu_process.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index a57d136..bd3a8b8 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4746,9 +4746,6 @@ qemuProcessInit(virQEMUDriverPtr driver,
>vm->def->os.machine)))
>  goto cleanup;
>  
> -if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 
> 0)
> -goto cleanup;
> -
>  /* Do this upfront, so any part of the startup process can add
>   * runtime state to vm->def that won't be persisted. This let's us
>   * report implicit runtime defaults in the XML, like vnc listen/socket
> @@ -4757,6 +4754,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
>  if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm) < 0)
>  goto cleanup;
>  
> +if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 
> 0)
> +goto cleanup;
> +

This needs to be goto stop for the reasons described in the previous e-mail.

>  if (flags & VIR_QEMU_PROCESS_START_PRETEND) {
>  if (qemuDomainSetPrivatePaths(driver, vm) < 0)
>  goto cleanup;
> 

Honestly, I like what we have now better. I mean, SetDefTransient() is
very unlikely to fail. It's just doing a copy of domain definition (in a
very stupid way, but lets save that for a different discussion).
Basically, it will fail on OOM only (which you will not get on a Linux
system, unless you really try).
However, the StartValidate() just reads some data without any
allocation. Thus, from memory management POV, should your domain be
unable to start we don't allocate any memory just to find that out.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v3 24/28] cputest: Convert all json data files to query-cpu-model-expansion

2017-02-23 Thread Jiri Denemark
Converted by running the following command, renaming the files as
*.new, and committing only the *.new files.

(cd tests/cputestdata; ./cpu-convert.py *.json)

Signed-off-by: Jiri Denemark 
---

Notes:
Version 3:
- no change

Version 2:
- reconverted to contain "vendor" properties

 tests/cputestdata/x86_64-cpuid-A10-5800K.json.new  | 203 +
 .../cputestdata/x86_64-cpuid-Core-i5-2500.json.new | 203 +
 .../x86_64-cpuid-Core-i5-2540M.json.new| 203 +
 .../x86_64-cpuid-Core-i5-4670T.json.new| 203 +
 .../cputestdata/x86_64-cpuid-Core-i5-6600.json.new | 203 +
 .../cputestdata/x86_64-cpuid-Core-i7-2600.json.new | 203 +
 .../x86_64-cpuid-Core-i7-3740QM.json.new   | 203 +
 .../cputestdata/x86_64-cpuid-Core-i7-3770.json.new | 203 +
 .../x86_64-cpuid-Core-i7-4600U.json.new| 203 +
 .../x86_64-cpuid-Core-i7-5600U.json.new| 203 +
 .../cputestdata/x86_64-cpuid-Core2-E6850.json.new  | 203 +
 .../cputestdata/x86_64-cpuid-Opteron-2350.json.new | 203 +
 .../cputestdata/x86_64-cpuid-Opteron-6234.json.new | 203 +
 tests/cputestdata/x86_64-cpuid-Phenom-B95.json.new | 203 +
 .../cputestdata/x86_64-cpuid-Xeon-E3-1245.json.new | 203 +
 .../cputestdata/x86_64-cpuid-Xeon-E5-2630.json.new | 203 +
 .../cputestdata/x86_64-cpuid-Xeon-E5-2650.json.new | 203 +
 .../cputestdata/x86_64-cpuid-Xeon-E7-4820.json.new | 203 +
 tests/cputestdata/x86_64-cpuid-Xeon-W3520.json.new | 203 +
 19 files changed, 3857 insertions(+)
 create mode 100644 tests/cputestdata/x86_64-cpuid-A10-5800K.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-2500.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-2540M.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-4670T.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-6600.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-2600.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3770.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-4600U.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Core2-E6850.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-2350.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-6234.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Phenom-B95.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E3-1245.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.json.new
 create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-W3520.json.new

diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K.json.new 
b/tests/cputestdata/x86_64-cpuid-A10-5800K.json.new
new file mode 100644
index 0..132ed249b
--- /dev/null
+++ b/tests/cputestdata/x86_64-cpuid-A10-5800K.json.new
@@ -0,0 +1,203 @@
+{
+  "return": {
+"model": {
+  "name": "base",
+  "props": {
+"pfthreshold": false,
+"pku": false,
+"rtm": false,
+"tsc_adjust": true,
+"tsc-deadline": false,
+"xstore-en": false,
+"tsc-scale": false,
+"sse": true,
+"smap": false,
+"stepping": 1,
+"tce": false,
+"kvm_steal_time": true,
+"smep": false,
+"rdpid": false,
+"xcrypt": false,
+"sse4_2": true,
+"monitor": false,
+"sse4_1": true,
+"kvm-mmu": false,
+"flushbyasid": false,
+"kvm-steal-time": true,
+"lm": true,
+"tsc": true,
+"adx": false,
+"fxsr": true,
+"sha-ni": false,
+"tm": false,
+"pclmuldq": true,
+"xgetbv1": false,
+"xstore": false,
+"vmcb_clean": false,
+"vme": true,
+"vendor": "AuthenticAMD",
+"arat": false,
+"ffxsr": true,
+"de": true,
+"avx512f": false,
+"pse": true,
+"ds-cpl": false,
+"tbm": true,
+"ia64": false,
+"phe-en": false,
+"f16c": true,
+"ds": false,
+"mpx": false,
+"tsc-adjust": true,
+"aes": true,
+"avx2": false,
+"pbe": false,
+"cx16": true,
+"ds_cpl": false,
+"movbe": false,
+"perfctr-nb": false,
+"nrip_save": true,
+"kvm_mmu": false,
+"o

[libvirt] [PATCH v3 26/28] cputest: Drop obsolete CPU test data files

2017-02-23 Thread Jiri Denemark
Signed-off-by: Jiri Denemark 
---

Notes:
Version 3:
- no change

Version 2:
- no change

 tests/cputestdata/x86_64-cpuid-A10-5800K.json  | 77 ---
 tests/cputestdata/x86_64-cpuid-Core-i5-2500.json   | 88 --
 tests/cputestdata/x86_64-cpuid-Core-i5-2540M.json  | 82 
 tests/cputestdata/x86_64-cpuid-Core-i5-4670T.json  | 77 ---
 tests/cputestdata/x86_64-cpuid-Core-i5-6600.json   | 82 
 tests/cputestdata/x86_64-cpuid-Core-i7-2600.json   | 77 ---
 tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.json | 77 ---
 tests/cputestdata/x86_64-cpuid-Core-i7-3770.json   | 77 ---
 tests/cputestdata/x86_64-cpuid-Core-i7-4600U.json  | 82 
 tests/cputestdata/x86_64-cpuid-Core-i7-5600U.json  | 88 --
 tests/cputestdata/x86_64-cpuid-Core2-E6850.json| 77 ---
 tests/cputestdata/x86_64-cpuid-Opteron-2350.json   | 71 -
 tests/cputestdata/x86_64-cpuid-Opteron-6234.json   | 88 --
 tests/cputestdata/x86_64-cpuid-Phenom-B95.json | 77 ---
 tests/cputestdata/x86_64-cpuid-Xeon-E3-1245.json   | 88 --
 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630.json   | 77 ---
 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json   | 71 -
 tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.json   | 77 ---
 tests/cputestdata/x86_64-cpuid-Xeon-W3520.json | 77 ---
 19 files changed, 1510 deletions(-)
 delete mode 100644 tests/cputestdata/x86_64-cpuid-A10-5800K.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-2500.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-2540M.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-4670T.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-6600.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-2600.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3770.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-4600U.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Core2-E6850.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-2350.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-6234.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Phenom-B95.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E3-1245.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.json
 delete mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-W3520.json

diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K.json 
b/tests/cputestdata/x86_64-cpuid-A10-5800K.json
deleted file mode 100644
index 53b39ad03..0
--- a/tests/cputestdata/x86_64-cpuid-A10-5800K.json
+++ /dev/null
@@ -1,77 +0,0 @@
-{
-  "return": [
-{
-  "cpuid-register": "EAX",
-  "cpuid-input-ecx": 1,
-  "cpuid-input-eax": 13,
-  "features": 0
-},
-{
-  "cpuid-register": "EDX",
-  "cpuid-input-eax": 2147483658,
-  "features": 9
-},
-{
-  "cpuid-register": "EAX",
-  "cpuid-input-eax": 1073741825,
-  "features": 16777467
-},
-{
-  "cpuid-register": "EDX",
-  "cpuid-input-eax": 3221225473,
-  "features": 0
-},
-{
-  "cpuid-register": "EDX",
-  "cpuid-input-eax": 2147483655,
-  "features": 0
-},
-{
-  "cpuid-register": "ECX",
-  "cpuid-input-eax": 2147483649,
-  "features": 2165747
-},
-{
-  "cpuid-register": "EDX",
-  "cpuid-input-eax": 2147483649,
-  "features": 642779136
-},
-{
-  "cpuid-register": "EBX",
-  "cpuid-input-ecx": 0,
-  "cpuid-input-eax": 7,
-  "features": 10
-},
-{
-  "cpuid-register": "ECX",
-  "cpuid-input-eax": 1,
-  "features": 3065524739
-},
-{
-  "cpuid-register": "EDX",
-  "cpuid-input-eax": 1,
-  "features": 126614527
-}
-  ],
-  "id": "feature-words"
-}
-
-{
-  "return": 21,
-  "id": "family"
-}
-
-{
-  "return": 16,
-  "id": "model"
-}
-
-{
-  "return": 1,
-  "id": "stepping"
-}
-
-{
-  "return": "AMD A10-5800K APU with Radeon(tm) HD Graphics  ",
-  "id": "model-id"
-}
diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-2500.json 
b/tests/cputestdata/x86_64-cpuid-Core-i5-2500.json
deleted file mode 100644
index 156b77248..0
--- a/tests/cputestdata/x86_64-cpuid-Core-i5-2500.json
+++ /dev/null
@@ -1,88 +0,0 @@
-{
-  "return": [
-{
-  "cpuid-register": "EAX",
-  "cpuid-input-eax": 6,
-  "features": 4
-},
-{
-  "cpuid-register": "EAX",
-  "cpuid-input-ecx":

[libvirt] [PATCH v3 22/28] cputest: Use virArch enum rather then strings

2017-02-23 Thread Jiri Denemark
Signed-off-by: Jiri Denemark 
---

Notes:
Version 3:
- no change

Version 2:
- no change

 tests/cputest.c | 294 
 1 file changed, 148 insertions(+), 146 deletions(-)

diff --git a/tests/cputest.c b/tests/cputest.c
index 406b40dfe..c0a816b60 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -56,7 +56,7 @@ enum cpuTestBoolWithError {
 
 
 struct data {
-const char *arch;
+virArch arch;
 const char *host;
 const char *name;
 const char **models;
@@ -72,14 +72,15 @@ static virQEMUDriver driver;
 
 
 static virCPUDefPtr
-cpuTestLoadXML(const char *arch, const char *name)
+cpuTestLoadXML(virArch arch, const char *name)
 {
 char *xml = NULL;
 xmlDocPtr doc = NULL;
 xmlXPathContextPtr ctxt = NULL;
 virCPUDefPtr cpu = NULL;
 
-if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml", abs_srcdir, arch, name) 
< 0)
+if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml",
+abs_srcdir, virArchToString(arch), name) < 0)
 goto cleanup;
 
 if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
@@ -96,7 +97,7 @@ cpuTestLoadXML(const char *arch, const char *name)
 
 
 static virCPUDefPtr *
-cpuTestLoadMultiXML(const char *arch,
+cpuTestLoadMultiXML(virArch arch,
 const char *name,
 unsigned int *count)
 {
@@ -108,7 +109,8 @@ cpuTestLoadMultiXML(const char *arch,
 int n;
 size_t i;
 
-if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml", abs_srcdir, arch, name) 
< 0)
+if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml",
+abs_srcdir, virArchToString(arch), name) < 0)
 goto cleanup;
 
 if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
@@ -145,7 +147,7 @@ cpuTestLoadMultiXML(const char *arch,
 
 
 static int
-cpuTestCompareXML(const char *arch,
+cpuTestCompareXML(virArch arch,
   virCPUDef *cpu,
   const char *name,
   bool updateCPU)
@@ -155,7 +157,7 @@ cpuTestCompareXML(const char *arch,
 int ret = -1;
 
 if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml",
-abs_srcdir, arch, name) < 0)
+abs_srcdir, virArchToString(arch), name) < 0)
 goto cleanup;
 
 if (!(actual = virCPUDefFormat(cpu, NULL, updateCPU)))
@@ -457,7 +459,7 @@ cpuTestCPUID(bool guest, const void *arg)
 char *result = NULL;
 
 if (virAsprintf(&hostFile, "%s/cputestdata/%s-cpuid-%s.xml",
-abs_srcdir, data->arch, data->host) < 0)
+abs_srcdir, virArchToString(data->arch), data->host) < 0)
 goto cleanup;
 
 if (virTestLoadFile(hostFile, &host) < 0 ||
@@ -523,7 +525,7 @@ cpuTestJSONCPUID(const void *arg)
 int ret = -1;
 
 if (virAsprintf(&json, "%s/cputestdata/%s-cpuid-%s.json",
-abs_srcdir, data->arch, data->host) < 0 ||
+abs_srcdir, virArchToString(data->arch), data->host) < 0 ||
 virAsprintf(&result, "cpuid-%s-json", data->host) < 0)
 goto cleanup;
 
@@ -591,7 +593,7 @@ mymain(void)
 VIR_FREE(tmp);  \
 \
 if (virAsprintf(&testLabel, "%s(%s): %s",   \
-#api, arch, name) < 0) {\
+#api, virArchToString(arch), name) < 0) {   \
 ret = -1;   \
 break;  \
 }   \
@@ -677,159 +679,159 @@ mymain(void)
 } while (0)
 
 /* host to host comparison */
-DO_TEST_COMPARE("x86_64", "host", "host", VIR_CPU_COMPARE_IDENTICAL);
-DO_TEST_COMPARE("x86_64", "host", "host-better", 
VIR_CPU_COMPARE_INCOMPATIBLE);
-DO_TEST_COMPARE("x86_64", "host", "host-worse", VIR_CPU_COMPARE_SUPERSET);
-DO_TEST_COMPARE("x86_64", "host", "host-amd-fake", 
VIR_CPU_COMPARE_INCOMPATIBLE);
-DO_TEST_COMPARE("x86_64", "host", "host-incomp-arch", 
VIR_CPU_COMPARE_INCOMPATIBLE);
-DO_TEST_COMPARE("x86_64", "host", "host-no-vendor", 
VIR_CPU_COMPARE_IDENTICAL);
-DO_TEST_COMPARE("x86_64", "host-no-vendor", "host", 
VIR_CPU_COMPARE_INCOMPATIBLE);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host", 
VIR_CPU_COMPARE_IDENTICAL);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-better", 
VIR_CPU_COMPARE_INCOMPATIBLE);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-worse", 
VIR_CPU_COMPARE_SUPERSET);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-amd-fake", 
VIR_CPU_COMPARE_INCOMPATIBLE);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-incomp-arch", 
VIR_CPU_COMPARE_INCOMPATIBLE);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-no-vendor", 
VIR_CPU_COMPARE_IDENTICAL);
+DO_TEST_COMPARE(VIR_ARCH_X86_64, "host-no-vend

  1   2   >