[libvirt] [PATCH] qemu: Fix memory leak in processGuestPanicEvent
After processing the processEvent->data for a qemuProcessEventHandler callout, it's expected that the called processEvent->eventType helper will perform the proper free on the data field. In this case it's a qemuMonitorEventPanicInfoPtr. Signed-off-by: John Ferlan--- Noticed this while working through the DumpComplete patch series. One has to follow the bouncing ball, but will note that when the processEvent->data is passed to other cases, it ends up getting VIR_FREE()'d at the end of various functions, so this should too since it's at the end of the line. src/qemu/qemu_driver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a203c9297..5eaf97a46 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4309,6 +4309,7 @@ processGuestPanicEvent(virQEMUDriverPtr driver, qemuDomainRemoveInactiveJob(driver, vm); cleanup: +qemuMonitorEventPanicInfoFree(info); virObjectUnref(cfg); } -- 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] fix regex to check CN from server certificate
Currently when the script validates the PKI files and the certificate 'Subject:' field contains RDNs after the Common Name (CN), these values are also included, creating a false result that the CN is not correct. A small change to the sed regex fixes this issue, by extracting only the value for CN and nothing else. The regex is replaced with the exact same regex used to extract the CN value from the client certificate. --- tools/virt-pki-validate.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/virt-pki-validate.in b/tools/virt-pki-validate.in index 206637abf..b04680dde 100755 --- a/tools/virt-pki-validate.in +++ b/tools/virt-pki-validate.in @@ -255,7 +255,7 @@ then echo CA organization: $ORG echo Server organization: $S_ORG fi -S_HOST=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*CN=\([a-zA-Z\. _-]*\)+\1+'` +S_HOST=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*CN=\(.[a-zA-Z \._-]*\).*+\1+'` if test "$S_HOST" != "`hostname -s`" && test "$S_HOST" != "`hostname`" then echo The server certificate does not seem to match the host name -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2] vbox: fix SEGV during dumpxml of a serial port
commit 77a12987a48 changed the "virDomainChrSourceDef source" inside virDomainChrDef to "virDomainChrSourceDefPtr source", and started allocating source inside virDomainChrDefNew(), but vboxDumpSerial() was allocating a virDomainChrDef with a simple VIR_ALLOC() (i.e. never calling virDomainChrDefNew()), so source was never initialized, leading to a SEGV any time a serial port was present. The same problem was created in vboxDumpParallel(). This patch changes vboxDumpSerial() and vboxDumpParallel() to use virDomainChrDefNew() instead of VIR_ALLOC(), and changes both of those functions to return an error if virDomainChrDef() (or any other allocation) fails. This resolves: https://bugzilla.redhat.com/1536649 --- Change from V1: Due to reviews of V1 whining about the patch calling out the lack of returning failure on OOM in a comment rather than fixing it, V2 changes both functions to return 0/-1, and their caller to abort the dumpxml if they return -1. (If I'd taken the extra 30 seconds to look one level up the call chain before posting V1, I would have done that to begin with - there's really nothing complicated about the change, so I'm just as comfortable posting this V2 patch without being able to test as I was with V1). src/vbox/vbox_common.c | 43 +++ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 33aefabe5..e8381ac95 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3862,7 +3862,7 @@ vboxDumpAudio(virDomainDefPtr def, vboxDriverPtr data ATTRIBUTE_UNUSED, } } -static void +static int vboxDumpSerial(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRUint32 serialPortCount) { PRUint32 serialPortIncCount = 0; @@ -3886,9 +3886,15 @@ vboxDumpSerial(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRUin } /* Allocate memory for the serial ports which are enabled */ -if ((def->nserials > 0) && (VIR_ALLOC_N(def->serials, def->nserials) >= 0)) { -for (i = 0; i < def->nserials; i++) -ignore_value(VIR_ALLOC(def->serials[i])); +if (def->nserials > 0) { +if (VIR_ALLOC_N(def->serials, def->nserials) < 0) +return -1; + +for (i = 0; i < def->nserials; i++) { +def->serials[i] = virDomainChrDefNew(NULL); +if (!def->serials[i]) +return -1; +} } /* Now get the details about the serial ports here */ @@ -3936,7 +3942,8 @@ vboxDumpSerial(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRUin if (pathUtf16) { VBOX_UTF16_TO_UTF8(pathUtf16, ); - ignore_value(VIR_STRDUP(def->serials[serialPortIncCount]->source->data.file.path, path)); +if (VIR_STRDUP(def->serials[serialPortIncCount]->source->data.file.path, path) < 0) +return -1; } serialPortIncCount++; @@ -3948,9 +3955,10 @@ vboxDumpSerial(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRUin VBOX_RELEASE(serialPort); } } +return 0; } -static void +static int vboxDumpParallel(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRUint32 parallelPortCount) { PRUint32 parallelPortIncCount = 0; @@ -3974,9 +3982,15 @@ vboxDumpParallel(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRU } /* Allocate memory for the parallel ports which are enabled */ -if ((def->nparallels > 0) && (VIR_ALLOC_N(def->parallels, def->nparallels) >= 0)) { -for (i = 0; i < def->nparallels; i++) -ignore_value(VIR_ALLOC(def->parallels[i])); +if (def->nparallels > 0) { +if (VIR_ALLOC_N(def->parallels, def->nparallels) < 0) +return -1; + +for (i = 0; i < def->nparallels; i++) { +def->parallels[i] = virDomainChrDefNew(NULL); +if (!def->parallels[i]) +return -1; +} } /* Now get the details about the parallel ports here */ @@ -4011,7 +4025,8 @@ vboxDumpParallel(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRU gVBoxAPI.UIParallelPort.GetPath(parallelPort, ); VBOX_UTF16_TO_UTF8(pathUtf16, ); - ignore_value(VIR_STRDUP(def->parallels[parallelPortIncCount]->source->data.file.path, path)); +if (VIR_STRDUP(def->parallels[parallelPortIncCount]->source->data.file.path, path) < 0) +return -1; parallelPortIncCount++; @@ -4022,6 +4037,7 @@ vboxDumpParallel(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine, PRU VBOX_RELEASE(parallelPort); } } +return 0; } static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) @@ -4162,8 +4178,11 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom,
[libvirt] [RFC v2 REPOST] arm64: KVM: KVM API extensions for SVE
Hi all, Reposting this to give people another chance to comment before I move ahead... ---8<--- Here's a second, slightly more complete stab at the KVM API extensions for SVE. I haven't started implementing in earnest yet, so any comments at this stage would be very helpful. [libvir-list readers: this is a proposal for extending the KVM API on AArch64 systems to support the Scalable Vector Extension [1], [2]. This has some interesting configuration and migration quirks -- see "Vector length control" in particular, and feel free to throw questions my way...] Cheers ---Dave [1] Overview https://community.arm.com/processors/b/blog/posts/technology-update-the-scalable-vector-extension-sve-for-the-armv8-a-architecture [2] Architecture spec https://developer.arm.com/products/architecture/a-profile/docs/ddi0584/latest/arm-architecture-reference-manual-supplement-the-scalable-vector-extension-sve-for-armv8-a ---8<--- New feature KVM_ARM_VCPU_SVE: * enables exposure of SVE to the guest * enables visibility of / access to KVM_REG_ARM_SVE_*() via KVM reg ioctls. The main purposes of this are a) is to allow userspace to hide weird-sized registers that it doesn't understand how to deal with, and b) allow SVE to be hidden from the VM so that it can migrate to nodes that don't support SVE. ZCR_EL1 is not specifically hidden, since it is "just a system register" and does not have a weird size or semantics etc. Registers: * A new register size is defined KVM_REG_SIZE_U2048 (which can be encoded sensibly using the next unused value for the reg size field in the reg ID) (grep KVM_REG_SIZE_). * Reg IDs for the SVE regs will be defined as "coproc" 0x14 (i.e., 0x14 << KVM_REG_ARM_COPROC_SHIFT) KVM_REG_ARM_SVE_Z(n, i) is slice i of Zn (each slice is 2048 bits) KVM_REG_ARM_SVE_P(n, i) is slice i of Pn (each slice is 256 bits) KVM_REG_ARM_FFR(i) is slice i of FFR (each slice is 256 bits) The slice sizes allow each register to be read/written in exactly one slice for SVE. Surplus bits (beyond the maximum VL supported by the vcpu) will be read-as-zero write-ignore. Reading/writing surplus slices will probably be forbidden, and the surplus slices would not be reported via KVM_GET_REG_LIST. (We could make these RAZ/WI too, but I'm not sure if it's worth it, or why it would be useful.) Future extensions to the architecture might grow the registers up to 32 slices: this may or may not actually happen, but SVE keeps the possibilty open. I've tried to design for it. * KVM_REG_ARM_SVE_Z(n, 0) bits [127:0] alias Vn in KVM_REG_ARM_CORE(fp_regs.v[n]) .. KVM_REG_ARM_CORE(fp_regs.v[n])+3. It's simplest for userspace if the two views always appear to be in sync, but it's unclear whether this is really useful. Perhaps this can be relaxed if it's a big deal for the KVM implementation; I don't know yet. Vector length control: Some means is needed to determine the set of vector lengths visible to guest software running on a vcpu. When a vcpu is created, the set would be defaulted to the maximal set that can be supported while permitting each vcpu to run on any host CPU. SVE has some virtualisation quirks which mean that this set may exclude some vector lengths that are available for host userspace applications. The common case should be that the sets are the same however. * New ioctl KVM_ARM_VCPU_{SET,GET}_SVE_VLS to set or retrieve the set of vector lengths available to the guest. Adding random vcpu ioctls To configure a non-default set of vector lengths, KVM_ARM_VCPU_SET_SVE_VLS can be called: this would only be permitted before the vcpu is first run. This is primarily intended for supporting migration, by providing a robust check that the destination node will run the vcpu correctly. In a cluster with non-uniform SVE implementation across nodes, this also allows a specific set of VLs to be requested that the caller knows is usable across the whole cluster. For migration purposes, userspace would need to do KVM_ARM_VCPU_GET_SVE_VLS at the origin node and store the returned set as VM metadata: on the destination node, KVM_ARM_VCPU_SET_SVE_VLS should be used to request that exact set of VLs: if the destination node can't support that set of VLs, the call will fail. The interface would look something like: ioctl(vcpu_fd, KVM_ARM_SVE_SET_VLS, __u64 vqs[SVE_VQ_MAX / 64]); How to expose this to the user in an intelligible way would be a problem for userspace to solve. At present, other than initialising each vcpu to the maximum supportable set of VLs, I don't propose having a way to probe for what sets of VLs are supportable: the above call either succeeds or fails. Cheers ---Dave ___ kvmarm mailing list kvm...@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm -- libvir-list
Re: [libvirt] [PATCH 0/6] port allocator: make used port bitmap global etc
ping On 20.12.2017 09:35, Nikolay Shirokovskiy wrote: > This patch set addresses issue described in [1] and the core of > changes go to the first patch. The others are cleanups and > refactorings. > > [1] https://www.redhat.com/archives/libvir-list/2017-December/msg00600.html > > Nikolay Shirokovskiy (6): > port allocator: make used port bitmap global > port allocator: remove range on manual port reserving > port allocator: remove range check in release function > port allocator: drop skip flag > port allocator: remove release functionality from set used > port allocator: make port range constant object > > src/bhyve/bhyve_command.c | 4 +- > src/bhyve/bhyve_driver.c | 4 +- > src/bhyve/bhyve_process.c | 7 +- > src/bhyve/bhyve_utils.h| 2 +- > src/libvirt_private.syms | 3 +- > src/libxl/libxl_conf.c | 8 +-- > src/libxl/libxl_conf.h | 12 ++-- > src/libxl/libxl_domain.c | 3 +- > src/libxl/libxl_driver.c | 17 +++-- > src/libxl/libxl_migration.c| 4 +- > src/qemu/qemu_conf.h | 12 ++-- > src/qemu/qemu_driver.c | 27 > src/qemu/qemu_migration.c | 12 ++-- > src/qemu/qemu_process.c| 55 +-- > src/util/virportallocator.c| 148 > +++-- > src/util/virportallocator.h| 24 +++ > tests/bhyvexml2argvtest.c | 5 +- > tests/libxlxml2domconfigtest.c | 7 +- > tests/virportallocatortest.c | 49 -- > 19 files changed, 196 insertions(+), 207 deletions(-) > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 1/9] qemu: Add support for DUMP_COMPLETED event
On Fri, Jan 26, 2018 at 08:43:38 -0500, John Ferlan wrote: > > > On 01/25/2018 11:59 AM, Jiri Denemark wrote: > > On Fri, Jan 19, 2018 at 14:53:08 -0500, John Ferlan wrote: > >> The event is fired when the domain memory only dump completes. > >> > >> Wire up the code to extract and send along the status. > >> > >> Signed-off-by: John Ferlan> >> --- > >> src/qemu/qemu_monitor.c | 18 ++ > >> src/qemu/qemu_monitor.h | 19 +++ > >> src/qemu/qemu_monitor_json.c | 31 +++ > >> 3 files changed, 68 insertions(+) ... > > According to qapi-schema the DUMP_COMPLETED event may contain an error > > string. Don't we want to consume it here too? > > We could I suppose, passing it back through like EmitBlockJob and > BlockJobCallback. I believe you wanted to say s/BlockJob/Dump/... > Once I page all this code back into short term memory (Nov. seems so > long ago), I'll work through the other comments as well and post a > new version. Yeah, sorry about the delayed review. More priority stuff (such as holiday and Spectre) appeared. > I'm trying to think about the common stats parser right now and how to > handle errors as the dump completed event code would use VIR_WARN when > failing to parse the result, but the query code would use virReportError I think you can just use virReportError and discard the error in the dump completed event code. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 8/9] qemu: Allow showing the dump progress for memory only dump
On Fri, Jan 19, 2018 at 14:53:15 -0500, John Ferlan wrote: > https://bugzilla.redhat.com/show_bug.cgi?id=916061 > > If the QEMU version running is new enough (based on the DUMP_COMPLETED > event), then we can add a 'detach' boolean to the dump-guest-memory > command in order to tell QEMU to run in a thread. This ensures that we > don't lock out other commands while the potentially long running dump > memory is completed. > > This allows the usage of a qemuDumpWaitForCompletion which will wait > for the event while the qemuDomainGetJobInfoDumpStats can be used via > qemuDomainGetJobInfo in order to query QEMU in order to determine > how far along the job is. > > Signed-off-by: John Ferlan> --- > src/qemu/qemu_driver.c | 48 > 1 file changed, 44 insertions(+), 4 deletions(-) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index adf66228b..efb3652df 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -3758,6 +3758,34 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned > int flags) > } > > > +/** > + * qemuDumpWaitForCompletion: > + * @vm: domain object > + * > + * If the query dump capability exists, then it's possible to start a > + * guest memory dump operation using a thread via a 'detach' qualifier > + * to the dump guest memory command. This allows the async check if the > + * dump is done. > + * > + * Returns 0 on success, -1 on failure > + */ > +static int > +qemuDumpWaitForCompletion(virDomainObjPtr vm) > +{ > +qemuDomainObjPrivatePtr priv = vm->privateData; > + > +if (!priv->job.dumpCompletion) > +return 0; This condition can never be true in your code. You can just drop it while dropping dumpCompletion. > + > +VIR_DEBUG("Waiting for dump completion"); > +while (!priv->job.dumpCompleted && !priv->job.abortJob) { > +if (virDomainObjWait(vm) < 0) > +return -1; > +} > +return 0; > +} > + > + > static int > qemuDumpToFd(virQEMUDriverPtr driver, > virDomainObjPtr vm, > @@ -3766,6 +3794,7 @@ qemuDumpToFd(virQEMUDriverPtr driver, > const char *dumpformat) > { > qemuDomainObjPrivatePtr priv = vm->privateData; > +bool detach = false; > int ret = -1; > > if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) { > @@ -3774,10 +3803,13 @@ qemuDumpToFd(virQEMUDriverPtr driver, > return -1; > } > > +detach = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_COMPLETED); > + > if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < > 0) > return -1; > > -VIR_FREE(priv->job.current); > +if (!detach) > +VIR_FREE(priv->job.current); > priv->job.dump_memory_only = true; > > if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) > @@ -3792,15 +3824,23 @@ qemuDumpToFd(virQEMUDriverPtr driver, > "for this QEMU binary"), > dumpformat); > ret = -1; > +ignore_value(qemuDomainObjExitMonitor(driver, vm)); > goto cleanup; > } > } > > -ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, false); > +ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, detach); > > - cleanup: > -ignore_value(qemuDomainObjExitMonitor(driver, vm)); > +if (detach && ret == 0) > +priv->job.dumpCompletion = true; > + > +if ((qemuDomainObjExitMonitor(driver, vm) < 0) || ret < 0) > +goto cleanup; > + > +if (detach) > +ret = qemuDumpWaitForCompletion(vm); We should update job.completed at this point. > > + cleanup: > return ret; > } Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 6/9] qemu: Introduce qemuDomainGetJobInfoDumpStats
On Fri, Jan 19, 2018 at 14:53:13 -0500, John Ferlan wrote: > Add an API to allow fetching the Dump statistics for the job > via the qemuDomainGetJobInfo API. > > Signed-off-by: John Ferlan> --- > src/qemu/qemu_driver.c | 56 > -- > 1 file changed, 54 insertions(+), 2 deletions(-) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 00a010b45..adf66228b 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -13186,6 +13186,53 @@ qemuDomainGetJobInfoMigrationStats(virQEMUDriverPtr > driver, > > > static int > +qemuDomainGetJobInfoDumpStats(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + qemuDomainJobInfoPtr jobInfo) > +{ > +qemuDomainObjPrivatePtr priv = vm->privateData; > +qemuMonitorDumpStats stats; > +int rv; > + > +if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE) < 0) > +return -1; > + > +rv = qemuMonitorQueryDump(priv->mon, ); > + > +if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0) > +return -1; > + > +/* Save the stats in the migration stats so that qemuDomainJobInfoToInfo > + * will be copy properly */ > +jobInfo->stats.ram_total = stats.total; > +jobInfo->stats.ram_remaining = stats.total - stats.completed; > +jobInfo->stats.ram_transferred = stats.completed; I think we should store the raw DumpStats in jobInfo similarly to what we do with migration stats and let qemuDomainJobInfoTo* translate them. If we store the stats type in jobInfo (see below), we can even change jobInfo->stats into a union to make it clear what stats structures are used for each type. > +switch (stats.status) { > +case QEMU_MONITOR_DUMP_STATUS_NONE: > +case QEMU_MONITOR_DUMP_STATUS_FAILED: > +case QEMU_MONITOR_DUMP_STATUS_LAST: > +virReportError(VIR_ERR_OPERATION_FAILED, > + _("dump query failed, status=%d"), stats.status); > +return -1; > +break; > + > +case QEMU_MONITOR_DUMP_STATUS_ACTIVE: > +jobInfo->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE; > +VIR_DEBUG("dump active, bytes written='%llu' remaining='%llu'", > + stats.completed, stats.total - stats.completed); > +break; > + > +case QEMU_MONITOR_DUMP_STATUS_COMPLETED: > +jobInfo->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED; > +VIR_DEBUG("dump completed, bytes written='%llu'", stats.completed); > +break; > +} > + > +return 0; > +} > + > + > +static int > qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver, >virDomainObjPtr vm, >bool completed, > @@ -13226,8 +13273,13 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr > driver, > } > *jobInfo = *priv->job.current; > > -if (qemuDomainGetJobInfoMigrationStats(driver, vm, jobInfo) < 0) > -goto cleanup; > +if (priv->job.asyncJob == QEMU_ASYNC_JOB_DUMP && > priv->job.dumpCompletion) { Oh, so this is the only place where job.dumpCompletion is actually doing something useful. It's distinguishing whether we need to get dump or migration stats. We can just use job.dump_memory_only for this as priv->job.current is NULL if job.dump_memory_only is true but the DUMP_COMPLETED event is not supported. Or alternatively we could have an explicit enum for distinguishing the two types of statistics, store it in qemuDomainJobInfo, and use it here to select the right function for fetching the statistics. > +if (qemuDomainGetJobInfoDumpStats(driver, vm, jobInfo) < 0) > +goto cleanup; > +} else { > +if (qemuDomainGetJobInfoMigrationStats(driver, vm, jobInfo) < 0) > +goto cleanup; > +} Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/10] nodedev: allow opening with nodedev:///system and nodedev:///session URIs
Allow the possibility of opening a connection to only the nodedev driver, by defining nodedev:///system and nodedev:///session URIs and registering a fake hypervisor driver that supports them. The hypervisor drivers can now directly open a nodedev driver connection at time of need, instead of having to pass around a virConnectPtr through many functions. This will facilitate the later change to support separate daemons for each driver. Signed-off-by: Daniel P. Berrangé--- src/node_device/node_device_driver.c | 73 +++- src/node_device/node_device_driver.h | 9 + src/node_device/node_device_hal.c| 18 + src/node_device/node_device_udev.c | 19 ++ 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 6216a69773..efbe898249 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -47,6 +47,78 @@ virNodeDeviceDriverStatePtr driver; +virDrvOpenStatus nodeConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + virConfPtr conf ATTRIBUTE_UNUSED, + unsigned int flags) +{ +virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + +/* Verify uri was specified */ +if (conn->uri == NULL) { +/* Only hypervisor drivers are permitted to auto-open on NULL uri */ +return VIR_DRV_OPEN_DECLINED; +} else { +if (STRNEQ_NULLABLE(conn->uri->scheme, "nodedev")) +return VIR_DRV_OPEN_DECLINED; + +/* Leave for remote driver */ +if (conn->uri->server != NULL) +return VIR_DRV_OPEN_DECLINED; + +if (driver == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("nodedev state driver is not active")); +return VIR_DRV_OPEN_ERROR; +} + +if (driver->privileged) { +if (STRNEQ(conn->uri->path, "/system")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected nodedev URI path '%s', try nodedev:///system"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} else { +if (STRNEQ(conn->uri->path, "/session")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected nodedev URI path '%s', try nodedev:///session"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} +} + +if (virConnectOpenEnsureACL(conn) < 0) +return VIR_DRV_OPEN_ERROR; + +return VIR_DRV_OPEN_SUCCESS; +} + +int nodeConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 0; +} + + +int nodeConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Trivially secure, since always inside the daemon */ +return 1; +} + + +int nodeConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Not encrypted, but remote driver takes care of that */ +return 0; +} + + +int nodeConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 1; +} static int nodeDeviceUpdateCaps(virNodeDeviceDefPtr def) @@ -661,7 +733,6 @@ nodeConnectNodeDeviceEventDeregisterAny(virConnectPtr conn, return ret; } - int nodedevRegister(void) { diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h index 109c717815..83a9449139 100644 --- a/src/node_device/node_device_driver.h +++ b/src/node_device/node_device_driver.h @@ -51,6 +51,15 @@ extern virNodeDeviceDriverStatePtr driver; int nodedevRegister(void); +virDrvOpenStatus nodeConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth, + virConfPtr conf, + unsigned int flags); +int nodeConnectClose(virConnectPtr conn); +int nodeConnectIsSecure(virConnectPtr conn); +int nodeConnectIsEncrypted(virConnectPtr conn); +int nodeConnectIsAlive(virConnectPtr conn); + int nodeNumOfDevices(virConnectPtr conn, const char *cap, diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c index c19e327c96..9cd5bb3eec 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -773,6 +773,22 @@ static virNodeDeviceDriver halNodeDeviceDriver = { }; +static virHypervisorDriver halHypervisorDriver = { +.name = "nodedev", +.connectOpen = nodeConnectOpen, /* 4.1.0 */ +.connectClose = nodeConnectClose, /* 4.1.0 */ +.connectIsEncrypted = nodeConnectIsEncrypted, /* 4.1.0 */ +.connectIsSecure = nodeConnectIsSecure, /* 4.1.0 */ +.connectIsAlive = nodeConnectIsAlive, /* 4.1.0 */ +}; + + +static virConnectDriver halConnectDriver = { +.hypervisorDriver = , +
[libvirt] [PATCH 08/10] secret: allow opening with secret:///system and secret:///session URIs
Allow the possibility of opening a connection to only the secret driver, by defining secret:///system and secret:///session URIs and registering a fake hypervisor driver that supports them. The hypervisor drivers can now directly open a secret driver connection at time of need, instead of having to pass around a virConnectPtr through many functions. This will facilitate the later change to support separate daemons for each driver. Signed-off-by: Daniel P. Berrangé--- src/secret/secret_driver.c | 95 ++ 1 file changed, 95 insertions(+) diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index d833a863f6..e9e67b8aa5 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -57,6 +57,7 @@ typedef struct _virSecretDriverState virSecretDriverState; typedef virSecretDriverState *virSecretDriverStatePtr; struct _virSecretDriverState { virMutex lock; +bool privileged; /* readonly */ virSecretObjListPtr secrets; char *configDir; @@ -464,6 +465,7 @@ secretStateInitialize(bool privileged, secretDriverLock(); driver->secretEventState = virObjectEventStateNew(); +driver->privileged = privileged; if (privileged) { if (VIR_STRDUP(base, SYSCONFDIR "/libvirt") < 0) @@ -514,6 +516,80 @@ secretStateReload(void) } +static virDrvOpenStatus secretConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + virConfPtr conf ATTRIBUTE_UNUSED, + unsigned int flags) +{ +virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + +/* Verify uri was specified */ +if (conn->uri == NULL) { +/* Only hypervisor drivers are permitted to auto-open on NULL uri */ +return VIR_DRV_OPEN_DECLINED; +} else { +if (STRNEQ_NULLABLE(conn->uri->scheme, "secret")) +return VIR_DRV_OPEN_DECLINED; + +/* Leave for remote driver */ +if (conn->uri->server != NULL) +return VIR_DRV_OPEN_DECLINED; + +if (driver == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("secret state driver is not active")); +return VIR_DRV_OPEN_ERROR; +} + +if (driver->privileged) { +if (STRNEQ(conn->uri->path, "/system")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected secret URI path '%s', try secret:///system"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} else { +if (STRNEQ(conn->uri->path, "/session")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected secret URI path '%s', try secret:///session"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} +} + +if (virConnectOpenEnsureACL(conn) < 0) +return VIR_DRV_OPEN_ERROR; + +return VIR_DRV_OPEN_SUCCESS; +} + +static int secretConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 0; +} + + +static int secretConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Trivially secure, since always inside the daemon */ +return 1; +} + + +static int secretConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Not encrypted, but remote driver takes care of that */ +return 0; +} + + +static int secretConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 1; +} + + static int secretConnectSecretEventRegisterAny(virConnectPtr conn, virSecretPtr secret, @@ -573,6 +649,23 @@ static virSecretDriver secretDriver = { .connectSecretEventDeregisterAny = secretConnectSecretEventDeregisterAny, /* 3.0.0 */ }; + +static virHypervisorDriver secretHypervisorDriver = { +.name = "secret", +.connectOpen = secretConnectOpen, /* 4.1.0 */ +.connectClose = secretConnectClose, /* 4.1.0 */ +.connectIsEncrypted = secretConnectIsEncrypted, /* 4.1.0 */ +.connectIsSecure = secretConnectIsSecure, /* 4.1.0 */ +.connectIsAlive = secretConnectIsAlive, /* 4.1.0 */ +}; + + +static virConnectDriver secretConnectDriver = { +.hypervisorDriver = , +.secretDriver = , +}; + + static virStateDriver stateDriver = { .name = "secret", .stateInitialize = secretStateInitialize, @@ -584,6 +677,8 @@ static virStateDriver stateDriver = { int secretRegister(void) { +if (virRegisterConnectDriver(, false) < 0) +return -1; if (virSetSharedSecretDriver() < 0) return -1; if (virRegisterStateDriver() < 0) -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 1/9] qemu: Add support for DUMP_COMPLETED event
On 01/25/2018 11:59 AM, Jiri Denemark wrote: > On Fri, Jan 19, 2018 at 14:53:08 -0500, John Ferlan wrote: >> The event is fired when the domain memory only dump completes. >> >> Wire up the code to extract and send along the status. >> >> Signed-off-by: John Ferlan>> --- >> src/qemu/qemu_monitor.c | 18 ++ >> src/qemu/qemu_monitor.h | 19 +++ >> src/qemu/qemu_monitor_json.c | 31 +++ >> 3 files changed, 68 insertions(+) > ... >> +static void >> +qemuMonitorJSONHandleDumpCompleted(qemuMonitorPtr mon, >> + virJSONValuePtr data) >> +{ >> +const char *statusstr; >> +qemuMonitorDumpStatus status; >> +virJSONValuePtr result; >> + >> +if (!(result = virJSONValueObjectGetObject(data, "result"))) { >> +VIR_WARN("missing result in dump completed event"); >> +return; >> +} >> + >> +if (!(statusstr = virJSONValueObjectGetString(result, "status"))) { >> +VIR_WARN("missing status string in dump completed event"); >> +return; >> +} >> + >> +status = qemuMonitorDumpStatusTypeFromString(statusstr); >> +if (status < 0) { >> +VIR_WARN("invalid status string '%s' in dump completed event", >> + statusstr); >> +return; >> +} >> + >> +qemuMonitorEmitDumpCompleted(mon, status); > > According to qapi-schema the DUMP_COMPLETED event may contain an error > string. Don't we want to consume it here too? > > Jirka > We could I suppose, passing it back through like EmitBlockJob and BlockJobCallback. Once I page all this code back into short term memory (Nov. seems so long ago), I'll work through the other comments as well and post a new version. I'm trying to think about the common stats parser right now and how to handle errors as the dump completed event code would use VIR_WARN when failing to parse the result, but the query code would use virReportError Tks - John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/10] network: allow opening with network:///system and network:///session URIs
Allow the possibility of opening a connection to only the network driver, by defining network:///system and network:///session URIs and registering a fake hypervisor driver that supports them. The hypervisor drivers can now directly open a network driver connection at time of need, instead of having to pass around a virConnectPtr through many functions. This will facilitate the later change to support separate daemons for each driver. Signed-off-by: Daniel P. Berrangé--- src/network/bridge_driver.c | 95 src/network/bridge_driver_platform.h | 3 ++ 2 files changed, 98 insertions(+) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 7f21381bd4..7aea8079d4 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -671,6 +671,8 @@ networkStateInitialize(bool privileged, goto error; } +network_driver->privileged = privileged; + /* configuration/state paths are one of * ~/.config/libvirt/... (session/unprivileged) * /etc/libvirt/... && /var/(run|lib)/libvirt/... (system/privileged). @@ -868,6 +870,80 @@ networkStateCleanup(void) } +static virDrvOpenStatus networkConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + virConfPtr conf ATTRIBUTE_UNUSED, + unsigned int flags) +{ +virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + +/* Verify uri was specified */ +if (conn->uri == NULL) { +/* Only hypervisor drivers are permitted to auto-open on NULL uri */ +return VIR_DRV_OPEN_DECLINED; +} else { +if (STRNEQ_NULLABLE(conn->uri->scheme, "network")) +return VIR_DRV_OPEN_DECLINED; + +/* Leave for remote driver */ +if (conn->uri->server != NULL) +return VIR_DRV_OPEN_DECLINED; + +if (network_driver == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("network state driver is not active")); +return VIR_DRV_OPEN_ERROR; +} + +if (network_driver->privileged) { +if (STRNEQ(conn->uri->path, "/system")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected network URI path '%s', try network:///system"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} else { +if (STRNEQ(conn->uri->path, "/session")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected network URI path '%s', try network:///session"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} +} + +if (virConnectOpenEnsureACL(conn) < 0) +return VIR_DRV_OPEN_ERROR; + +return VIR_DRV_OPEN_SUCCESS; +} + +static int networkConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 0; +} + + +static int networkConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Trivially secure, since always inside the daemon */ +return 1; +} + + +static int networkConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Not encrypted, but remote driver takes care of that */ +return 0; +} + + +static int networkConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 1; +} + + /* networkKillDaemon: * * kill the specified pid/name, and wait a bit to make sure it's dead. @@ -5699,6 +5775,23 @@ static virNetworkDriver networkDriver = { .networkGetDHCPLeases = networkGetDHCPLeases, /* 1.2.6 */ }; + +static virHypervisorDriver networkHypervisorDriver = { +.name = "network", +.connectOpen = networkConnectOpen, /* 4.1.0 */ +.connectClose = networkConnectClose, /* 4.1.0 */ +.connectIsEncrypted = networkConnectIsEncrypted, /* 4.1.0 */ +.connectIsSecure = networkConnectIsSecure, /* 4.1.0 */ +.connectIsAlive = networkConnectIsAlive, /* 4.1.0 */ +}; + + +static virConnectDriver networkConnectDriver = { +.hypervisorDriver = , +.networkDriver = , +}; + + static virStateDriver networkStateDriver = { .name = "bridge", .stateInitialize = networkStateInitialize, @@ -5710,6 +5803,8 @@ static virStateDriver networkStateDriver = { int networkRegister(void) { +if (virRegisterConnectDriver(, false) < 0) +return -1; if (virSetSharedNetworkDriver() < 0) return -1; if (virRegisterStateDriver() < 0) diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driver_platform.h index f04c0c48b4..706000df4e 100644 --- a/src/network/bridge_driver_platform.h +++ b/src/network/bridge_driver_platform.h @@ -34,6 +34,9 @@ struct _virNetworkDriverState { virMutex lock; +/* Read-only */ +bool privileged; + /*
[libvirt] [PATCH 09/10] storage: open secret driver connection at time of use
Instead of passing around a virConnectPtr object, just open a connection to the secret driver at time of use. Opening connections on demand will be beneficial when the secret driver is in a separate daemon. It also solves the problem that a number of callers just pass in a NULL connection today which prevents secret lookup working at all. Signed-off-by: Daniel P. Berrangé--- src/storage/storage_backend_iscsi.c | 14 +++--- src/storage/storage_backend_logical.c | 2 +- src/storage/storage_backend_rbd.c | 41 +++ src/storage/storage_util.c| 95 --- src/storage/storage_util.h| 6 +-- 5 files changed, 71 insertions(+), 87 deletions(-) diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index b0c5096adb..921215c9e9 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -273,13 +273,13 @@ virStorageBackendISCSICheckPool(virStoragePoolObjPtr pool, static int virStorageBackendISCSISetAuth(const char *portal, - virConnectPtr conn, virStoragePoolSourcePtr source) { unsigned char *secret_value = NULL; size_t secret_size; virStorageAuthDefPtr authdef = source->auth; int ret = -1; +virConnectPtr conn = NULL; if (!authdef || authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE) return 0; @@ -292,12 +292,9 @@ virStorageBackendISCSISetAuth(const char *portal, return -1; } -if (!conn) { -virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("iscsi 'chap' authentication not supported " - "for autostarted pools")); +conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); +if (!conn) return -1; -} if (virSecretGetSecretString(conn, >seclookupdef, VIR_SECRET_USAGE_TYPE_ISCSI, @@ -322,11 +319,12 @@ virStorageBackendISCSISetAuth(const char *portal, cleanup: VIR_DISPOSE_N(secret_value, secret_size); +virObjectUnref(conn); return ret; } static int -virStorageBackendISCSIStartPool(virConnectPtr conn, +virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); @@ -362,7 +360,7 @@ virStorageBackendISCSIStartPool(virConnectPtr conn, if (virISCSINodeNew(portal, def->source.devices[0].path) < 0) goto cleanup; -if (virStorageBackendISCSISetAuth(portal, conn, >source) < 0) +if (virStorageBackendISCSISetAuth(portal, >source) < 0) goto cleanup; if (virISCSIConnectionLogin(portal, diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index 5df30de29d..64bfc8c976 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -997,7 +997,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, return -1; if (vol->target.encryption && -virStorageBackendCreateVolUsingQemuImg(conn, pool, vol, NULL, 0) < 0) +virStorageBackendCreateVolUsingQemuImg(pool, vol, NULL, 0) < 0) goto error; if ((fd = virStorageBackendVolOpen(vol->target.path, , diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index 7f9597cabe..e901f370d5 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -71,7 +71,6 @@ virStorageBackendRBDRADOSConfSet(rados_t cluster, static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, - virConnectPtr conn, virStoragePoolSourcePtr source) { int ret = -1; @@ -87,6 +86,7 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, const char *mon_op_timeout = "30"; const char *osd_op_timeout = "30"; const char *rbd_default_format = "2"; +virConnectPtr conn = NULL; if (authdef) { VIR_DEBUG("Using cephx authorization, username: %s", authdef->username); @@ -96,12 +96,9 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, goto cleanup; } -if (!conn) { -virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("'ceph' authentication not supported " - "for autostarted pools")); +conn = virConnectOpen(geteuid() == 0 ? "secret:///system" : "secret:///session"); +if (!conn) return -1; -} if (virSecretGetSecretString(conn, >seclookupdef, VIR_SECRET_USAGE_TYPE_CEPH, @@ -201,6 +198,7 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, VIR_DISPOSE_N(secret_value,
[libvirt] [PATCH 00/10] Enable direct use of secondary drivers
Currently the secondary drivers can only be used if you have a connection to a primary hypervisor driver. This series introduces explicit URIs that allow opening a connection that only talks to a specific secondary driver. In the future these URIs will resolve to individual daemons containing those drivers. This also allows us to fix long standing problems with most code that uses secrets internally. We need to pass a virConnectPtr into such code but some call stacks don't have a connection available. In some cases we open a temporary connection to the QEMU driver, but this is suboptimal for deployments without the QEMU driver present. Daniel P. Berrangé (10): storage: move driver registration back to end of the file storage: allow opening with storage:///system and storage:///session URIs network: move driver registration back to end of the file network: allow opening with network:///system and network:///session URIs nwfilter: allow opening with nwfilter:///system URI interface: allow opening with interface:///system and interface:///session URIs nodedev: allow opening with nodedev:///system and nodedev:///session URIs secret: allow opening with secret:///system and secret:///session URIs storage: open secret driver connection at time of use storage: remove virConnectPtr from all backend functions src/interface/interface_backend_netcf.c | 98 - src/interface/interface_backend_udev.c | 97 - src/network/bridge_driver.c | 185 + src/network/bridge_driver_platform.h| 3 + src/node_device/node_device_driver.c| 73 ++- src/node_device/node_device_driver.h| 9 + src/node_device/node_device_hal.c | 18 ++ src/node_device/node_device_udev.c | 19 ++ src/nwfilter/nwfilter_driver.c | 83 src/secret/secret_driver.c | 95 + src/storage/storage_backend.h | 45 ++-- src/storage/storage_backend_disk.c | 30 +-- src/storage/storage_backend_fs.c| 15 +- src/storage/storage_backend_gluster.c | 9 +- src/storage/storage_backend_iscsi.c | 24 +-- src/storage/storage_backend_logical.c | 38 ++-- src/storage/storage_backend_mpath.c | 5 +- src/storage/storage_backend_rbd.c | 53 ++--- src/storage/storage_backend_scsi.c | 46 +++-- src/storage/storage_backend_sheepdog.c | 33 ++- src/storage/storage_backend_vstorage.c | 10 +- src/storage/storage_backend_zfs.c | 15 +- src/storage/storage_driver.c| 351 src/storage/storage_util.c | 146 ++--- src/storage/storage_util.h | 39 ++-- tests/storagevolxml2argvtest.c | 7 +- 26 files changed, 1047 insertions(+), 499 deletions(-) -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/10] storage: move driver registration back to end of the file
By convention the last thing in the driver.c files should be the driver callback table and function to register it. Signed-off-by: Daniel P. Berrangé--- src/storage/storage_driver.c | 172 +-- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 3b66d51719..f68acc75be 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -2687,92 +2687,6 @@ storageConnectStoragePoolEventDeregisterAny(virConnectPtr conn, } - -static virStorageDriver storageDriver = { -.name = "storage", -.connectNumOfStoragePools = storageConnectNumOfStoragePools, /* 0.4.0 */ -.connectListStoragePools = storageConnectListStoragePools, /* 0.4.0 */ -.connectNumOfDefinedStoragePools = storageConnectNumOfDefinedStoragePools, /* 0.4.0 */ -.connectListDefinedStoragePools = storageConnectListDefinedStoragePools, /* 0.4.0 */ -.connectListAllStoragePools = storageConnectListAllStoragePools, /* 0.10.2 */ -.connectStoragePoolEventRegisterAny = storageConnectStoragePoolEventRegisterAny, /* 2.0.0 */ -.connectStoragePoolEventDeregisterAny = storageConnectStoragePoolEventDeregisterAny, /* 2.0.0 */ -.connectFindStoragePoolSources = storageConnectFindStoragePoolSources, /* 0.4.0 */ -.storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */ -.storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */ -.storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */ -.storagePoolCreateXML = storagePoolCreateXML, /* 0.4.0 */ -.storagePoolDefineXML = storagePoolDefineXML, /* 0.4.0 */ -.storagePoolBuild = storagePoolBuild, /* 0.4.0 */ -.storagePoolUndefine = storagePoolUndefine, /* 0.4.0 */ -.storagePoolCreate = storagePoolCreate, /* 0.4.0 */ -.storagePoolDestroy = storagePoolDestroy, /* 0.4.0 */ -.storagePoolDelete = storagePoolDelete, /* 0.4.0 */ -.storagePoolRefresh = storagePoolRefresh, /* 0.4.0 */ -.storagePoolGetInfo = storagePoolGetInfo, /* 0.4.0 */ -.storagePoolGetXMLDesc = storagePoolGetXMLDesc, /* 0.4.0 */ -.storagePoolGetAutostart = storagePoolGetAutostart, /* 0.4.0 */ -.storagePoolSetAutostart = storagePoolSetAutostart, /* 0.4.0 */ -.storagePoolNumOfVolumes = storagePoolNumOfVolumes, /* 0.4.0 */ -.storagePoolListVolumes = storagePoolListVolumes, /* 0.4.0 */ -.storagePoolListAllVolumes = storagePoolListAllVolumes, /* 0.10.2 */ - -.storageVolLookupByName = storageVolLookupByName, /* 0.4.0 */ -.storageVolLookupByKey = storageVolLookupByKey, /* 0.4.0 */ -.storageVolLookupByPath = storageVolLookupByPath, /* 0.4.0 */ -.storageVolCreateXML = storageVolCreateXML, /* 0.4.0 */ -.storageVolCreateXMLFrom = storageVolCreateXMLFrom, /* 0.6.4 */ -.storageVolDownload = storageVolDownload, /* 0.9.0 */ -.storageVolUpload = storageVolUpload, /* 0.9.0 */ -.storageVolDelete = storageVolDelete, /* 0.4.0 */ -.storageVolWipe = storageVolWipe, /* 0.8.0 */ -.storageVolWipePattern = storageVolWipePattern, /* 0.9.10 */ -.storageVolGetInfo = storageVolGetInfo, /* 0.4.0 */ -.storageVolGetInfoFlags = storageVolGetInfoFlags, /* 3.0.0 */ -.storageVolGetXMLDesc = storageVolGetXMLDesc, /* 0.4.0 */ -.storageVolGetPath = storageVolGetPath, /* 0.4.0 */ -.storageVolResize = storageVolResize, /* 0.9.10 */ - -.storagePoolIsActive = storagePoolIsActive, /* 0.7.3 */ -.storagePoolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */ -}; - - -static virStateDriver stateDriver = { -.name = "storage", -.stateInitialize = storageStateInitialize, -.stateAutoStart = storageStateAutoStart, -.stateCleanup = storageStateCleanup, -.stateReload = storageStateReload, -}; - -static int -storageRegisterFull(bool allbackends) -{ -if (virStorageBackendDriversRegister(allbackends) < 0) -return -1; -if (virSetSharedStorageDriver() < 0) -return -1; -if (virRegisterStateDriver() < 0) -return -1; -return 0; -} - - -int -storageRegister(void) -{ -return storageRegisterFull(false); -} - - -int -storageRegisterAll(void) -{ -return storageRegisterFull(true); -} - - static int virStorageAddISCSIPoolSourceHost(virDomainDiskDefPtr def, virStoragePoolDefPtr pooldef) @@ -3065,3 +2979,89 @@ virStoragePoolObjBuildTempFilePath(virStoragePoolObjPtr obj, driver->stateDir, def->name, voldef->name)); return tmp; } + + +static virStorageDriver storageDriver = { +.name = "storage", +.connectNumOfStoragePools = storageConnectNumOfStoragePools, /* 0.4.0 */ +.connectListStoragePools = storageConnectListStoragePools, /* 0.4.0 */ +.connectNumOfDefinedStoragePools = storageConnectNumOfDefinedStoragePools, /* 0.4.0 */ +.connectListDefinedStoragePools = storageConnectListDefinedStoragePools, /* 0.4.0 */ +
[libvirt] [PATCH 05/10] nwfilter: allow opening with nwfilter:///system URI
Allow the possibility of opening a connection to only the storage driver, by defining a nwfilter:///system URI and registering a fake hypervisor driver that supports it. The hypervisor drivers can now directly open a nwfilter driver connection at time of need, instead of having to pass around a virConnectPtr through many functions. This will facilitate the later change to support separate daemons for each driver. Signed-off-by: Daniel P. Berrangé--- src/nwfilter/nwfilter_driver.c | 83 ++ 1 file changed, 83 insertions(+) diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 885dbcc282..5787152adc 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -363,6 +363,71 @@ nwfilterStateCleanup(void) } +static virDrvOpenStatus nwfilterConnectOpen(virConnectPtr conn, +virConnectAuthPtr auth ATTRIBUTE_UNUSED, +virConfPtr conf ATTRIBUTE_UNUSED, +unsigned int flags) +{ +virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + +/* Verify uri was specified */ +if (conn->uri == NULL) { +/* Only hypervisor drivers are permitted to auto-open on NULL uri */ +return VIR_DRV_OPEN_DECLINED; +} else { +if (STRNEQ_NULLABLE(conn->uri->scheme, "nwfilter")) +return VIR_DRV_OPEN_DECLINED; + +/* Leave for remote driver */ +if (conn->uri->server != NULL) +return VIR_DRV_OPEN_DECLINED; + +if (driver == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("nwfilter state driver is not active")); +return VIR_DRV_OPEN_ERROR; +} + +if (STRNEQ(conn->uri->path, "/system")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected nwfilter URI path '%s', try nwfilter:///system"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} + +if (virConnectOpenEnsureACL(conn) < 0) +return VIR_DRV_OPEN_ERROR; + +return VIR_DRV_OPEN_SUCCESS; +} + +static int nwfilterConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 0; +} + + +static int nwfilterConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Trivially secure, since always inside the daemon */ +return 1; +} + + +static int nwfilterConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Not encrypted, but remote driver takes care of that */ +return 0; +} + + +static int nwfilterConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 1; +} + + static virNWFilterObjPtr nwfilterObjFromNWFilter(const unsigned char *uuid) { @@ -635,6 +700,22 @@ static virNWFilterDriver nwfilterDriver = { }; +static virHypervisorDriver nwfilterHypervisorDriver = { +.name = "nwfilter", +.connectOpen = nwfilterConnectOpen, /* 4.1.0 */ +.connectClose = nwfilterConnectClose, /* 4.1.0 */ +.connectIsEncrypted = nwfilterConnectIsEncrypted, /* 4.1.0 */ +.connectIsSecure = nwfilterConnectIsSecure, /* 4.1.0 */ +.connectIsAlive = nwfilterConnectIsAlive, /* 4.1.0 */ +}; + + +static virConnectDriver nwfilterConnectDriver = { +.hypervisorDriver = , +.nwfilterDriver = , +}; + + static virStateDriver stateDriver = { .name = "NWFilter", .stateInitialize = nwfilterStateInitialize, @@ -651,6 +732,8 @@ static virDomainConfNWFilterDriver domainNWFilterDriver = { int nwfilterRegister(void) { +if (virRegisterConnectDriver(, false) < 0) +return -1; if (virSetSharedNWFilterDriver() < 0) return -1; if (virRegisterStateDriver() < 0) -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 02/10] storage: allow opening with storage:///system and storage:///session URIs
Allow the possibility of opening a connection to only the storage driver, by defining storage:///system and storage:///session URIs and registering a fake hypervisor driver that supports them. The hypervisor drivers can now directly open a storage driver connection at time of need, instead of having to pass around a virConnectPtr through many functions. This will facilitate the later change to support separate daemons for each driver. Signed-off-by: Daniel P. Berrangé--- src/storage/storage_driver.c | 90 1 file changed, 90 insertions(+) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index f68acc75be..5d21007edb 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -388,6 +388,79 @@ storageStateCleanup(void) return 0; } +static virDrvOpenStatus storageConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + virConfPtr conf ATTRIBUTE_UNUSED, + unsigned int flags) +{ +virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + +/* Verify uri was specified */ +if (conn->uri == NULL) { +/* Only hypervisor drivers are permitted to auto-open on NULL uri */ +return VIR_DRV_OPEN_DECLINED; +} else { +if (STRNEQ_NULLABLE(conn->uri->scheme, "storage")) +return VIR_DRV_OPEN_DECLINED; + +/* Leave for remote driver */ +if (conn->uri->server != NULL) +return VIR_DRV_OPEN_DECLINED; + +if (driver == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("storage state driver is not active")); +return VIR_DRV_OPEN_ERROR; +} + +if (driver->privileged) { +if (STRNEQ(conn->uri->path, "/system")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected storage URI path '%s', try storage:///system"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} else { +if (STRNEQ(conn->uri->path, "/session")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected storage URI path '%s', try storage:///session"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} +} + +if (virConnectOpenEnsureACL(conn) < 0) +return VIR_DRV_OPEN_ERROR; + +return VIR_DRV_OPEN_SUCCESS; +} + +static int storageConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 0; +} + + +static int storageConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Trivially secure, since always inside the daemon */ +return 1; +} + + +static int storageConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Not encrypted, but remote driver takes care of that */ +return 0; +} + + +static int storageConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 1; +} + static virStoragePoolObjPtr storagePoolObjFindByUUID(const unsigned char *uuid, @@ -3031,6 +3104,21 @@ static virStorageDriver storageDriver = { }; +static virHypervisorDriver storageHypervisorDriver = { +.name = "storage", +.connectOpen = storageConnectOpen, /* 4.1.0 */ +.connectClose = storageConnectClose, /* 4.1.0 */ +.connectIsEncrypted = storageConnectIsEncrypted, /* 4.1.0 */ +.connectIsSecure = storageConnectIsSecure, /* 4.1.0 */ +.connectIsAlive = storageConnectIsAlive, /* 4.1.0 */ +}; + +static virConnectDriver storageConnectDriver = { +.hypervisorDriver = , +.storageDriver = , +}; + + static virStateDriver stateDriver = { .name = "storage", .stateInitialize = storageStateInitialize, @@ -3043,6 +3131,8 @@ static virStateDriver stateDriver = { static int storageRegisterFull(bool allbackends) { +if (virRegisterConnectDriver(, false) < 0) +return -1; if (virStorageBackendDriversRegister(allbackends) < 0) return -1; if (virSetSharedStorageDriver() < 0) -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 10/10] storage: remove virConnectPtr from all backend functions
Now that we can open connections to the secondary drivers on demand, there is no need to pass a virConnectPtr into all the backend functions. Signed-off-by: Daniel P. Berrangé--- src/storage/storage_backend.h | 45 ++--- src/storage/storage_backend_disk.c | 30 +--- src/storage/storage_backend_fs.c | 15 ++ src/storage/storage_backend_gluster.c | 9 ++-- src/storage/storage_backend_iscsi.c| 12 ++--- src/storage/storage_backend_logical.c | 36 +- src/storage/storage_backend_mpath.c| 5 +- src/storage/storage_backend_rbd.c | 24 +++-- src/storage/storage_backend_scsi.c | 46 ++ src/storage/storage_backend_sheepdog.c | 33 + src/storage/storage_backend_vstorage.c | 10 ++-- src/storage/storage_backend_zfs.c | 15 ++ src/storage/storage_driver.c | 89 +++--- src/storage/storage_util.c | 59 -- src/storage/storage_util.h | 33 + tests/storagevolxml2argvtest.c | 7 +-- 16 files changed, 179 insertions(+), 289 deletions(-) diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 193cf134d6..8dbe344149 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -25,22 +25,16 @@ # include "virstorageobj.h" # include "storage_driver.h" -typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, - const char *srcSpec, +typedef char * (*virStorageBackendFindPoolSources)(const char *srcSpec, unsigned int flags); typedef int (*virStorageBackendCheckPool)(virStoragePoolObjPtr pool, bool *active); -typedef int (*virStorageBackendStartPool)(virConnectPtr conn, - virStoragePoolObjPtr pool); -typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendStartPool)(virStoragePoolObjPtr pool); +typedef int (*virStorageBackendBuildPool)(virStoragePoolObjPtr pool, unsigned int flags); -typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, -virStoragePoolObjPtr pool); -typedef int (*virStorageBackendStopPool)(virConnectPtr conn, - virStoragePoolObjPtr pool); -typedef int (*virStorageBackendDeletePool)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendRefreshPool)(virStoragePoolObjPtr pool); +typedef int (*virStorageBackendStopPool)(virStoragePoolObjPtr pool); +typedef int (*virStorageBackendDeletePool)(virStoragePoolObjPtr pool, unsigned int flags); /* A 'buildVol' backend must remove any volume created on error since @@ -52,46 +46,37 @@ typedef int (*virStorageBackendDeletePool)(virConnectPtr conn, * was not aware of between checking the pool and the create attempt. It * also avoids extra round trips to just delete a file. */ -typedef int (*virStorageBackendBuildVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendBuildVol)(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags); -typedef int (*virStorageBackendCreateVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendCreateVol)(virStoragePoolObjPtr pool, virStorageVolDefPtr vol); -typedef int (*virStorageBackendRefreshVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendRefreshVol)(virStoragePoolObjPtr pool, virStorageVolDefPtr vol); -typedef int (*virStorageBackendDeleteVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendDeleteVol)(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags); -typedef int (*virStorageBackendBuildVolFrom)(virConnectPtr conn, - virStoragePoolObjPtr pool, +typedef int (*virStorageBackendBuildVolFrom)(virStoragePoolObjPtr pool, virStorageVolDefPtr origvol, virStorageVolDefPtr newvol, unsigned int flags); -typedef int
[libvirt] [PATCH 06/10] interface: allow opening with interface:///system and interface:///session URIs
Allow the possibility of opening a connection to only the interface driver, by defining interface:///system and interface:///session URIs and registering a fake hypervisor driver that supports them. The hypervisor drivers can now directly open a interface driver connection at time of need, instead of having to pass around a virConnectPtr through many functions. This will facilitate the later change to support separate daemons for each driver. Signed-off-by: Daniel P. Berrangé--- src/interface/interface_backend_netcf.c | 98 - src/interface/interface_backend_udev.c | 97 +++- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index c7cc07122a..9b04271647 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -46,6 +46,7 @@ typedef struct { virObjectLockable parent; struct netcf *netcf; +bool privileged; } virNetcfDriverState, *virNetcfDriverStatePtr; static virClassPtr virNetcfDriverStateClass; @@ -78,7 +79,7 @@ virNetcfDriverStateDispose(void *obj) static int -netcfStateInitialize(bool privileged ATTRIBUTE_UNUSED, +netcfStateInitialize(bool privileged, virStateInhibitCallback callback ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED) { @@ -88,6 +89,8 @@ netcfStateInitialize(bool privileged ATTRIBUTE_UNUSED, if (!(driver = virObjectLockableNew(virNetcfDriverStateClass))) return -1; +driver->privileged = privileged; + /* open netcf */ if (ncf_init(>netcf, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -148,6 +151,80 @@ netcfStateReload(void) } +static virDrvOpenStatus netcfConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + virConfPtr conf ATTRIBUTE_UNUSED, + unsigned int flags) +{ +virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + +/* Verify uri was specified */ +if (conn->uri == NULL) { +/* Only hypervisor drivers are permitted to auto-open on NULL uri */ +return VIR_DRV_OPEN_DECLINED; +} else { +if (STRNEQ_NULLABLE(conn->uri->scheme, "interface")) +return VIR_DRV_OPEN_DECLINED; + +/* Leave for remote driver */ +if (conn->uri->server != NULL) +return VIR_DRV_OPEN_DECLINED; + +if (driver == NULL) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("interface state driver is not active")); +return VIR_DRV_OPEN_ERROR; +} + +if (driver->privileged) { +if (STRNEQ(conn->uri->path, "/system")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected interface URI path '%s', try interface:///system"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} else { +if (STRNEQ(conn->uri->path, "/session")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected interface URI path '%s', try interface:///session"), + conn->uri->path); +return VIR_DRV_OPEN_ERROR; +} +} +} + +if (virConnectOpenEnsureACL(conn) < 0) +return VIR_DRV_OPEN_ERROR; + +return VIR_DRV_OPEN_SUCCESS; +} + +static int netcfConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 0; +} + + +static int netcfConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Trivially secure, since always inside the daemon */ +return 1; +} + + +static int netcfConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +/* Not encrypted, but remote driver takes care of that */ +return 0; +} + + +static int netcfConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return 1; +} + + /* * Get a minimal virInterfaceDef containing enough metadata * for access control checks to be performed. Currently @@ -1134,6 +1211,23 @@ static virInterfaceDriver interfaceDriver = { #endif /* HAVE_NETCF_TRANSACTIONS */ }; + +static virHypervisorDriver interfaceHypervisorDriver = { +.name = "interface", +.connectOpen = netcfConnectOpen, /* 4.1.0 */ +.connectClose = netcfConnectClose, /* 4.1.0 */ +.connectIsEncrypted = netcfConnectIsEncrypted, /* 4.1.0 */ +.connectIsSecure = netcfConnectIsSecure, /* 4.1.0 */ +.connectIsAlive = netcfConnectIsAlive, /* 4.1.0 */ +}; + + +static virConnectDriver interfaceConnectDriver = { +.hypervisorDriver = , +.interfaceDriver = , +}; + + static virStateDriver interfaceStateDriver = { .name = INTERFACE_DRIVER_NAME, .stateInitialize = netcfStateInitialize,
[libvirt] [PATCH 03/10] network: move driver registration back to end of the file
By convention the last thing in the driver.c files should be the driver callback table and function to register it. Signed-off-by: Daniel P. Berrangé--- src/network/bridge_driver.c | 90 ++--- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 334da7a85d..7f21381bd4 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -4241,51 +4241,6 @@ networkGetDHCPLeases(virNetworkPtr net, } -static virNetworkDriver networkDriver = { -.name = "bridge", -.connectNumOfNetworks = networkConnectNumOfNetworks, /* 0.2.0 */ -.connectListNetworks = networkConnectListNetworks, /* 0.2.0 */ -.connectNumOfDefinedNetworks = networkConnectNumOfDefinedNetworks, /* 0.2.0 */ -.connectListDefinedNetworks = networkConnectListDefinedNetworks, /* 0.2.0 */ -.connectListAllNetworks = networkConnectListAllNetworks, /* 0.10.2 */ -.connectNetworkEventRegisterAny = networkConnectNetworkEventRegisterAny, /* 1.2.1 */ -.connectNetworkEventDeregisterAny = networkConnectNetworkEventDeregisterAny, /* 1.2.1 */ -.networkLookupByUUID = networkLookupByUUID, /* 0.2.0 */ -.networkLookupByName = networkLookupByName, /* 0.2.0 */ -.networkCreateXML = networkCreateXML, /* 0.2.0 */ -.networkDefineXML = networkDefineXML, /* 0.2.0 */ -.networkUndefine = networkUndefine, /* 0.2.0 */ -.networkUpdate = networkUpdate, /* 0.10.2 */ -.networkCreate = networkCreate, /* 0.2.0 */ -.networkDestroy = networkDestroy, /* 0.2.0 */ -.networkGetXMLDesc = networkGetXMLDesc, /* 0.2.0 */ -.networkGetBridgeName = networkGetBridgeName, /* 0.2.0 */ -.networkGetAutostart = networkGetAutostart, /* 0.2.1 */ -.networkSetAutostart = networkSetAutostart, /* 0.2.1 */ -.networkIsActive = networkIsActive, /* 0.7.3 */ -.networkIsPersistent = networkIsPersistent, /* 0.7.3 */ -.networkGetDHCPLeases = networkGetDHCPLeases, /* 1.2.6 */ -}; - -static virStateDriver networkStateDriver = { -.name = "bridge", -.stateInitialize = networkStateInitialize, -.stateAutoStart = networkStateAutoStart, -.stateCleanup = networkStateCleanup, -.stateReload = networkStateReload, -}; - -int -networkRegister(void) -{ -if (virSetSharedNetworkDriver() < 0) -return -1; -if (virRegisterStateDriver() < 0) -return -1; -return 0; -} - - /* A unified function to log network connections and disconnections */ static void @@ -5716,3 +5671,48 @@ networkBandwidthUpdate(virDomainNetDefPtr iface, virNetworkObjEndAPI(); return ret; } + + +static virNetworkDriver networkDriver = { +.name = "bridge", +.connectNumOfNetworks = networkConnectNumOfNetworks, /* 0.2.0 */ +.connectListNetworks = networkConnectListNetworks, /* 0.2.0 */ +.connectNumOfDefinedNetworks = networkConnectNumOfDefinedNetworks, /* 0.2.0 */ +.connectListDefinedNetworks = networkConnectListDefinedNetworks, /* 0.2.0 */ +.connectListAllNetworks = networkConnectListAllNetworks, /* 0.10.2 */ +.connectNetworkEventRegisterAny = networkConnectNetworkEventRegisterAny, /* 1.2.1 */ +.connectNetworkEventDeregisterAny = networkConnectNetworkEventDeregisterAny, /* 1.2.1 */ +.networkLookupByUUID = networkLookupByUUID, /* 0.2.0 */ +.networkLookupByName = networkLookupByName, /* 0.2.0 */ +.networkCreateXML = networkCreateXML, /* 0.2.0 */ +.networkDefineXML = networkDefineXML, /* 0.2.0 */ +.networkUndefine = networkUndefine, /* 0.2.0 */ +.networkUpdate = networkUpdate, /* 0.10.2 */ +.networkCreate = networkCreate, /* 0.2.0 */ +.networkDestroy = networkDestroy, /* 0.2.0 */ +.networkGetXMLDesc = networkGetXMLDesc, /* 0.2.0 */ +.networkGetBridgeName = networkGetBridgeName, /* 0.2.0 */ +.networkGetAutostart = networkGetAutostart, /* 0.2.1 */ +.networkSetAutostart = networkSetAutostart, /* 0.2.1 */ +.networkIsActive = networkIsActive, /* 0.7.3 */ +.networkIsPersistent = networkIsPersistent, /* 0.7.3 */ +.networkGetDHCPLeases = networkGetDHCPLeases, /* 1.2.6 */ +}; + +static virStateDriver networkStateDriver = { +.name = "bridge", +.stateInitialize = networkStateInitialize, +.stateAutoStart = networkStateAutoStart, +.stateCleanup = networkStateCleanup, +.stateReload = networkStateReload, +}; + +int +networkRegister(void) +{ +if (virSetSharedNetworkDriver() < 0) +return -1; +if (virRegisterStateDriver() < 0) +return -1; +return 0; +} -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 5/9] qemu: Introduce qemuDomainGetJobInfoMigrationStats
On Fri, Jan 19, 2018 at 14:53:12 -0500, John Ferlan wrote: > Extract out the parts of qemuDomainGetJobStatsInternal that get > the migration stats. We're about to add the ability to get just > dump information. > > Signed-off-by: John Ferlan> --- > src/qemu/qemu_driver.c | 52 > -- > 1 file changed, 33 insertions(+), 19 deletions(-) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 266a76b0e..00a010b45 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -13155,13 +13155,43 @@ qemuConnectBaselineCPU(virConnectPtr conn > ATTRIBUTE_UNUSED, > > > static int > +qemuDomainGetJobInfoMigrationStats(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + qemuDomainJobInfoPtr jobInfo) > +{ > +qemuDomainObjPrivatePtr priv = vm->privateData; > +bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); > + > +if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE || > +jobInfo->status == QEMU_DOMAIN_JOB_STATUS_MIGRATING || > +jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED || > +jobInfo->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY) { > +if (events && > +jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE && > +qemuMigrationFetchStats(driver, vm, QEMU_ASYNC_JOB_NONE, > +jobInfo, NULL) < 0) > +return -1; > + > +if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE && > +qemuMigrationFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_NONE, > + jobInfo) < 0) I just realized we would happily try to fetch storage migration stats even if the job is not really a migration one (e.g., save or dump). We should fix this in a separate patch... > +return -1; > + > +if (qemuDomainJobInfoUpdateTime(jobInfo) < 0) > +return -1; > +} > + > +return 0; > +} ... ACK Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv4 RESEND] vhost-user: add support reconnect for vhost-user ports
On 01/17/2018 05:14 PM, ZhiPeng Lu wrote: > For vhost-user ports, Open vSwitch acts as the server and QEMU the client. > When OVS crashes or restarts, the QEMU process should be reconnected to > OVS. > > Signed-off-by: ZhiPeng Lu> Signed-off-by: Michal Privoznik > --- > v1->v2: > - modify xml format > v2->v3: > - fix commit message syntax > - reimplemente functions and the struct about reconnect > v3->v4: > - revert reimplemente functions and the struct about reconnect > --- > docs/formatdomain.html.in| 7 +- > docs/schemas/domaincommon.rng| 26 ++-- > src/conf/domain_conf.c | 158 > +-- > tests/qemuxml2argvdata/net-vhostuser-multiq.args | 12 +- > tests/qemuxml2argvdata/net-vhostuser-multiq.xml | 11 +- > 5 files changed, 127 insertions(+), 87 deletions(-) > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index d272cc1..f0f9f4b 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -5832,7 +5832,9 @@ qemu-kvm -net nic,model=? /dev/null >/interface >interface type='vhostuser' > mac address='52:54:00:3b:83:1b'/ > -source type='unix' path='/tmp/vhost2.sock' mode='client'/ > +source type='unix' path='/tmp/vhost2.sock' mode='client' > + reconnect enabled='yes' timeout='10'/ > +/source Extra space at EOL. > model type='virtio'/ > driver queues='5'/ >/interface > @@ -5848,6 +5850,9 @@ qemu-kvm -net nic,model=? /dev/null >are supported. >vhost-user requires the virtio model type, thus the >model element is mandatory. > + Since 3.10.0 the element has an optional Since 4.1.0 > + attribute reconnect which configures reconnect timeout Not attribute. Child element. > + (in seconds) if the connection is lost. > > > Traffic filtering with NWFilter > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng > index f22c932..9258c7d 100644 > --- a/docs/schemas/domaincommon.rng > +++ b/docs/schemas/domaincommon.rng > @@ -2399,6 +2399,18 @@ > > > > + > + > + > + > + > + > + > + > + > + > + > + > >
Re: [libvirt] [PATCH 07/15] nodedev: Introduce virNodeDeviceCapsListExport
> -Original Message- > From: libvir-list-boun...@redhat.com [mailto:libvir-list- > boun...@redhat.com] On Behalf Of Erik Skultety > Sent: Thursday, January 25, 2018 5:24 PM > To: libvir-list@redhat.com > Cc: Erik Skultety> Subject: [libvirt] [PATCH 07/15] nodedev: Introduce > virNodeDeviceCapsListExport > > Whether asking for a number of capabilities supported by a device or > listing them, it's handled essentially by a copy-paste code, so extract > the common stuff into this new helper which also updates all capabilities > just before touching them. > > Signed-off-by: Erik Skultety > --- > src/conf/node_device_conf.c | 73 > +++ > src/conf/node_device_conf.h | 5 +++ > src/libvirt_private.syms | 1 + > src/node_device/node_device_driver.c | 75 +-- > - > 4 files changed, 97 insertions(+), 57 deletions(-) > > diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c > index 217673a56..9467bb415 100644 > --- a/src/conf/node_device_conf.c > +++ b/src/conf/node_device_conf.c > @@ -2487,6 +2487,79 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) } > > > +/** > + * virNodeDeviceCapsListExport: > + * @def: node device definition > + * @list: pointer to an array to store all supported capabilities by a > +device > + * > + * Takes the definition, scans through all the capabilities that the > +device > + * supports (including the nested caps) and populates a newly allocated > +list > + * with them. Caller is responsible for freeing the list. > + * If NULL is passed to @list, only the number of caps will be returned. > + * > + * Returns the number of capabilities the device supports, -1 on error. > + */ > +int > +virNodeDeviceCapsListExport(virNodeDeviceDefPtr def, > +virNodeDevCapType **list) { > +virNodeDevCapsDefPtr caps = NULL; > +virNodeDevCapType *tmp = NULL; > +bool want_list = !!list; > +int ncaps = 0; > +int ret = -1; > + > +#define MAYBE_ADD_CAP(cap) \ > +do { \ > +if (want_list) \ > +tmp[ncaps] = cap; \ > +} while (0) > + > +if (want_list && VIR_ALLOC_N(tmp, VIR_NODE_DEV_CAP_LAST - 1) < 0) > +goto cleanup; > + > +for (caps = def->caps; caps; caps = caps->next) { > +unsigned int flags; > + > +MAYBE_ADD_CAP(caps->data.type); > +ncaps++; > + > +/* check nested caps for a given type as well */ > +if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) { > +flags = caps->data.scsi_host.flags; > + > +if (flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { > +MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_FC_HOST); > +ncaps++; > +} > + > +if (flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) { > +MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_VPORTS); > +ncaps++; > +} > +} > + > +if (caps->data.type == VIR_NODE_DEV_CAP_PCI_DEV) { > +flags = caps->data.pci_dev.flags; > + > +if (flags & VIR_NODE_DEV_CAP_FLAG_PCI_MDEV) { > +MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_MDEV_TYPES); > +ncaps++; > +} > +} > +} > + > +#undef MAYBE_ADD_CAP > + > +if (want_list) > +VIR_STEAL_PTR(*list, tmp); > +ret = ncaps; > + cleanup: > +VIR_FREE(tmp); > +return ret; > +} > + > + > #ifdef __linux__ > > int > diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h > index 7e32f5c05..53cdfdb01 100644 > --- a/src/conf/node_device_conf.h > +++ b/src/conf/node_device_conf.h > @@ -403,4 +403,9 @@ virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath, > > int > virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def); > + > +int > +virNodeDeviceCapsListExport(virNodeDeviceDefPtr def, > +virNodeDevCapType **list); > + > #endif /* __VIR_NODE_DEVICE_CONF_H__ */ diff --git > a/src/libvirt_private.syms b/src/libvirt_private.syms index > 6098cf121..1698e6227 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -699,6 +699,7 @@ virNodeDevCapMdevTypeFree; virNodeDevCapsDefFree; > virNodeDevCapTypeFromString; virNodeDevCapTypeToString; > +virNodeDeviceCapsListExport; > virNodeDeviceCreateVport; > virNodeDeviceDefFormat; > virNodeDeviceDefFree; > diff --git a/src/node_device/node_device_driver.c > b/src/node_device/node_device_driver.c > index 48f45474c..8fb08742b 100644 > --- a/src/node_device/node_device_driver.c > +++ b/src/node_device/node_device_driver.c > @@ -306,8 +306,6 @@ nodeDeviceNumOfCaps(virNodeDevicePtr device) { > virNodeDeviceObjPtr obj; > virNodeDeviceDefPtr def; > -virNodeDevCapsDefPtr caps; > -int ncaps = 0; > int ret = -1; > > if (!(obj = nodeDeviceObjFindByName(device->name))) > @@ -317,27 +315,7 @@ nodeDeviceNumOfCaps(virNodeDevicePtr device) > if
Re: [libvirt] [PATCH v5 00/16] Move qemu command line controller checks to qemuDomainDeviceDefValidateController* checks
ping^2 Tks - John On 01/19/2018 01:27 PM, John Ferlan wrote: > > ping? > > Should still apply with current top. I can resend if requested. > > Tks, > > John > > On 01/05/2018 06:47 PM, John Ferlan wrote: >> v4: https://www.redhat.com/archives/libvir-list/2017-December/msg00401.html >> >> Changes since v4: >> >> Insert patch 1 to split the qemuDomainSetSCSIControllerModel as has been >> discussed during review. >> >> Adjustments to the SCSI patches as a result. >> >> Added patch 16 from Mark Hartmayer >> >> Andrea Bolognani (1): >> qemu: Add missing checks for pcie-root-port options >> >> John Ferlan (14): >> qemu: Split qemuDomainSetSCSIControllerModel >> qemu: Introduce qemuDomainDeviceDefValidateControllerAttributes >> qemu: Move and rename qemuBuildCheckSCSIControllerModel >> qemu: Move model set for qemuBuildControllerDevStr >> qemu: Adjust SCSI controller switch in qemuBuildControllerDevStr >> qemu: Add check for iothread attribute in validate controller >> qemu: Introduce qemuDomainDeviceDefValidateControllerSCSI >> qemu: Introduce qemuDomainDeviceDefValidateControllerPCI >> qemu: Use virDomainPCIControllerOpts in qemuBuildControllerDevStr >> qemu: Move PCI command modelName check to controller def validate >> qemu: Move PCI command modelName TypeToString to controller def >> validate >> qemu: Move PCI more command checks to controller def validate >> qemu: Complete PCI command checks to controller def validate >> qemu: Introduce qemuDomainDeviceDefValidateControllerSATA >> >> Marc Hartmayer (1): >> qemu: Use switch statement for address types in >> qemuBuildControllerDevStr >> >> src/qemu/qemu_alias.c | 4 +- >> src/qemu/qemu_command.c| 452 +-- >> src/qemu/qemu_domain.c | 474 >> - >> src/qemu/qemu_domain_address.c | 74 ++- >> src/qemu/qemu_domain_address.h | 6 +- >> tests/qemumemlocktest.c| 14 ++ >> tests/qemuxml2xmltest.c| 5 +- >> 7 files changed, 568 insertions(+), 461 deletions(-) >> > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 02/15] conf: nodedev: Rename virNodeDeviceCapMatch to virNodeDevObjHasCap
On 01/25/2018 10:23 AM, Erik Skultety wrote: > We currently have 2 methods that do the capability matching. This should > be condensed to a single function and all the derivates should just call > into that using a proper type conversion. > > Signed-off-by: Erik Skultety> --- > src/conf/virnodedeviceobj.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c > index a4d38b3a1..ccad59a4b 100644 > --- a/src/conf/virnodedeviceobj.c > +++ b/src/conf/virnodedeviceobj.c > @@ -55,6 +55,8 @@ static void virNodeDeviceObjDispose(void *opaque); > static void virNodeDeviceObjListDispose(void *opaque); > static bool virNodeDeviceObjHasCapStr(const virNodeDeviceObj *obj, >const char *cap); > +static bool virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, > + int type); > Again, I'm failing to see why the forward declaration is needed. ACk to the rest. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 01/15] conf: nodedev: Rename virNodeDevObjHasCap to virNodeDevObjHasCapStr
On 01/25/2018 10:23 AM, Erik Skultety wrote: > We currently have 2 methods that do the capability matching. This should > be condensed to a single function and all the derivates should just call > into that using a proper type conversion. > > Signed-off-by: Erik Skultety> --- > src/conf/virnodedeviceobj.c | 12 +++- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c > index c4e3a40d3..a4d38b3a1 100644 > --- a/src/conf/virnodedeviceobj.c > +++ b/src/conf/virnodedeviceobj.c > @@ -53,6 +53,8 @@ static virClassPtr virNodeDeviceObjClass; > static virClassPtr virNodeDeviceObjListClass; > static void virNodeDeviceObjDispose(void *opaque); > static void virNodeDeviceObjListDispose(void *opaque); > +static bool virNodeDeviceObjHasCapStr(const virNodeDeviceObj *obj, > + const char *cap); > I'm failing to see why this needed. ACK to the rest though. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 03/15] conf: nodedev: Convert virNodeDevObjHasCapStr to a simple wrapper
On 01/25/2018 10:23 AM, Erik Skultety wrote: > This patch drops the capability matching redundancy by simply converting > the string input to our internal types which are then in turn used for > the actual capability matching. > > Signed-off-by: Erik Skultety> --- > src/conf/virnodedeviceobj.c | 50 > + > 1 file changed, 1 insertion(+), 49 deletions(-) > > diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c > index ccad59a4b..5360df805 100644 > --- a/src/conf/virnodedeviceobj.c > +++ b/src/conf/virnodedeviceobj.c > @@ -128,55 +128,7 @@ static bool > virNodeDeviceObjHasCapStr(const virNodeDeviceObj *obj, >const char *cap) > { > -virNodeDevCapsDefPtr caps = obj->def->caps; > -const char *fc_host_cap = > -virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST); > -const char *vports_cap = > -virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); > -const char *mdev_types = > -virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_MDEV_TYPES); > - > -while (caps) { > -if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type))) { > -return true; > -} else { > -switch (caps->data.type) { > -case VIR_NODE_DEV_CAP_PCI_DEV: > -if ((STREQ(cap, mdev_types)) && > -(caps->data.pci_dev.flags & > VIR_NODE_DEV_CAP_FLAG_PCI_MDEV)) > -return true; > -break; > - > -case VIR_NODE_DEV_CAP_SCSI_HOST: > -if ((STREQ(cap, fc_host_cap) && > -(caps->data.scsi_host.flags & > VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) || > -(STREQ(cap, vports_cap) && > -(caps->data.scsi_host.flags & > VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))) > -return true; > -break; > - > -case VIR_NODE_DEV_CAP_SYSTEM: > -case VIR_NODE_DEV_CAP_USB_DEV: > -case VIR_NODE_DEV_CAP_USB_INTERFACE: > -case VIR_NODE_DEV_CAP_NET: > -case VIR_NODE_DEV_CAP_SCSI_TARGET: > -case VIR_NODE_DEV_CAP_SCSI: > -case VIR_NODE_DEV_CAP_STORAGE: > -case VIR_NODE_DEV_CAP_FC_HOST: > -case VIR_NODE_DEV_CAP_VPORTS: > -case VIR_NODE_DEV_CAP_SCSI_GENERIC: > -case VIR_NODE_DEV_CAP_DRM: > -case VIR_NODE_DEV_CAP_MDEV_TYPES: > -case VIR_NODE_DEV_CAP_MDEV: > -case VIR_NODE_DEV_CAP_CCW_DEV: > -case VIR_NODE_DEV_CAP_LAST: > -break; > -} > -} > - > -caps = caps->next; > -} > -return false; > +return virNodeDeviceObjHasCap(obj, virNodeDevCapTypeFromString(cap)); I wonder if we should check for the TypeFromString() conversion rather than pass it to the other function directly. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 05/15] nodedev: Move the sysfs-related cap handling to node_device_conf.c
On 01/25/2018 10:23 AM, Erik Skultety wrote: > The capabilities are defined/parsed/formatted/queried from this module, > no reason for 'update' not being part of the module as well. This also > involves some module-specific prefix changes. > This patch also drops the node_device_linux_sysfs module from the repo > since: > a) it only contained the capability handlers we just moved > b) it's only linked with the driver (by design) and thus unreachable to > other modules > c) we touch sysfs across all the src/util modules so the module being > deleted hasn't been serving its original intention for some time already. > > Signed-off-by: Erik Skultety> --- > src/Makefile.am | 4 +- > src/conf/node_device_conf.c | 154 +- > src/conf/node_device_conf.h | 7 + > src/libvirt_private.syms | 2 + > src/node_device/node_device_driver.c | 7 +- > src/node_device/node_device_hal.c | 1 - > src/node_device/node_device_linux_sysfs.c | 206 > -- > src/node_device/node_device_linux_sysfs.h | 33 - > src/node_device/node_device_udev.c| 5 +- > 9 files changed, 168 insertions(+), 251 deletions(-) > delete mode 100644 src/node_device/node_device_linux_sysfs.c > delete mode 100644 src/node_device/node_device_linux_sysfs.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index 166c9a8e9..b8ecd8df8 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -1168,9 +1168,7 @@ ACCESS_DRIVER_POLKIT_POLICY = \ > > NODE_DEVICE_DRIVER_SOURCES = \ > node_device/node_device_driver.c \ > - node_device/node_device_driver.h \ > - node_device/node_device_linux_sysfs.c \ > - node_device/node_device_linux_sysfs.h > + node_device/node_device_driver.h > > NODE_DEVICE_DRIVER_HAL_SOURCES = \ > node_device/node_device_hal.c \ > diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c > index 70a753ebf..5b0af559a 100644 > --- a/src/conf/node_device_conf.c > +++ b/src/conf/node_device_conf.c > int > -virNodeDeviceGetSCSIHostCaps(virNodeDevCap) > +virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath, > + virNodeDevCapPCIDevPtr pci_dev) > +{ ATTRIBUTE_UNUSED to both. Also, it seems interesting that for rename of SCSI version of the function you have a separate patch but for PCI you do it in one run. I share your feelings towards PCI, SCSI is so much better bus and thus deserves its own patch :-) > +return -1; > +} > + > + > +int virNodeDeviceGetSCSITargetCaps(const char *sysfsPath ATTRIBUTE_UNUSED, > + virNodeDevCapSCSITargetPtr scsi_target > ATTRIBUTE_UNUSED) > { > return -1; > } > diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h > index cf79773aa..4e3154875 100644 > --- a/src/conf/node_device_conf.h > +++ b/src/conf/node_device_conf.h > @@ -393,4 +393,11 @@ virNodeDeviceDeleteVport(virConnectPtr conn, > int > virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); > > +int > +virNodeDeviceGetSCSITargetCaps(const char *sysfsPath, > + virNodeDevCapSCSITargetPtr scsi_target); > + > +int > +virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath, > + virNodeDevCapPCIDevPtr pci_dev); > #endif /* __VIR_NODE_DEVICE_CONF_H__ */ > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index bc8cc1fba..0cd8086a6 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -707,7 +707,9 @@ virNodeDeviceDefParseNode; > virNodeDeviceDefParseString; > virNodeDeviceDeleteVport; > virNodeDeviceGetParentName; > +virNodeDeviceGetPCIDynamicCaps; > virNodeDeviceGetSCSIHostCaps; > +virNodeDeviceGetSCSITargetCaps; > virNodeDeviceGetWWNs; > > > diff --git a/src/node_device/node_device_driver.c > b/src/node_device/node_device_driver.c > index a2f687942..2e42d3527 100644 > --- a/src/node_device/node_device_driver.c > +++ b/src/node_device/node_device_driver.c > @@ -38,7 +38,6 @@ > #include "node_device_event.h" > #include "node_device_driver.h" > #include "node_device_hal.h" > -#include "node_device_linux_sysfs.h" > #include "virvhba.h" > #include "viraccessapicheck.h" > #include "virnetdev.h" > @@ -59,7 +58,7 @@ nodeDeviceUpdateCaps(virNodeDeviceDefPtr def) > virNodeDeviceGetSCSIHostCaps(>data.scsi_host); > break; > case VIR_NODE_DEV_CAP_SCSI_TARGET: > -nodeDeviceSysfsGetSCSITargetCaps(def->sysfs_path, > +virNodeDeviceGetSCSITargetCaps(def->sysfs_path, > >data.scsi_target); > break; > case VIR_NODE_DEV_CAP_NET: > @@ -70,8 +69,8 @@ nodeDeviceUpdateCaps(virNodeDeviceDefPtr def) > return -1; > break; > case
Re: [libvirt] [PATCH 08/15] conf: nodedev: Refresh capabilities before touching them
On 01/25/2018 10:23 AM, Erik Skultety wrote: > Most of them are static, however in case of PCI and SCSI_HOST devices, > the nested capabilities can change dynamically, e.g. due to a driver > change (from host_pci_driver -> vfio_pci). > > Signed-off-by: Erik Skultety> Suggested-by: Wu Zongyong > --- > src/conf/node_device_conf.c | 3 +++ > src/conf/virnodedeviceobj.c | 4 > 2 files changed, 7 insertions(+) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 11/15] util: mdev: Introduce virMediatedDeviceTypeReadAttrs getter
On 01/25/2018 10:23 AM, Erik Skultety wrote: > This should serve as a replacement for the existing udevFillMdevType > which is responsible for fetching the device type's attributes from the > sysfs interface. The problem with the existing solution is that it's > tied to the udev backend. > > Signed-off-by: Erik Skultety> --- > src/util/virmdev.c | 34 ++ > src/util/virmdev.h | 5 + > 2 files changed, 39 insertions(+) > > diff --git a/src/util/virmdev.c b/src/util/virmdev.c > index db679b8a6..b57cc3ed9 100644 > --- a/src/util/virmdev.c > +++ b/src/util/virmdev.c > @@ -496,3 +496,37 @@ virMediatedDeviceTypeFree(virMediatedDeviceTypePtr type) > VIR_FREE(type->device_api); > VIR_FREE(type); > } > + > + > +int > +virMediatedDeviceTypeReadAttrs(const char *sysfspath, > + virMediatedDeviceTypePtr *type) > +{ > +int ret = -1; > +virMediatedDeviceTypePtr tmp = NULL; > + > +#define MDEV_GET_SYSFS_ATTR(attr, dst, cb) \ > +do { \ > +if (cb(dst, "%s/%s", sysfspath, attr) < 0) \ > +goto cleanup; \ > +} while (0) \ Drop this backward slash. > + > +if (VIR_ALLOC(tmp) < 0) > +goto cleanup; > + > +if (VIR_STRDUP(tmp->id, last_component(sysfspath)) < 0) > +goto cleanup; > + > +MDEV_GET_SYSFS_ATTR("name", >name, virFileReadValueString); > +MDEV_GET_SYSFS_ATTR("device_api", >device_api, > virFileReadValueString); > +MDEV_GET_SYSFS_ATTR("available_instances", >available_instances, > +virFileReadValueUint); > + > +#undef MDEV_GET_SYSFS_ATTR > + > +VIR_STEAL_PTR(*type, tmp); > +ret = 0; > + cleanup: > +virMediatedDeviceTypeFree(tmp); > +return ret; > +} > diff --git a/src/util/virmdev.h b/src/util/virmdev.h > index 320610ab9..01ab02e75 100644 > --- a/src/util/virmdev.h > +++ b/src/util/virmdev.h > @@ -129,4 +129,9 @@ virMediatedDeviceListMarkDevices(virMediatedDeviceListPtr > dst, > > void > virMediatedDeviceTypeFree(virMediatedDeviceTypePtr type); > + > +int > +virMediatedDeviceTypeReadAttrs(const char *sysfspath, > + virMediatedDeviceTypePtr *type); ACK if you also expose the function in libvirt_private.syms. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 04/15] nodedev: Drop the nodeDeviceSysfsGetSCSIHostCaps wrapper
On 01/25/2018 10:23 AM, Erik Skultety wrote: > We can call directly the virNodeDeviceGetSCSIHostCaps helper instead. > > Signed-off-by: Erik Skultety> --- > src/conf/node_device_conf.c | 12 > src/node_device/node_device_driver.c | 2 +- > src/node_device/node_device_hal.c | 4 ++-- > src/node_device/node_device_linux_sysfs.c | 12 > src/node_device/node_device_linux_sysfs.h | 1 - > src/node_device/node_device_udev.c| 2 +- > 6 files changed, 16 insertions(+), 17 deletions(-) > > diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c > index bf84fd2b3..70a753ebf 100644 > --- a/src/conf/node_device_conf.c > +++ b/src/conf/node_device_conf.c > @@ -2431,6 +2431,8 @@ virNodeDeviceDeleteVport(virConnectPtr conn, > } > > > +#ifdef __linux__ > + > int > virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host) > { > @@ -2511,3 +2513,13 @@ virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr > scsi_host) > VIR_FREE(tmp); > return ret; > } > + > +#else > + > +int > +virNodeDeviceGetSCSIHostCaps(virNodeDevCap) The linux version of this function takes virNodeDevCapSCSIHostPtr. This non-linux should do so too. Also, you should give the argument a name and mark it as ATTRIBUTE_UNUSED. > +{ > +return -1; > +} > + > +#endif /* __linux__ */ > diff --git a/src/node_device/node_device_driver.c > b/src/node_device/node_device_driver.c > index 6216a6977..a2f687942 100644 > --- a/src/node_device/node_device_driver.c > +++ b/src/node_device/node_device_driver.c > @@ -56,7 +56,7 @@ nodeDeviceUpdateCaps(virNodeDeviceDefPtr def) > while (cap) { > switch (cap->data.type) { > case VIR_NODE_DEV_CAP_SCSI_HOST: > -nodeDeviceSysfsGetSCSIHostCaps(>data.scsi_host); > +virNodeDeviceGetSCSIHostCaps(>data.scsi_host); > break; > case VIR_NODE_DEV_CAP_SCSI_TARGET: > nodeDeviceSysfsGetSCSITargetCaps(def->sysfs_path, > diff --git a/src/node_device/node_device_hal.c > b/src/node_device/node_device_hal.c > index c19e327c9..4c50f4613 100644 > --- a/src/node_device/node_device_hal.c > +++ b/src/node_device/node_device_hal.c > @@ -151,7 +151,7 @@ gather_pci_cap(LibHalContext *ctx, const char *udi, > ignore_value(virStrToLong_ui(p+1, , 16, >pci_dev.function)); > } > > -if (nodeDeviceSysfsGetPCIRelatedDevCaps(sysfs_path, >pci_dev) < > 0) { > +if (virNodeDeviceGetPCIDynamicCaps(sysfs_path, >pci_dev) < 0) { > VIR_FREE(sysfs_path); > return -1; This doesn't look right. You're not changing PCI function in this patch. ACK to the rest. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 06/15] nodedev: Export nodeDeviceUpdateCaps from node_device_conf.c
On 01/25/2018 10:23 AM, Erik Skultety wrote: > Since we moved the helpers from nodedev driver to src/conf, the actual > 'update' function using those helpers should be moved as well so that we > don't need to call back into the driver. > > Signed-off-by: Erik Skultety> --- > src/conf/node_device_conf.c | 54 > > src/conf/node_device_conf.h | 3 ++ > src/libvirt_private.syms | 1 + > src/node_device/node_device_driver.c | 54 > +--- > 4 files changed, 59 insertions(+), 53 deletions(-) > ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 09/15] util: mdev: Drop some unused symbols/includes from the header
On 01/25/2018 10:23 AM, Erik Skultety wrote: > There were some leftovers from early development which never got used. > > Signed-off-by: Erik Skultety> --- > src/util/virmdev.h | 3 --- > 1 file changed, 3 deletions(-) ACK, nice. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 12/15] util: pci: Introduce virPCIGetMdevTypes helper
On 01/25/2018 10:23 AM, Erik Skultety wrote: > This is a replacement for the existing udevPCIGetMdevTypesCap which is > static to the udev backend. This simple helper constructs the sysfs path > from the device's base path for each mdev type and queries the > corresponding attributes of that type. > > Signed-off-by: Erik Skultety> --- > src/libvirt_private.syms | 1 + > src/util/virpci.c| 58 > > src/util/virpci.h| 4 > 3 files changed, 63 insertions(+) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 75eaf1d4c..8d4c8dd3f 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -2456,6 +2456,7 @@ virPCIDeviceWaitForCleanup; > virPCIEDeviceInfoFree; > virPCIGetDeviceAddressFromSysfsLink; > virPCIGetHeaderType; > +virPCIGetMdevTypes; > virPCIGetNetName; > virPCIGetPhysicalFunction; > virPCIGetVirtualFunctionIndex; > diff --git a/src/util/virpci.c b/src/util/virpci.c > index fe57bef32..12d7ef0e4 100644 > --- a/src/util/virpci.c > +++ b/src/util/virpci.c > @@ -3027,6 +3027,64 @@ virPCIGetVirtualFunctionInfo(const char > *vf_sysfs_device_path, > return ret; > } > > + > +int > +virPCIGetMdevTypes(const char *sysfspath, > + virMediatedDeviceTypePtr **types) Since this function returns size_t on success, I guess the retval should be type of ssize_t at least. We are not guaranteed that size_t will fit into int (although in this case it will - currently you will have only limited number of MDEVs if any). ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 07/15] nodedev: Introduce virNodeDeviceCapsListExport
On 01/25/2018 10:23 AM, Erik Skultety wrote: > Whether asking for a number of capabilities supported by a device or > listing them, it's handled essentially by a copy-paste code, so extract > the common stuff into this new helper which also updates all > capabilities just before touching them. > > Signed-off-by: Erik Skultety> --- > src/conf/node_device_conf.c | 73 +++ > src/conf/node_device_conf.h | 5 +++ > src/libvirt_private.syms | 1 + > src/node_device/node_device_driver.c | 75 > +--- > 4 files changed, 97 insertions(+), 57 deletions(-) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 10/15] util: mdev: Introduce virMediatedDeviceType structure
On 01/25/2018 10:23 AM, Erik Skultety wrote: > This is later going to replace the existing virNodeDevCapMdevType, since: > 1) it's going to couple related stuff in a single module > 2) util is supposed to contain helpers that are widely accessible across > the whole repository. > > Signed-off-by: Erik Skultety> --- > src/libvirt_private.syms | 1 + > src/util/virmdev.c | 13 + > src/util/virmdev.h | 12 > 3 files changed, 26 insertions(+) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 14/15] conf: Replace usage of virNodeDevCapMdevType with virMediatedDeviceType
On 01/25/2018 10:24 AM, Erik Skultety wrote: > Now that we have all the building blocks in place, switch the nodedev > driver to use the "new" virMediatedDeviceType type instead of the "old" > virNodeDevCapMdevType one. > > Signed-off-by: Erik Skultety> --- > src/conf/node_device_conf.c | 21 - > src/conf/node_device_conf.h | 14 +- > src/libvirt_private.syms| 1 - > 3 files changed, 5 insertions(+), 31 deletions(-) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 13/15] nodedev: udev: Drop the unused mdev type helpers
On 01/25/2018 10:24 AM, Erik Skultety wrote: > These are not necessary anymore, since these are going to be shadowed by > the helpers provided by util/virmdev.c module. > > Signed-off-by: Erik Skultety> --- > src/node_device/node_device_udev.c | 119 > - > 1 file changed, 119 deletions(-) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 15/15] conf: nodedev: Update PCI mdev capabilities dynamically
On 01/25/2018 10:24 AM, Erik Skultety wrote: > Just like SRIOV, a PCI device is only capable of the mediated devices > framework when it's bound to the vendor native driver, thus if a driver > change occurs, e.g. vendor_native->vfio, we need to refresh some of the > device's capabilities to reflect the reality, mdev included. > > Signed-off-by: Erik Skultety> Suggested-by: Wu Zongyong > --- > src/conf/node_device_conf.c| 34 +++--- > src/node_device/node_device_udev.c | 1 - > 2 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/src/node_device/node_device_udev.c > b/src/node_device/node_device_udev.c > index 1ccf1f8b4..e10660ba0 100644 > --- a/src/node_device/node_device_udev.c > +++ b/src/node_device/node_device_udev.c > @@ -484,7 +484,6 @@ udevProcessPCI(struct udev_device *device, > } > > ret = 0; > - > cleanup: > virPCIDeviceFree(pciDev); > virPCIEDeviceInfoFree(pci_express); > Unrelated change. ACK to the rest. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/9] Resolve libvirtd hang on termination with connected long running client
On Fri, Jan 26, 2018 at 11:47:04AM +0300, Nikolay Shirokovskiy wrote: > > > On 19.01.2018 20:23, John Ferlan wrote: > > RFC: > > https://www.redhat.com/archives/libvir-list/2018-January/msg00318.html > > > > Adjustments since RFC... > > > > Patches 1&2: No change, were already R-B'd > > Patch 3: Removed code as noted in code review, update commit message > > Patch 4: From old series removed, see below for more details > > Patch 9: no change > > NB: Patches 5-8 and 10 from Nikolay Shirokovskiy > >> > are removed as they seemed to not be necessary > > > > Replaced the former patch 4 with series of patches to (slowly) provide > > support to disable new connections, handle removing waiting jobs, causing > > the waiting workers to quit, and allow any running jobs to complete. > > > > As it turns out, waiting for running jobs to complete cannot be done > > from the virNetServerClose callbacks because that means the event loop > > processing done during virNetServerRun will not allow any currently > > long running worker job thread a means to complete. > > Hi, John. > > So you suggest a different appoarch. Instead of introducing means to > help rpc threads to finish after event loop is finished (stateShutdown hook > in my series) > you suggest to block futher new rpc processing and then waiting running > rpc calls to finish keeping event loop running for that purpose. > > This could lead to libvirtd never finish its termination if one of > qemu processes do not respond for example. In case of long running > operation such as migration finishing can take much time. On the > over hand if we finish rpc threads abruptly as in case of stateShutdown hook > we will deal with all possible error paths on daemon finishing. May > be good approach is to abort long running operation, then give rpc threads > some time to finish as you suggest and only after that finish them abruptly > to handle hanging qemu etc. We should keep in mind why we are bothering todo any of this "graceful" cleanup. 99% of the time it would be fine for libvirtd to just immediately immediately exit and not run any cleanup code, since the OS cleans everything up regardless. Really the only benefit of running cleanup is so that developers can check for memory leaks across the process execution. On balance it is *way* more important that libvirtd is guranteed to exit in a short, finite amount of time, even if that means skipping cleanup, because that is what is relevant to production deployment. So this means while it is nice to wait for worker threads to complete their current RPC option, we should not wait too long. eg Give them 15 seconds to finish their work, and if they're not done then just unconditionally exit libvirtd, possibly skipping remaining cleanup if that's neccessary to avoid SEGV. Regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/9] Resolve libvirtd hang on termination with connected long running client
On 19.01.2018 20:23, John Ferlan wrote: > RFC: > https://www.redhat.com/archives/libvir-list/2018-January/msg00318.html > > Adjustments since RFC... > > Patches 1&2: No change, were already R-B'd > Patch 3: Removed code as noted in code review, update commit message > Patch 4: From old series removed, see below for more details > Patch 9: no change > NB: Patches 5-8 and 10 from Nikolay Shirokovskiy> are removed as they seemed to not be necessary > > Replaced the former patch 4 with series of patches to (slowly) provide > support to disable new connections, handle removing waiting jobs, causing > the waiting workers to quit, and allow any running jobs to complete. > > As it turns out, waiting for running jobs to complete cannot be done > from the virNetServerClose callbacks because that means the event loop > processing done during virNetServerRun will not allow any currently > long running worker job thread a means to complete. Hi, John. So you suggest a different appoarch. Instead of introducing means to help rpc threads to finish after event loop is finished (stateShutdown hook in my series) you suggest to block futher new rpc processing and then waiting running rpc calls to finish keeping event loop running for that purpose. This could lead to libvirtd never finish its termination if one of qemu processes do not respond for example. In case of long running operation such as migration finishing can take much time. On the over hand if we finish rpc threads abruptly as in case of stateShutdown hook we will deal with all possible error paths on daemon finishing. May be good approach is to abort long running operation, then give rpc threads some time to finish as you suggest and only after that finish them abruptly to handle hanging qemu etc. Also in this approach we keep event loop running for rpc threads only but there can be other threads that depend on the loop. For example if qemu is rebooted we spawn a thread that executes qemuProcessFakeReboot that sends commands to qemu (i.e. depends on event loop). We need to await such threads finishing too while keep event loop running. In approach of stateShutdown hook we finish all threads that uses qemu monitor by closing the monitor. And hack with timeout in a loop... I think of a different aproach for waiting rpc threads to finish their work. First let's make drain function only flush job queue and take some callback which will be called when all workers will be free from work (let's keep worker threads as Dan suggested). In this callback we can use same technique as in virNetDaemonSignalHandler. That is make some IO to set some flag in the event loop thread and cause virEventRunDefaultImpl to finish and then test this flag in virNetDaemonRun. Nikolay > > So when virNetDaemonQuit is called as a result of the libvirtd signal > handlers for SIG{QUIT|INT|TERM}, instead of just causing virNetServerRun > to quit immediately, alter to using a quitRequested flag and then use > that quitRequested flag to check for long running worker threads before > causing the event loop to quit resulting in libvirtd being able to run > through the virNetDaemonClose processing. > > John Ferlan (9): > libvirtd: Alter refcnt processing for domain server objects > libvirtd: Alter refcnt processing for server program objects > netserver: Remove ServiceToggle during ServerDispose > util: Introduce virThreadPoolDrain > rpc: Introduce virNetServerQuitRequested > rpc: Introduce virNetServerWorkerCount > rpc: Alter virNetDaemonQuit processing > docs: Add news article for libvirtd issue > APPLY ONLY FOR TESTING PURPOSES > > daemon/libvirtd.c| 43 +++- > docs/news.xml| 12 + > src/libvirt_private.syms | 1 + > src/libvirt_remote.syms | 2 ++ > src/qemu/qemu_driver.c | 5 > src/rpc/virnetdaemon.c | 45 +- > src/rpc/virnetserver.c | 52 --- > src/rpc/virnetserver.h | 4 +++ > src/util/virthreadpool.c | 64 > > src/util/virthreadpool.h | 2 ++ > 10 files changed, 204 insertions(+), 26 deletions(-) > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 7/9] qemu: Add dump completed event to the capabilities
On Fri, Jan 19, 2018 at 14:53:14 -0500, John Ferlan wrote: > Add the DUMP_COMPLETED check to the capabilities. This is the > mechanism used to determine whether the dump-guest-memory command > can support the "-detach" option and thus be able to wait on the > event and allow for a query of the progress of the dump. > > Signed-off-by: John Ferlan> --- > src/qemu/qemu_capabilities.c | 2 ++ > src/qemu/qemu_capabilities.h | 1 + > tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml | 1 + > tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml | 1 + > tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml | 1 + > tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1 + > tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml| 1 + > tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml | 1 + > tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml | 1 + > tests/qemucapabilitiesdata/caps_2.6.0.ppc64.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.ppc64.xml | 1 + > tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + > tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + > 18 files changed, 19 insertions(+) ACK Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH RESEND v1 1/2] i386: Add Intel Processor Trace feature support
On 22/01/2018 11:36, Kang, Luwei wrote: >>> On Thu, Jan 18, 2018 at 03:44:49PM +0100, Paolo Bonzini wrote: On 18/01/2018 15:37, Eduardo Habkost wrote: > On Thu, Jan 18, 2018 at 02:39:57PM +0100, Paolo Bonzini wrote: >> On 18/01/2018 14:24, Eduardo Habkost wrote: >>> However, if there's a simple way to make it possible to migrate >>> between hosts with different CPUID[14h] data, it would be even >>> better. With the current KVM intel-pt implementation, what >>> happens if the CPUID[14h] data seen by the guest doesn't match >>> exactly the CPUID[14h] leaves from the host? >> >> Some bits in there can be treated as CPU features (e.g. EBX bit 0 >> "CR3 filtering support"). Probably we should handle these in KVM right >> now. >> KVM needs to compute a mask of valid 1 bits for IA32_RTIT_CTL based >> on CPUID, and apply it when the MSR is written. > > Does this mean QEMU can't set CPUID values that won't match the host > with the existing implementation, or this won't matter for > well-behaved guests that don't try to set reserved bits on the MSRs? All the features could be handled exactly like regular feature bits. If QEMU sets them incorrectly and "enforce" is not used, bad things happen but it's the user's fault. >>> >>> Oh, I mean setting the bit to 0 when it's 1 on the host (if it's >>> 0 on the host, QEMU would never set it anyway). Is it safe to do it >>> with the current KVM intel-pt implementation? >> >> It's not, but it's (very) easy to fix. > > Hi Paolo, > Do you mean there need to add some check before setting IA32_RTIT_CTL > MSR in KVM because some bits of this MSR is depend on the result of > CPUID[14]. Any attempts to change these reserved bit should cause a #GP. Yes, but the guest's CPUID[14] need not match the host. Likewise, the number of address range MSRs in the guest, from CPUID[EAX=14h,ECX=1].EAX[2:0], might be lower than in the host. >> It also needs to >> whitelist bits like we do for other feature words. These include: >> >> - CPUID[EAX=14h,ECX=0].EBX >> >> - CPUID[EAX=14h,ECX=0].ECX except bit 31 >> >> - CPUID[EAX=14h,ECX=1].EAX bits 16:31 (if >> CPUID[EAX=14h,ECX=0].EBX[3]=1) >> >> - CPUID[EAX=14h,ECX=1].EBX (if CPUID[EAX=14h,ECX=0].EBX[1]=1) > > What do you mean by whitelist? KVM needs to tell QEMU the bits it knows about. > > I think kvm_arch_get_supported_cpuid() function can get the result of > CPUID[14] from KVM. Is this the whitelist what you mentioned? Whitelist means that KVM must not return all the bits from CPUID[14]; only those it knows about. Paolo > Thanks, > Luwei Kang > >>> >>> So KVM isn't currently doing it on GET_SUPPORTED_CPUID? Oops. >>> >>> >> Others, currently only CPUID[EAX=14h,ECX=0].ECX[31] must match, >> there is no way to emulate the "wrong" value. > > In this case we could make it configurable but require the host and > guest value to always match. > > This might be an obstacle to enabling intel-pt by default (because > it could make VMs not migratable to newer hosts), but may allow the > feature to be configured in a predictable way. Yeah, but consider that virtualized PT anyway would only be enabled on Ice Lake processors. It's a few years away anyway! >> Others, currently only CPUID[EAX=14h,ECX=1].EAX[2:0] are numeric >> values, and it's possible to emulate a lower value than the one in the >> processor. > > This could be handled by QEMU. There's no requirement that all > GET_SUPPORTED_CPUID values should be validated by simple bit > masking. Good! Paolo >>> > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 4/9] qemu: Add new parameter to qemuMonitorDumpToFd
On Fri, Jan 19, 2018 at 14:53:11 -0500, John Ferlan wrote: > Add a @detach parameter to the API in order allow running the QEMU > code as a thread. > > Signed-off-by: John Ferlan> --- > src/qemu/qemu_driver.c | 2 +- > src/qemu/qemu_monitor.c | 7 +-- > src/qemu/qemu_monitor.h | 3 ++- > src/qemu/qemu_monitor_json.c | 4 +++- > src/qemu/qemu_monitor_json.h | 3 ++- > tests/qemumonitorjsontest.c | 3 ++- > 6 files changed, 15 insertions(+), 7 deletions(-) ACK Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REBASE PATCH v2 3/9] qemu: Introduce qemuMonitor[JSON]QueryDump
On Fri, Jan 19, 2018 at 14:53:10 -0500, John Ferlan wrote: > Add the query-dump API's in order to allow the dump-guest-memory > to be used to monitor progress. > > Signed-off-by: John Ferlan> --- > src/qemu/qemu_monitor.c | 14 + > src/qemu/qemu_monitor.h | 11 +++ > src/qemu/qemu_monitor_json.c | 69 > > src/qemu/qemu_monitor_json.h | 4 +++ > 4 files changed, 98 insertions(+) > > diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c > index 031cd0a68..e9096d329 100644 > --- a/src/qemu/qemu_monitor.c > +++ b/src/qemu/qemu_monitor.c > @@ -2772,6 +2772,20 @@ qemuMonitorMigrateCancel(qemuMonitorPtr mon) > } > > > +int > +qemuMonitorQueryDump(qemuMonitorPtr mon, > + qemuMonitorDumpStatsPtr stats) > +{ > +QEMU_CHECK_MONITOR(mon); > + > +/* No capability is supported without JSON monitor */ > +if (!mon->json) > +return 0; Just use QEMU_CHECK_MONITOR_JSON(mon), which will report an error if JSON is not enabled. > + > +return qemuMonitorJSONQueryDump(mon, stats); > +} > + > + > /** > * Returns 1 if @capability is supported, 0 if it's not, or -1 on error. > */ > diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h > index f2ac71071..f7ce9ed40 100644 > --- a/src/qemu/qemu_monitor.h > +++ b/src/qemu/qemu_monitor.h > @@ -777,6 +777,17 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon); > int qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon, > const char *capability); > > +typedef struct _qemuMonitorDumpStats qemuMonitorDumpStats; > +typedef qemuMonitorDumpStats *qemuMonitorDumpStatsPtr; > +struct _qemuMonitorDumpStats { > +int status; /* qemuMonitorDumpStatus */ > +unsigned long long completed; /* bytes written */ > +unsigned long long total; /* total bytes to be written */ > +}; > + > +int qemuMonitorQueryDump(qemuMonitorPtr mon, > + qemuMonitorDumpStatsPtr stats); > + > int qemuMonitorDumpToFd(qemuMonitorPtr mon, > int fd, > const char *dumpformat); > diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c > index 169c01205..ddb1ec3c6 100644 > --- a/src/qemu/qemu_monitor_json.c > +++ b/src/qemu/qemu_monitor_json.c > @@ -3136,6 +3136,75 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon) > return ret; > } > > + > +/* qemuMonitorJSONQueryDump: > + * @mon: Monitor pointer > + * @stats: Dump "stats" > + * > + * Attempt to make a "query-dump" call, check for errors, and get/return > + * the current from the reply > + * > + * Returns: 0 on success, -1 on failure > + */ > +int > +qemuMonitorJSONQueryDump(qemuMonitorPtr mon, > + qemuMonitorDumpStatsPtr stats) > +{ > +int ret = -1; > +virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-dump", NULL); > +virJSONValuePtr reply = NULL; > +virJSONValuePtr result = NULL; > +const char *statusstr; > + > +if (!cmd) > +return -1; > + > +if (qemuMonitorJSONCommand(mon, cmd, ) < 0) > +goto cleanup; > + > +if (qemuMonitorJSONCheckError(cmd, reply) < 0) > +goto cleanup; > + > +if (!(result = virJSONValueObjectGetObject(reply, "return"))) > +goto cleanup; When qemuMonitorJSONCheckError doesn't report an error, the reply is guaranteed to have an object with "return" key. In other words, just do result = virJSONValueObjectGetObject(reply, "return"); > + > +if (!(statusstr = virJSONValueObjectGetString(result, "status"))) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("incomplete result, failed to get status")); > +goto cleanup; > +} > + > +stats->status = qemuMonitorDumpStatusTypeFromString(statusstr); > +if (stats->status < 0) { > +virReportError(VIR_ERR_INTERNAL_ERROR, > + _("incomplete result, unknown status string '%s'"), > + statusstr); > +goto cleanup; > +} > + > +if (virJSONValueObjectGetNumberUlong(result, "completed", > + >completed) < 0) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("incomplete result, failed to get completed")); > +goto cleanup; > +} > + > +if (virJSONValueObjectGetNumberUlong(result, "total", >total) < > 0) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("incomplete result, failed to get total")); > +goto cleanup; > +} This stats parsing code could be moved into a separate function since the DUMP_COMPLETED event contains the same structure. And we could benefit from using it to filling the priv->job.completed data after qemuDumpWaitForCompletion() returns without having to ask for the stats. Jirka -- libvir-list mailing list