[libvirt] [PATCH perl v2] Add constants for new perf event support
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- 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
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
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
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
--- 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
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
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
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
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
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
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
--- 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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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