[libvirt] Please help confirm this upsream issue
Hi I just try to verify the bug 828546 with the latest libvirt version on rhel7, and found an issue that the on_crash element on guest's xml didn't support the rename-restart events on the upsteam. I discussed this issue with eric before, he said that this feature was implemented by fujitsu first, he didn't backported this and he just backported what upstream does, also he was not sure if Fujitsu implemented the rename-restart events either, so can you help me confirm that should we support the rename-restart events on the upstream? thanks -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v6 2/2] qemu: support to drop disk with 'optional' startupPolicy
On 08/06/2013 09:40 PM, Martin Kletzander wrote: On 08/02/2013 08:37 AM, Guannan Ren wrote: Go through disks of guest, if one disk doesn't exist or its backing chain is broken, with 'optional' startupPolicy, for CDROM and Floppy we only discard its source path definition in xml, for disks we drop it from disk list and free it. --- include/libvirt/libvirt.h.in | 1 + src/qemu/qemu_domain.c | 69 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7bd3559..52ac95d 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4727,6 +4727,7 @@ typedef void (*virConnectDomainEventBlockJobCallback)(virConnectPtr conn, */ typedef enum { VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START = 0, /* oldSrcPath is set */ +VIR_DOMAIN_EVENT_DISK_DROP_MISSING_ON_START = 1, #ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_DISK_CHANGE_LAST diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 1ff802c..6794e26 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c [...] @@ -2080,11 +2111,12 @@ qemuDomainCheckDiskPresence(virQEMUDriverPtr driver, bool cold_boot) { int ret = -1; -size_t i; +ssize_t i; virDomainDiskDefPtr disk; +size_t ndisks = vm-def-ndisks; VIR_DEBUG(Checking for disk presence); -for (i = 0; i vm-def-ndisks; i++) { +for (i = ndisks - 1; i = 0; i--) { disk = vm-def-disks[i]; Now I noticed that there should be either (1) a check for domain without any disks (if ndisks == 0; return 0) or (2) a different for loop, like this for example: for (i = vm-def-ndisks; i 0; i--) { disk = vm-def-disks[i - 1]; I know that I proposed the faulty version, sorry for that. From those 2 versions I like the second one better because it looks cleaner and you can skip first lines of this hunk. It'd be nice to have a test for this to make sure we won't break it in future. At least xml2xml test if we can't test the disk dropping now. ACK with that fixed and this patch squashed in the previous one (also with those mentioned things fixed). Martin pushed with these mentioned fixed. Guannan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Please help confirm this upsream issue
On Wed, Aug 07, 2013 at 02:34:56AM -0400, Zhenfeng Wang wrote: Hi I just try to verify the bug 828546 with the latest libvirt version on rhel7, and found an issue that the on_crash element on guest's xml didn't support the rename-restart events on the upsteam. I discussed this issue with eric before, he said that this feature was implemented by fujitsu first, he didn't backported this and he just backported what upstream does, also he was not sure if Fujitsu implemented the rename-restart events either, so can you help me confirm that should we support the rename-restart events on the upstream? thanks The bug you quote is marked private so people on this list cannot view it. Your question is a matter for RHEL engineers to answer, not the libvirt community, so please take it off this list. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Please help confirm this upsream issue
Hi Daniel Thanks for your reply, please ignore this mail, I will retest this issue on the upstream, also will correct my question later. - Original Message - From: Daniel P. Berrange berra...@redhat.com To: Zhenfeng Wang zhw...@redhat.com Cc: libvir-list@redhat.com Sent: Wednesday, August 7, 2013 5:41:29 AM Subject: Re: [libvirt] Please help confirm this upsream issue On Wed, Aug 07, 2013 at 02:34:56AM -0400, Zhenfeng Wang wrote: Hi I just try to verify the bug 828546 with the latest libvirt version on rhel7, and found an issue that the on_crash element on guest's xml didn't support the rename-restart events on the upsteam. I discussed this issue with eric before, he said that this feature was implemented by fujitsu first, he didn't backported this and he just backported what upstream does, also he was not sure if Fujitsu implemented the rename-restart events either, so can you help me confirm that should we support the rename-restart events on the upstream? thanks The bug you quote is marked private so people on this list cannot view it. Your question is a matter for RHEL engineers to answer, not the libvirt community, so please take it off this list. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/4] Fix handling of CA certificate chains
On 06.08.2013 13:35, Daniel P. Berrange wrote: This series fixes the CA certificate validation so that it correctly works when a client and server cert are both signed by intermediate CAs, sharing a common ancestor CA. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list ACK series but see my comments to 2/4 and 4/4. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/4] Avoid re-generating certs every time
On 06.08.2013 13:35, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com Currently every test case in the TLS test suite generates the certs fresh. This is a waste of time, since its parameters don't change across test cases. Create certs once in main method. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- tests/virnettlscontexttest.c | 670 +++ tests/virnettlshelpers.c | 9 +- tests/virnettlshelpers.h | 4 +- tests/virnettlssessiontest.c | 152 +- 4 files changed, 445 insertions(+), 390 deletions(-) diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index 0a0d31a..a02e724 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -124,38 +118,54 @@ mymain(void) data.careq = _caReq;\ data.certreq = _certReq;\ data.expectFail = _expectFail; \ -if (virtTestRun(TLS Context, 1, testTLSContextInit, data) 0) \ +if (virtTestRun(TLS Context #_caReq + #_certReq, 1, \ +testTLSContextInit, data) 0) \ ret = -1; \ } while (0) +# define TLS_CERT_REQ(varname, cavarname, \ + co, cn, an1, an2, ia1, ia2, bce, bcc, bci,\ + kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, eo) \ +static struct testTLSCertReq varname = {\ +NULL, #varname .pem, \ +co, cn, an1, an2, ia1, ia2, bce, bcc, bci, \ +kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, eo \ +}; \ +testTLSGenerateCert(varname, cavarname.crt) + Trailing whitespace +# define TLS_ROOT_REQ(varname, \ + co, cn, an1, an2, ia1, ia2, bce, bcc, bci,\ + kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, eo) \ +static struct testTLSCertReq varname = {\ +NULL, #varname .pem, \ +co, cn, an1, an2, ia1, ia2, bce, bcc, bci, \ +kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, eo \ +}; \ +testTLSGenerateCert(varname, NULL) + + diff --git a/tests/virnettlssessiontest.c b/tests/virnettlssessiontest.c index 9c5b3ca..6c71ac9 100644 --- a/tests/virnettlssessiontest.c +++ b/tests/virnettlssessiontest.c @@ -292,68 +273,87 @@ mymain(void) data.expectClientFail = _expectClientFail; \ data.hostname = _hostname; \ data.wildcards = _wildcards;\ -if (virtTestRun(TLS Session, 1, testTLSSessionInit, data) 0) \ +if (virtTestRun(TLS Session #_serverReq + #_clientReq, \ +1, testTLSSessionInit, data) 0) \ ret = -1; \ } while (0) +# define TLS_CERT_REQ(varname, cavarname, \ + co, cn, an1, an2, ia1, ia2, bce, bcc, bci,\ + kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, eo) \ +static struct testTLSCertReq varname = {\ +NULL, #varname .pem, \ +co, cn, an1, an2, ia1, ia2, bce, bcc, bci, \ +kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, so \ +}; \ +testTLSGenerateCert(varname, cavarname.crt) + Trailing whitespace +# define TLS_ROOT_REQ(varname, \ + co, cn, an1, an2, ia1, ia2, bce, bcc, bci,\ + kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, eo) \ +static struct testTLSCertReq varname = {\ +NULL, #varname .pem, \ +co, cn, an1, an2, ia1, ia2, bce, bcc, bci, \ +kue, kuc, kuv, kpe, kpc, kpo1, kpo2, so, so \ +}; \ +testTLSGenerateCert(varname, NULL) + /* A perfect CA, perfect client perfect server */ /* Basic:CA:critical */ -static struct testTLSCertReq cacertreq = { -NULL, NULL, cacert.pem, UK, -
Re: [libvirt] [PATCH 4/4] Fix validation of CA certificate chains
On 06.08.2013 13:35, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com The code added to validate CA certificates did not take into account the possibility that the cacert.pem file can contain multiple (concatenated) cert data blocks. Extend the code for loading CA certs to use the gnutls APIs for loading cert lists. Add test cases to check that multi-level trees of certs will validate correctly. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/rpc/virnettlscontext.c | 73 ++-- tests/virnettlscontexttest.c | 59 +++ tests/virnettlshelpers.c | 34 + tests/virnettlshelpers.h | 3 ++ tests/virnettlssessiontest.c | 63 -- 5 files changed, 214 insertions(+), 18 deletions(-) diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c index af0ec21..55fb7d0 100644 --- a/src/rpc/virnettlscontext.c +++ b/src/rpc/virnettlscontext.c +#define MAX_CERTS 16 static int virNetTLSContextSanityCheckCredentials(bool isServer, const char *cacertFile, const char *certFile) { gnutls_x509_crt_t cert = NULL; -gnutls_x509_crt_t cacert = NULL; +gnutls_x509_crt_t cacerts[MAX_CERTS]; +size_t ncacerts = MAX_CERTS; +size_t i; int ret = -1; if ((access(certFile, R_OK) == 0) -!(cert = virNetTLSContextLoadCertFromFile(certFile, isServer, false))) +!(cert = virNetTLSContextLoadCertFromFile(certFile, isServer))) goto cleanup; if ((access(cacertFile, R_OK) == 0) -!(cacert = virNetTLSContextLoadCertFromFile(cacertFile, isServer, false))) +virNetTLSContextLoadCACertListFromFile(cacertFile, cacerts, ncacerts) 0) goto cleanup; if (cert virNetTLSContextCheckCert(cert, certFile, isServer, false) 0) goto cleanup; -if (cacert -virNetTLSContextCheckCert(cacert, cacertFile, isServer, true) 0) -goto cleanup; +for (i = 0 ; i ncacerts ; i++) { Spacing +if (virNetTLSContextCheckCert(cacerts[i], cacertFile, isServer, true) 0) +goto cleanup; +} -if (cert cacert -virNetTLSContextCheckCertPair(cert, certFile, cacert, cacertFile, isServer) 0) +VIR_DEBUG(Here); +if (cert ncacerts +virNetTLSContextCheckCertPair(cert, certFile, cacerts, ncacerts, cacertFile, isServer) 0) { +VIR_DEBUG(there); goto cleanup; +} ret = 0; cleanup: if (cert) gnutls_x509_crt_deinit(cert); -if (cacert) -gnutls_x509_crt_deinit(cacert); +for (i = 0 ; i ncacerts ; i++) Spacing +gnutls_x509_crt_deinit(cacerts[i]); return ret; } diff --git a/tests/virnettlshelpers.c b/tests/virnettlshelpers.c index 8236e82..baf043a 100644 --- a/tests/virnettlshelpers.c +++ b/tests/virnettlshelpers.c @@ -406,6 +406,40 @@ testTLSGenerateCert(struct testTLSCertReq *req, } +void testTLSWriteCertChain(const char *filename, + gnutls_x509_crt_t *certs, + size_t ncerts) +{ +size_t i; +int fd; +int err; +static char buffer[1024*1024]; +size_t size; + +if ((fd = open(filename, O_WRONLY|O_CREAT, 0600)) 0) { +VIR_WARN(Failed to open %s, filename); +abort(); +} + +for (i = 0 ; i ncerts ; i++) { Spacing +size = sizeof(buffer); +if ((err = gnutls_x509_crt_export(certs[i], GNUTLS_X509_FMT_PEM, buffer, size) 0)) { +VIR_WARN(Failed to export certificate %s, gnutls_strerror(err)); +unlink(filename); +abort(); +} + Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] build: fix configure detection of if_bridge.h on RHEL 6
On Tue, Aug 06, 2013 at 02:41:55PM -0600, Eric Blake wrote: A fresh checkout on a RHEL 6 machine with these packages: kernel-headers-2.6.32-405.el6.x86_64 glibc-2.12-1.128.el6.x86_64 failed to configure with this message: checking for linux/if_bridge.h... no configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support Digging in config.log, we see that the problem is identical to what we fixed earlier in commit d12c2811: configure:98831: checking for linux/if_bridge.h configure:98853: gcc -std=gnu99 -c -g -O2 conftest.c 5 In file included from /usr/include/linux/if_bridge.h:17, from conftest.c:559: /usr/include/linux/in6.h:31: error: redefinition of 'struct in6_addr' /usr/include/linux/in6.h:48: error: redefinition of 'struct sockaddr_in6' /usr/include/linux/in6.h:56: error: redefinition of 'struct ipv6_mreq' configure:98860: $? = 1 I had not hit it earlier because I was using incremental builds, where config.cache had shielded me from the kernel-headers breakage. * configure.ac (if_bridge.h): Avoid conflicting type definitions. Signed-off-by: Eric Blake ebl...@redhat.com --- Pushing under the build-breaker rule, and backporting to v1.1.1-maint This change breaks configure on any Fedora install I have, so I've had to revert it in master, since broken Fedora is more of a show stopper than broken RHEL6. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox][PATCH] Fix delete of running containers
The stop function is removed since 0.5.0, update delete function using virsh destroy to stop container. Signed-off-by: Wayne Sun g...@redhat.com --- bin/virt-sandbox-service |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service index 550d46c..926d1d5 100755 --- a/bin/virt-sandbox-service +++ b/bin/virt-sandbox-service @@ -254,9 +254,11 @@ class Container: def delete(self): self.connect() -# Stop service if it is running +# Stop container if it is running try: -self.stop() +p = Popen([/usr/bin/virsh, -c, self.uri, destroy, self.name], + stdout=PIPE, stderr=PIPE) +p.communicate() except: pass -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Add info about access control checks into API reference
From: Daniel P. Berrange berra...@redhat.com So that app developers / admins know what access control checks are performed for each API, this patch extends the API docs generator to include details of the ACLs for each. The gendispatch.pl script is extended so that it generates a simple XML describing ACL rules, eg. aclinfo ... api name='virConnectNumOfDomains' check object='connect' perm='search_domains'/ filter object='domain' perm='getattr'/ /api api name='virDomainAttachDeviceFlags' check object='domain' perm='write'/ check object='domain' perm='save' flags='!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE'/ check object='domain' perm='save' flags='VIR_DOMAIN_AFFECT_CONFIG'/ /api ... /aclinfo The newapi.xsl template loads the XML files containing the ACL rules and generates a short block of HTML for each API describing the parameter checks and return value filters (if any). Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/libvirt.css | 14 +++ docs/newapi.xsl| 68 ++ src/Makefile.am| 22 ++-- src/rpc/gendispatch.pl | 59 --- 4 files changed, 157 insertions(+), 6 deletions(-) diff --git a/docs/libvirt.css b/docs/libvirt.css index 8a00d12..ed67b2f 100644 --- a/docs/libvirt.css +++ b/docs/libvirt.css @@ -477,3 +477,17 @@ dl.variablelist dt { dl.variablelist dt:after { content: : ; } + +table.acl { +margin: 1em; +border-spacing: 0px; +border: 1px solid #ccc; +} + +table.acl tr, table.acl td { +padding: 0.3em; +} + +table.acl thead { +background: #ddd; +} diff --git a/docs/newapi.xsl b/docs/newapi.xsl index d5b210e..58f12eb 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -29,6 +29,69 @@ xsl:variable name=htmldirhtml/xsl:variable xsl:variable name=href_base..//xsl:variable + xsl:variable name=acls +xsl:copy-of select=document('../src/libvirt_access.xml')/aclinfo/api/ + /xsl:variable + xsl:variable name=qemuacls +xsl:copy-of select=document('../src/libvirt_access_qemu.xml')/aclinfo/api/ + /xsl:variable + xsl:variable name=lxcacls +xsl:copy-of select=document('../src/libvirt_access_lxc.xml')/aclinfo/api/ + /xsl:variable + + xsl:template name=aclinfo +xsl:param name=api/ + +xsl:if test=count(exsl:node-set($acls)/api[@name=$api]/check) 0 + h5Access control parameter checks/h5 + table class=acl +thead + tr +thObject/th +thPermission/th +thCondition/th + /tr +/thead +xsl:apply-templates select=exsl:node-set($acls)/api[@name=$api]/check mode=acl/ + /table +/xsl:if +xsl:if test=count(exsl:node-set($acls)/api[@name=$api]/filter) 0 + h5Access control return value filters/h5 + table class=acl +thead + tr +thObject/th +thPermission/th + /tr +/thead +xsl:apply-templates select=exsl:node-set($acls)/api[@name=$api]/filter mode=acl/ + /table +/xsl:if + /xsl:template + + xsl:template match=check mode=acl +tr + tdxsl:value-of select=@object//td + tdxsl:value-of select=@perm//td + xsl:choose +xsl:when test=@flags + tdxsl:value-of select=@flags//td +/xsl:when +xsl:otherwise + td-/td +/xsl:otherwise + /xsl:choose +/tr + /xsl:template + + xsl:template match=filter mode=acl +tr + tdxsl:value-of select=@object//td + tdxsl:value-of select=@perm//td +/tr + /xsl:template + + xsl:template name=navbar xsl:variable name=previous select=preceding-sibling::file[1]/ xsl:variable name=next select=following-sibling::file[1]/ @@ -553,6 +616,11 @@ /xsl:if /dl /xsl:if +div class=acl + xsl:call-template name=aclinfo +xsl:with-param name=api select=$name/ + /xsl:call-template +/div /xsl:template xsl:template match=exports mode=toc diff --git a/src/Makefile.am b/src/Makefile.am index ac66ecf..277f749 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -830,6 +830,11 @@ ACCESS_DRIVER_SYM_FILES = \ libvirt_access_qemu.syms \ libvirt_access_lxc.syms +ACCESS_DRIVER_API_FILES = \ + libvirt_access.xml \ + libvirt_access_qemu.xml \ + libvirt_access_lxc.xml + ACCESS_DRIVER_SOURCES = \ access/viraccessperm.h access/viraccessperm.c \ access/viraccessmanager.h access/viraccessmanager.c \ @@ -1496,8 +1501,8 @@ EXTRA_DIST += $(ACCESS_DRIVER_POLKIT_SOURCES) endif -BUILT_SOURCES += $(ACCESS_DRIVER_GENERATED) -CLEANFILES += $(ACCESS_DRIVER_GENERATED) +BUILT_SOURCES += $(ACCESS_DRIVER_GENERATED) $(ACCESS_DRIVER_API_FILES) +CLEANFILES += $(ACCESS_DRIVER_GENERATED) $(ACCESS_DRIVER_API_FILES) libvirt_access.syms:
Re: [libvirt] [sandbox][PATCH] Fix delete of running containers
On Wed, Aug 07, 2013 at 07:56:05PM +0800, Wayne Sun wrote: The stop function is removed since 0.5.0, update delete function using virsh destroy to stop container. Signed-off-by: Wayne Sun g...@redhat.com --- bin/virt-sandbox-service |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service index 550d46c..926d1d5 100755 --- a/bin/virt-sandbox-service +++ b/bin/virt-sandbox-service @@ -254,9 +254,11 @@ class Container: def delete(self): self.connect() -# Stop service if it is running +# Stop container if it is running try: -self.stop() +p = Popen([/usr/bin/virsh, -c, self.uri, destroy, self.name], + stdout=PIPE, stderr=PIPE) +p.communicate() except: pass Hmm, I'm not convinced that we should allow deletion of sanboxes that are running at all. IMHO it is better if we just report an error to the admin if they attempt to delete a running sandbox, since I think that would commonly be a mistake they should be protected from. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [sandbox][PATCH] Fix delete of running containers
On 08/07/2013 08:08 PM, Daniel P. Berrange wrote: On Wed, Aug 07, 2013 at 07:56:05PM +0800, Wayne Sun wrote: The stop function is removed since 0.5.0, update delete function using virsh destroy to stop container. Signed-off-by: Wayne Sun g...@redhat.com --- bin/virt-sandbox-service |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service index 550d46c..926d1d5 100755 --- a/bin/virt-sandbox-service +++ b/bin/virt-sandbox-service @@ -254,9 +254,11 @@ class Container: def delete(self): self.connect() -# Stop service if it is running +# Stop container if it is running try: -self.stop() +p = Popen([/usr/bin/virsh, -c, self.uri, destroy, self.name], + stdout=PIPE, stderr=PIPE) +p.communicate() except: pass Hmm, I'm not convinced that we should allow deletion of sanboxes that are running at all. IMHO it is better if we just report an error to the admin if they attempt to delete a running sandbox, since I think that would commonly be a mistake they should be protected from. Daniel Yes, the right logic is not allow it, i'll work on v2 for this. Thanks! Wayne Sun -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Please help confirm this upsream issue
On 08/07/2013 03:41 AM, Daniel P. Berrange wrote: On Wed, Aug 07, 2013 at 02:34:56AM -0400, Zhenfeng Wang wrote: Hi I just try to verify the bug 828546 with the latest libvirt version on rhel7, and found an issue that the on_crash element on guest's xml didn't support the rename-restart events on the upsteam. I discussed this issue with eric before, he said that this feature was implemented by fujitsu first, he didn't backported this and he just backported what upstream does, also he was not sure if Fujitsu implemented the rename-restart events either, so can you help me confirm that should we support the rename-restart events on the upstream? thanks The bug you quote is marked private so people on this list cannot view it. Your question is a matter for RHEL engineers to answer, not the libvirt community, so please take it off this list. Although the question was poorly worded by referring to downstream elements, I still think the concept behind the question is appropriate for upstream. That is: What good is the rename-restart on_* XML element? Is it wired up for anything other than xen? A grep of the code base shows only: src/conf/domain_conf.h:VIR_DOMAIN_LIFECYCLE_RESTART_RENAME, src/conf/domain_conf.h:VIR_DOMAIN_LIFECYCLE_CRASH_RESTART_RENAME, src/nwfilter/nwfilter_ebiptables_driver.c:#define NWFILTER_FUNC_RENAME_CHAINS ebiptables_script_func_rename_chains src/nwfilter/nwfilter_ebiptables_driver.c:virBufferAsprintf(buf, NWFILTER_FUNC_RENAME_CHAINS, src/qemu/qemu_driver.c:vm-def-onPoweroff == VIR_DOMAIN_LIFECYCLE_RESTART_RENAME) { src/test/test_driver.c:case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME: src/xenapi/xenapi_utils.c:else if (action == VIR_DOMAIN_LIFECYCLE_CRASH_RESTART_RENAME) src/xenapi/xenapi_utils.c:num = XEN_ON_CRASH_BEHAVIOUR_RENAME_RESTART; src/xenapi/xenapi_utils.c:else if (action == XEN_ON_CRASH_BEHAVIOUR_RENAME_RESTART) src/xenapi/xenapi_utils.c:num = VIR_DOMAIN_LIFECYCLE_CRASH_RESTART_RENAME; which looks like only xen has wired up the ability to automatically rename a domain when restarting it. If so, we ought to update formatdomain.html to better clarify that not all actions are supported for all hypervisors. (Hmm, that page already admits that on_poweroffrename-restart/on_poweroff is treated like plain 'restart' for qemu/kvm; so really the question is whether we copied that behavior for the new support for on_crash). -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] build: fix configure detection of if_bridge.h on RHEL 6
On 08/07/2013 05:01 AM, Daniel P. Berrange wrote: On Tue, Aug 06, 2013 at 02:41:55PM -0600, Eric Blake wrote: A fresh checkout on a RHEL 6 machine with these packages: kernel-headers-2.6.32-405.el6.x86_64 glibc-2.12-1.128.el6.x86_64 failed to configure with this message: checking for linux/if_bridge.h... no configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support I had not hit it earlier because I was using incremental builds, where config.cache had shielded me from the kernel-headers breakage. * configure.ac (if_bridge.h): Avoid conflicting type definitions. Signed-off-by: Eric Blake ebl...@redhat.com --- Pushing under the build-breaker rule, and backporting to v1.1.1-maint This change breaks configure on any Fedora install I have, so I've had to revert it in master, since broken Fedora is more of a show stopper than broken RHEL6. Arrgh - this time, the incremental build on Fedora bit me. I hate that the use of linux/if_bridge.h is broken depending on platform, with opposite conditions on whether you include or avoid netinet/in.h; the kernel folks really botched this one. :( I'll come up with a v2. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox][PATCH v2] Fix delete of running container
Delete running container is not supprted and will report an error. Related to bug: https://bugzilla.redhat.com/show_bug.cgi?id=994495 Signed-off-by: Wayne Sun g...@redhat.com --- bin/virt-sandbox-service | 15 ++- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service index 550d46c..c07c33b 100755 --- a/bin/virt-sandbox-service +++ b/bin/virt-sandbox-service @@ -254,11 +254,16 @@ class Container: def delete(self): self.connect() -# Stop service if it is running -try: -self.stop() -except: -pass +# Check container is running or not +cmd = /usr/bin/virsh -c %s list | sed '1d;2d;$d' | awk -F' '\ + '{ print $2}' % self.uri +p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE) +out, err = p.communicate() +if p.returncode and p.returncode != 0: +raise OSError(_(Failed to list running domain)) + +if self.name in out.splitlines(): +raise ValueError([_(Delete running container is not supported)]) # Not sure we should remove content if os.path.exists(self.dest): -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv3] build: avoid -lgcrypt with newer gnutls
On Tue, Jul 30, 2013 at 3:45 PM, Eric Blake ebl...@redhat.com wrote: https://bugzilla.redhat.com/show_bug.cgi?id=951637 Newer gnutls uses nettle, rather than gcrypt, which is a lot nicer regarding initialization. Yet we were unconditionally initializing gcrypt even when gnutls wouldn't be using it, and having two crypto libraries linked into libvirt.so is pointless, but mostly harmless (it doesn't crash, but does interfere with certification efforts). There are three distinct version ranges to worry about when determining which crypto lib gnutls uses, per these gnutls mails: 2.12: http://lists.gnu.org/archive/html/gnutls-devel/2011-03/msg00034.html 3.0: http://lists.gnu.org/archive/html/gnutls-devel/2011-07/msg00035.html If pkg-config can prove version numbers and/or list the crypto library used for static linking, we have our proof; if not, it is safer (even if pointless) to continue to use gcrypt ourselves. * configure.ac (WITH_GNUTLS): Probe whether to add -lgcrypt, and define a witness WITH_GNUTLS_GCRYPT. * src/libvirt.c (virTLSMutexInit, virTLSMutexDestroy) (virTLSMutexLock, virTLSMutexUnlock, virTLSThreadImpl) (virGlobalInit): Honor the witness. * libvirt.spec.in (BuildRequires): Make gcrypt usage conditional, no longer needed in Fedora 19. Signed-off-by: Eric Blake ebl...@redhat.com --- v3: configure logic is enhanced to try harder to get the right answer for gentoo. I tested with Fedora 19 and RHEL 6, but need feedback from a gentoo tester before this can go in. configure.ac| 37 ++--- libvirt.spec.in |2 ++ src/libvirt.c | 10 ++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 1817126..e3d148c 100644 --- a/configure.ac +++ b/configure.ac @@ -1076,12 +1076,26 @@ if test x$with_gnutls != xno; then LIBS=$LIBS $GNUTLS_LIBS GNUTLS_FOUND=no + GNUTLS_GCRYPT=unknown if test -x $PKG_CONFIG ; then +dnl Triple probe: gnutls 2.12 only used gcrypt, gnutls = 3.0 uses +dnl only nettle, and versions in between had a configure option. +dnl Our goal is to avoid gcrypt if we can prove gnutls uses nettle, +dnl but it is a safe fallback to use gcrypt if we can't prove anything. +if $PKG_CONFIG --exists 'gnutls = 3.0'; then + GNUTLS_GCRYPT=no +elif $PKG_CONFIG --exists 'gnutls = 2.12'; then + GNUTLS_GCRYPT=probe +else + GNUTLS_GCRYPT=yes +fi PKG_CHECK_MODULES(GNUTLS, gnutls = $GNUTLS_REQUIRED, [GNUTLS_FOUND=yes], [GNUTLS_FOUND=no]) fi if test $GNUTLS_FOUND = no; then +dnl pkg-config couldn't help us, assume gcrypt is necessary fail=0 +GNUTLS_GCRYPT=yes AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1]) AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt]) @@ -1098,13 +1112,22 @@ if test x$with_gnutls != xno; then AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt]) fi else -dnl Not all versions of gnutls include -lgcrypt, and so we add -dnl it explicitly for the calls to gcry_control/check_version -GNUTLS_LIBS=$GNUTLS_LIBS -lgcrypt - -dnl We're not using gcrypt deprecated features so define -dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings -GNUTLS_CFLAGS=$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED +dnl See comments above about when to use gcrypt. +if test $GNUTLS_GCRYPT = probe; then + case `$PKG_CONFIG --libs --static gnutls` in +*gcrypt*) GNUTLS_GCRYPT=yes ;; +*nettle*) GNUTLS_GCRYPT=no ;; +*)GNUTLS_GCRYPT=unknown ;; + esac +fi +if test $GNUTLS_GCRYPT = yes || test $GNUTLS_GCRYPT = unknown; then + GNUTLS_LIBS=$GNUTLS_LIBS -lgcrypt + dnl We're not using gcrypt deprecated features so define + dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings + GNUTLS_CFLAGS=$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED + AC_DEFINE_UNQUOTED([WITH_GNUTLS_GCRYPT], 1, +[set to 1 if it is known or assumed that GNUTLS uses gcrypt]) +fi dnl gnutls 3.x moved some declarations to a new header AC_CHECK_HEADERS([gnutls/crypto.h], [], [], [[ diff --git a/libvirt.spec.in b/libvirt.spec.in index fce7f91..7fd3c85 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -438,7 +438,9 @@ BuildRequires: readline-devel BuildRequires: ncurses-devel BuildRequires: gettext BuildRequires: libtasn1-devel +%if (0%{?rhel} 0%{?rhel} 7) || (0%{?fedora} 0%{?fedora} 19) BuildRequires: libgcrypt-devel +%endif BuildRequires: gnutls-devel BuildRequires: libattr-devel %if %{with_libvirtd} diff --git a/src/libvirt.c b/src/libvirt.c index 8157488..66e8248 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -55,7 +55,9 @@ #include intprops.h #include virconf.h #if WITH_GNUTLS -# include gcrypt.h +# if WITH_GNUTLS_GCRYPT +# include gcrypt.h +#
Re: [libvirt] [PATCH 4/4] Fix validation of CA certificate chains
On Tue, Aug 6, 2013 at 6:35 AM, Daniel P. Berrange berra...@redhat.com wrote: From: Daniel P. Berrange berra...@redhat.com The code added to validate CA certificates did not take into account the possibility that the cacert.pem file can contain multiple (concatenated) cert data blocks. Extend the code for loading CA certs to use the gnutls APIs for loading cert lists. Add test cases to check that multi-level trees of certs will validate correctly. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/rpc/virnettlscontext.c | 73 ++-- tests/virnettlscontexttest.c | 59 +++ tests/virnettlshelpers.c | 34 + tests/virnettlshelpers.h | 3 ++ tests/virnettlssessiontest.c | 63 -- 5 files changed, 214 insertions(+), 18 deletions(-) diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c index af0ec21..55fb7d0 100644 --- a/src/rpc/virnettlscontext.c +++ b/src/rpc/virnettlscontext.c @@ -455,14 +455,15 @@ static int virNetTLSContextCheckCert(gnutls_x509_crt_t cert, static int virNetTLSContextCheckCertPair(gnutls_x509_crt_t cert, const char *certFile, - gnutls_x509_crt_t cacert, + gnutls_x509_crt_t *cacerts, + size_t ncacerts, const char *cacertFile, bool isServer) { unsigned int status; if (gnutls_x509_crt_list_verify(cert, 1, -cacert, 1, +cacerts, ncacerts, NULL, 0, 0, status) 0) { virReportError(VIR_ERR_SYSTEM_ERROR, isServer ? @@ -500,16 +501,15 @@ static int virNetTLSContextCheckCertPair(gnutls_x509_crt_t cert, static gnutls_x509_crt_t virNetTLSContextLoadCertFromFile(const char *certFile, - bool isServer, - bool isCA ATTRIBUTE_UNUSED) + bool isServer) { gnutls_datum_t data; gnutls_x509_crt_t cert = NULL; char *buf = NULL; int ret = -1; -VIR_DEBUG(isServer %d isCA %d certFile %s, - isServer, isCA, certFile); +VIR_DEBUG(isServer %d certFile %s, + isServer, certFile); if (gnutls_x509_crt_init(cert) 0) { virReportError(VIR_ERR_SYSTEM_ERROR, %s, @@ -543,40 +543,81 @@ cleanup: } +static int virNetTLSContextLoadCACertListFromFile(const char *certFile, + gnutls_x509_crt_t *certs, + size_t *ncerts) +{ +gnutls_datum_t data; +char *buf = NULL; +int ret = -1; +unsigned int certMax = *ncerts; + +*ncerts = 0; +VIR_DEBUG(certFile %s, certFile); + +if (virFileReadAll(certFile, (116), buf) 0) +goto cleanup; + +data.data = (unsigned char *)buf; +data.size = strlen(buf); + +if (gnutls_x509_crt_list_import(certs, certMax, data, GNUTLS_X509_FMT_PEM, 0) 0) { +virReportError(VIR_ERR_SYSTEM_ERROR, + _(Unable to import CA certificate list %s), + certFile); +goto cleanup; +} +*ncerts = certMax; + +ret = 0; + +cleanup: +VIR_FREE(buf); +return ret; +} + + +#define MAX_CERTS 16 static int virNetTLSContextSanityCheckCredentials(bool isServer, const char *cacertFile, const char *certFile) { gnutls_x509_crt_t cert = NULL; -gnutls_x509_crt_t cacert = NULL; +gnutls_x509_crt_t cacerts[MAX_CERTS]; +size_t ncacerts = MAX_CERTS; +size_t i; int ret = -1; if ((access(certFile, R_OK) == 0) -!(cert = virNetTLSContextLoadCertFromFile(certFile, isServer, false))) +!(cert = virNetTLSContextLoadCertFromFile(certFile, isServer))) goto cleanup; if ((access(cacertFile, R_OK) == 0) -!(cacert = virNetTLSContextLoadCertFromFile(cacertFile, isServer, false))) +virNetTLSContextLoadCACertListFromFile(cacertFile, cacerts, ncacerts) 0) goto cleanup; if (cert virNetTLSContextCheckCert(cert, certFile, isServer, false) 0) goto cleanup; -if (cacert -virNetTLSContextCheckCert(cacert, cacertFile, isServer, true) 0) -goto cleanup; +for (i = 0 ; i ncacerts ; i++) { +if (virNetTLSContextCheckCert(cacerts[i], cacertFile, isServer, true) 0) +
Re: [libvirt] [sandbox][PATCH v2] Fix delete of running container
On Wed, Aug 07, 2013 at 09:24:14PM +0800, Wayne Sun wrote: Delete running container is not supprted and will report an error. Related to bug: https://bugzilla.redhat.com/show_bug.cgi?id=994495 Signed-off-by: Wayne Sun g...@redhat.com --- bin/virt-sandbox-service | 15 ++- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service index 550d46c..c07c33b 100755 --- a/bin/virt-sandbox-service +++ b/bin/virt-sandbox-service @@ -254,11 +254,16 @@ class Container: def delete(self): self.connect() -# Stop service if it is running -try: -self.stop() -except: -pass +# Check container is running or not +cmd = /usr/bin/virsh -c %s list | sed '1d;2d;$d' | awk -F' '\ + '{ print $2}' % self.uri +p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE) +out, err = p.communicate() +if p.returncode and p.returncode != 0: +raise OSError(_(Failed to list running domain)) + +if self.name in out.splitlines(): +raise ValueError([_(Delete running container is not supported)]) virt-sandbox-service already has a connection to libvirt - no need to spawn virsh here. Just do something like this (untested): self.conn.fetch_domains() dom = self.conn.find_domain_by_name(self.name) info = dom.get_info() if info.state == LibvirtGObject.DomainState.RUNNING: .error... Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv3] build: avoid -lgcrypt with newer gnutls
On 08/07/2013 07:29 AM, Doug Goldstein wrote: On Tue, Jul 30, 2013 at 3:45 PM, Eric Blake ebl...@redhat.com wrote: https://bugzilla.redhat.com/show_bug.cgi?id=951637 Newer gnutls uses nettle, rather than gcrypt, which is a lot nicer regarding initialization. Yet we were unconditionally initializing gcrypt even when gnutls wouldn't be using it, and having two crypto libraries linked into libvirt.so is pointless, but mostly harmless (it doesn't crash, but does interfere with certification efforts). v3: configure logic is enhanced to try harder to get the right answer for gentoo. I tested with Fedora 19 and RHEL 6, but need feedback from a gentoo tester before this can go in. I can ACK this by visual code inspection. I haven't explicitly tested this patch but its a cleaned up version of the patch we previously discussed it. If you need me to test it, I can do that tonight. I'd feel better with an explicit test; we're in no rush, so I'll wait for your test results on gentoo. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/3] Reverse logic allowing partial DHCP host XML
On 08/02/2013 12:10 PM, Laine Stump wrote: On 07/31/2013 07:41 AM, Ján Tomko wrote: Before, missing attributes were only OK when adding entries; modification and deletion required all of them. Now, only deletion works with missing attributes, as long as the host is uniquely identified. --- src/conf/network_conf.c | 21 + 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index a0b543c..16bdb45 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -3297,6 +3297,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def, int ret = -1; virNetworkIpDefPtr ipdef = virNetworkIpDefByIndex(def, parentIndex); virNetworkDHCPHostDef host; +bool isDelete = (command == VIR_NETWORK_UPDATE_COMMAND_DELETE); ACK, but change the name of this bool to partialOkay to match its meaning and be consistent with what it's being named in virNetworkDHCPHostDefParseXML. Renamed and pushed. Thanks! Jan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/3] Reverse logic allowing partial DHCP host XML
On 08/01/2013 10:42 AM, Ján Tomko wrote: Before, missing attributes were only OK when adding entries; modification and deletion required all of them. Now, only deletion works with missing attributes, as long as the host is uniquely identified. --- src/conf/network_conf.c | 21 + 1 file changed, 5 insertions(+), 16 deletions(-) This one has been ACKed and pushed already: https://www.redhat.com/archives/libvir-list/2013-August/msg00299.html Jan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virthread: include config.h in the header file
The virthread.h header file includes platform specific header files that help define the thread implementation, see code snippet below. # ifdef WIN32 # include virthreadwin32.h # elif defined HAVE_PTHREAD_MUTEXATTR_INIT # include virthreadpthread.h # else # error Either pthreads or Win32 threads are required # endif Unfortunately, virthread.h does not include config.h so every source file which includes virthread.h must also include config.h, regardless of if the source file directly needs definitions in config.h. This patch adds config.h to virthread.h in an effort to help simplify things. Signed-off-by: Paul Moore pmo...@redhat.com --- src/util/virthread.h |2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/virthread.h b/src/util/virthread.h index 84d3bdc..091cdd0 100644 --- a/src/util/virthread.h +++ b/src/util/virthread.h @@ -22,6 +22,8 @@ #ifndef __THREADS_H_ # define __THREADS_H_ +#include config.h + # include internal.h # include virerror.h -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virthread: include config.h in the header file
On Wed, Aug 07, 2013 at 11:11:20AM -0400, Paul Moore wrote: The virthread.h header file includes platform specific header files that help define the thread implementation, see code snippet below. # ifdef WIN32 # include virthreadwin32.h # elif defined HAVE_PTHREAD_MUTEXATTR_INIT # include virthreadpthread.h # else # error Either pthreads or Win32 threads are required # endif Unfortunately, virthread.h does not include config.h so every source file which includes virthread.h must also include config.h, regardless of if the source file directly needs definitions in config.h. This patch adds config.h to virthread.h in an effort to help simplify things. Every single .c files is mandated to include config.h as its first header file, so .h files never need include it themselves. We enforce this rule via 'make syntax-check'. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virthread: include config.h in the header file
On Wednesday, August 07, 2013 04:25:04 PM Daniel P. Berrange wrote: On Wed, Aug 07, 2013 at 11:11:20AM -0400, Paul Moore wrote: The virthread.h header file includes platform specific header files that help define the thread implementation, see code snippet below. # ifdef WIN32 # include virthreadwin32.h # elif defined HAVE_PTHREAD_MUTEXATTR_INIT # include virthreadpthread.h # else # error Either pthreads or Win32 threads are required # endif Unfortunately, virthread.h does not include config.h so every source file which includes virthread.h must also include config.h, regardless of if the source file directly needs definitions in config.h. This patch adds config.h to virthread.h in an effort to help simplify things. Every single .c files is mandated to include config.h as its first header file, so .h files never need include it themselves. We enforce this rule via 'make syntax-check'. Okay, sorry for the noise. -- paul moore security and virtualization @ redhat -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] maint: the compiler is not always named gcc
https://bugzilla.redhat.com/show_bug.cgi?id=994589 complained that even when using a cross-compiler not named 'gcc', the configure output confusingly referred to gcc. * m4/virt-compile-warnings.m4 (LIBVIRT_COMPILE_WARNINGS): Use a more generic statement in configure output. Signed-off-by: Eric Blake ebl...@redhat.com --- Pushing under the trivial rule. m4/virt-compile-warnings.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/m4/virt-compile-warnings.m4 b/m4/virt-compile-warnings.m4 index 8731b70..6bf797f 100644 --- a/m4/virt-compile-warnings.m4 +++ b/m4/virt-compile-warnings.m4 @@ -62,7 +62,7 @@ AC_DEFUN([LIBVIRT_COMPILE_WARNINGS],[ # gcc 4.2 treats attribute(format) as an implicit attribute(nonnull), # which triggers spurious warnings for our usage -AC_CACHE_CHECK([whether gcc -Wformat allows NULL strings], +AC_CACHE_CHECK([whether the C compiler's -Wformat allows NULL strings], [lv_cv_gcc_wformat_null_works], [ save_CFLAGS=$CFLAGS CFLAGS='-Wunknown-pragmas -Werror -Wformat' @@ -101,7 +101,7 @@ AC_DEFUN([LIBVIRT_COMPILE_WARNINGS],[ dnl Check whether strchr(s, char variable) causes a bogus compile dnl warning, which is the case with GCC 4.6 on some glibc -AC_CACHE_CHECK([whether GCC -Wlogical-op gives bogus warnings], +AC_CACHE_CHECK([whether the C compiler's -Wlogical-op gives bogus warnings], [lv_cv_gcc_wlogical_op_broken], [ save_CFLAGS=$CFLAGS CFLAGS=-O2 -Wlogical-op -Werror -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] build: fix configure detection of if_bridge.h on RHEL 6
On 08/06/2013 02:41 PM, Eric Blake wrote: A fresh checkout on a RHEL 6 machine with these packages: kernel-headers-2.6.32-405.el6.x86_64 glibc-2.12-1.128.el6.x86_64 failed to configure with this message: checking for linux/if_bridge.h... no configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support +++ b/configure.ac @@ -999,7 +999,14 @@ if test $with_linux = yes; then if test $with_qemu = yes || test $with_lxc = yes ; then AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h linux/if_tun.h],, [AC_MSG_ERROR([You must install kernel-headers in order to compile libvirt with QEMU or LXC support])], - [[#include netinet/in.h + [[/* The kernel folks broke their headers when used with particular + * glibc versions; although the structs are ABI compatible, the + * C type system doesn't like struct redefinitions. We work around + * the problem here in the same manner as in virnetdevbridge.c. */ Except that v1 didn't EXACTLY match virnetdevbridge.c. +#include netinet/in.h +#define in6_addr in6_addr_ +#define sockaddr_in6 sockaddr_in6_ +#define ipv6_mreq ipv6_mreq_ ]]) This is the missing piece: diff --git i/configure.ac w/configure.ac index 4f2a7e9..4d6698d 100644 --- i/configure.ac +++ w/configure.ac @@ -1005,6 +1005,7 @@ if test $with_linux = yes; then #define in6_addr in6_addr_ #define sockaddr_in6 sockaddr_in6_ #define ipv6_mreq ipv6_mreq_ + #include linux/in6.h ]]) fi fi I've now tested fresh checkouts on RHEL5, RHEL6, Fedora 19, and FreeBSD; since all of them are able to pass configure, I'm going to repost the patch as a v2; but since the build failed last time around when invoking the build-breaker rule, this time around I'll wait for a review. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv2] build: fix configure detection of if_bridge.h on RHEL 6, try 2
This is a second attempt at fixing the problem first attempted in commit 2df8d99; basically undoing the fact that it was reverted in commit 43cee32f, plus fixing one more issue: the code in configure.ac has to EXACTLY match virnetdevbridge.c with regards to declaring in6 types before using if_bridge.h. The rest of this commit message borrows from the original: A fresh checkout on a RHEL 6 machine with these packages: kernel-headers-2.6.32-405.el6.x86_64 glibc-2.12-1.128.el6.x86_64 failed to configure with this message: checking for linux/if_bridge.h... no configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support Digging in config.log, we see that the problem is identical to what we fixed earlier in commit d12c2811: configure:98831: checking for linux/if_bridge.h configure:98853: gcc -std=gnu99 -c -g -O2 conftest.c 5 In file included from /usr/include/linux/if_bridge.h:17, from conftest.c:559: /usr/include/linux/in6.h:31: error: redefinition of 'struct in6_addr' /usr/include/linux/in6.h:48: error: redefinition of 'struct sockaddr_in6' /usr/include/linux/in6.h:56: error: redefinition of 'struct ipv6_mreq' configure:98860: $? = 1 I had not hit it earlier because I was using incremental builds, where config.cache had shielded me from the kernel-headers breakage. * configure.ac (if_bridge.h): Avoid conflicting type definitions. Signed-off-by: Eric Blake ebl...@redhat.com --- Although this fixes a build-breaker, this time I'm awaiting review since my first attempt caused grief on Fedora. configure.ac | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a155790..e5dd67b 100644 --- a/configure.ac +++ b/configure.ac @@ -997,7 +997,15 @@ if test $with_linux = yes; then if test $with_qemu = yes || test $with_lxc = yes ; then AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h linux/if_tun.h],, [AC_MSG_ERROR([You must install kernel-headers in order to compile libvirt with QEMU or LXC support])], - [[#include netinet/in.h + [[/* The kernel folks broke their headers when used with particular + * glibc versions; although the structs are ABI compatible, the + * C type system doesn't like struct redefinitions. We work around + * the problem here in the same manner as in virnetdevbridge.c. */ +#include netinet/in.h +#define in6_addr in6_addr_ +#define sockaddr_in6 sockaddr_in6_ +#define ipv6_mreq ipv6_mreq_ +#include linux/in6.h ]]) fi fi -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] cgroup: refactor macros usage
On 08/03/2013 12:01 PM, Roman Bogorodskiy wrote: util/vircgroup.c uses a lot of macros to detect if cgroup is supported by the system or not. These macros are pretty smart and allow to keep code compact, however the downside of that is that it's getting harder to navigate through the cgroup code. So re-organise macros in a more simple fashion, i.e. just explicitly provide functional and stub implementation for every public function. --- src/util/vircgroup.c | 984 +-- 1 file changed, 648 insertions(+), 336 deletions(-) Doing it all at once made it harder to review. It might have been nice to break this into smaller patches (maybe convert 2-3 functions at a time, instead of all of them). +#if defined(__linux__) defined(HAVE_MNTENT_H) defined(HAVE_GETMNTENT_R) \ + defined(_DIRENT_HAVE_D_TYPE) defined(major) defined(minor) +# define VIR_CGROUP_SUPPORTED Huh - if we are requiring __linux__, then some of the other things are a given (HAVE_MNTENT_H, major, minor), while some are still dependent on having new enough kernel/glibc (_DIRENT_HAVE_D_TYPE). It might be worth trimming this down now that it is obvious we only compile the #if part on Linux; conversely, see comments in the rest of the review about conditions that you didn't factor up here yet. + +#if defined(VIR_CGROUP_SUPPORTED) We prefer #ifdef VIR_CGROUP_SUPPORTED, when there is only one variable being tested. @@ -339,7 +332,6 @@ error: return -1; } - static int virCgroupCopyPlacement(virCgroupPtr group, Our style of late has been two blank lines between functions, so this change (and many others like it) is spurious. @@ -2609,63 +2484,6 @@ int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) Prior to this point, the patch is easy to follow (move the #else portions later in the file). But below here... cpuacct.usage_percpu, usage); } -#ifdef _SC_CLK_TCK I don't see _SC_CLK_TCK in the list of conditionals required by VIR_CGROUP_SUPPORTED up top; why not? -int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, -unsigned long long *sys) -{ ...it got a bit weird, claiming that you are moving the implementation of the #if part rather than the #else part. Again, this argues why splitting the patch into more reviewable portions makes life a bit easier. Does 'git diff --patience' make the output any more legible? -#if defined HAVE_KILL defined HAVE_MNTENT_H defined HAVE_GETMNTENT_R HAVE_KILL is another condition I don't see in the overriding VIR_CGROUP_SUPPORTED definition. + +#else /* !(VIR_CGROUP_SUPPORTED) */ +bool virCgroupAvailable(void) +{ +virReportSystemError(ENXIO, %s, + _(Control groups not supported on this platform)); +return false; This function did NOT set an error prior to your refactoring, so it should not set an error now. When doing refactoring, you must not make any semantic changes (at least, not without documenting in the commit message that such a change was essential, but even then, separating the change from the motion is preferred). Again, an argument for splitting this into smaller, reviewable patches, by moving only 2-3 functions per patch. +} +#endif /* VIR_CGROUP_SUPPORTED */ + +#if defined(VIR_CGROUP_SUPPORTED) defined(HAVE_KILL) Why do you have to split this into a separate section? Linux has always had kill(), meaning this is effectively the same as #ifdef VIR_CGROUP_SUPPORTED. I like where this is headed, but think it's worth another attempt. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Add info about access control checks into API reference
On 08/07/2013 12:06 PM, Eric Blake wrote: On 08/07/2013 06:06 AM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com So that app developers / admins know what access control checks are performed for each API, this patch extends the API docs generator to include details of the ACLs for each. The newapi.xsl template loads the XML files containing the ACL rules and generates a short block of HTML for each API describing the parameter checks and return value filters (if any). Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/libvirt.css | 14 +++ docs/newapi.xsl| 68 ++ src/Makefile.am| 22 ++-- src/rpc/gendispatch.pl | 59 --- 4 files changed, 157 insertions(+), 6 deletions(-) Can you also touch .gitignore to account for the following files now created by your patch? # src/libvirt_access.xml # src/libvirt_access_lxc.xml # src/libvirt_access_qemu.xml -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Patch for BUG ID 994657
Hi All, Here is the change I made to address the SIGSEGV we were seeing in libvirtd when attempting to create a new VM via virt-install: - We call virDomainDefFree after xenDaemonCreateXML returns to xenUnifiedDomainCreateXML. - xenUnifiedDomainCreateXML passes def to virGetDomain after XenDaemonCreateXML returns and before it calls virGetDomain. - xenUnifiedDomainCreateXML calls virDomainDefFree(def) when it's done with def, so no need to free inside xenUnifiedDomainCreateXML. patch - --- /tmp/xend_internal.c2013-08-07 12:03:03.0 -0600 +++ src/xen/xend_internal.c 2013-08-07 08:51:49.0 -0600 @@ -2171,7 +2171,9 @@ if (xenDaemonDomainResume(conn, def) 0) goto error; -virDomainDefFree(def); +// We call this a little later and still want to use def, so +// don't free it just yet. +//virDomainDefFree(def); return 0; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Patch for BUG ID 994657
On 08/07/2013 12:07 PM, Schmaus, John M. (John) wrote: Hi All, Here is the change I made to address the SIGSEGV we were seeing in libvirtd when attempting to create a new VM via virt-install: Thanks for taking time to identify a problem and propose a patch. Your patch didn't apply via 'git am' (see HACKING for details on how to submit a patch that is friendlier to reviewers). Also, your patch uses C99 // comments, which we prefer not to have in our code base. Finally, Stefan Bader beat you to the punch: commit 9d0557b9655fe4a3f31af2e1cc2f33de8acfaa7d Author: Stefan Bader stefan.ba...@canonical.com Date: Wed Jul 31 11:59:21 2013 +0200 xen: Avoid double free of virDomainDef in xenDaemonCreateXML The virDomainDef is allocated by the caller and also used after calling to xenDaemonCreateXML. So it must not get freed by the callee. Signed-off-by: Stefan Bader stefan.ba...@canonical.com As such, I've gone ahead and closed bug 994657. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] maint: avoid C99 loop declaration
Commit 3d0e3c1 reintroduced a problem previously squelched in commit 7e5aa78. Add a syntax check this time around. util/virutil.c: In function 'virGetGroupList': util/virutil.c:1015: error: 'for' loop initial declaration used outside C99 mode * cfg.mk (sc_prohibit_loop_var_decl): New rule. * src/util/virutil.c (virGetGroupList): Fix offender. Signed-off-by: Eric Blake ebl...@redhat.com --- Pushing under the build-breaker rule. cfg.mk | 12 +--- src/util/virutil.c | 8 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cfg.mk b/cfg.mk index 13de268..791c393 100644 --- a/cfg.mk +++ b/cfg.mk @@ -546,15 +546,21 @@ sc_avoid_attribute_unused_in_header: $(_sc_search_regexp) sc_prohibit_int_ijk: - @prohibit='\(int|unsigned) ([^(]* )*(i|j|k)(\s|,|;)' \ + @prohibit='\(int|unsigned) ([^(]* )*(i|j|k)(\s|,|;)' \ halt='use size_t, not int/unsigned int for loop vars i, j, k' \ $(_sc_search_regexp) sc_prohibit_loop_iijjkk: - @prohibit='\(int|unsigned) ([^=]+ )*(ii|jj|kk)(\s|,|;)' \ - halt='use i, j, k for loop iterators, not ii, jj, kk' \ + @prohibit='\(int|unsigned) ([^=]+ )*(ii|jj|kk)(\s|,|;)'\ + halt='use i, j, k for loop iterators, not ii, jj, kk' \ $(_sc_search_regexp) +# RHEL 5 gcc can't grok for (int i... +sc_prohibit_loop_var_decl: + @prohibit='\for *\(\w+[ *]+\w+'\ + in_vc_files='\.[ch]$$' \ + halt='declare loop iterators outside the for statement' \ + $(_sc_search_regexp) # Many of the function names below came from this filter: # git grep -B2 '\_('|grep -E '\.c- *[[:alpha:]_][[:alnum:]_]* ?\(.*[,;]$' \ diff --git a/src/util/virutil.c b/src/util/virutil.c index 3de72ea..34f5998 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -1010,18 +1010,18 @@ virGetGroupList(uid_t uid, gid_t gid, gid_t **list) } if (gid != (gid_t)-1) { -size_t n = ret; +size_t i; -for (size_t i = 0; i ret; i++) { +for (i = 0; i ret; i++) { if ((*list)[i] == gid) goto cleanup; } -if (VIR_APPEND_ELEMENT(*list, n, gid) 0) { +if (VIR_APPEND_ELEMENT(*list, i, gid) 0) { ret = -1; VIR_FREE(*list); goto cleanup; } else { -ret = n; +ret = i; } } -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv3] build: more workarounds for if_bridge.h
This is a second attempt at fixing the problem first attempted in commit 2df8d99; basically undoing the fact that it was reverted in commit 43cee32f, plus fixing two more issues: the code in configure.ac has to EXACTLY match virnetdevbridge.c with regards to declaring in6 types before using if_bridge.h, and the fact that RHEL 5 has even more conflicts: In file included from util/virnetdevbridge.c:49: /usr/include/linux/in6.h:47: error: conflicting types for 'in6addr_any' /usr/include/netinet/in.h:206: error: previous declaration of 'in6addr_any' was here /usr/include/linux/in6.h:49: error: conflicting types for 'in6addr_loopback' /usr/include/netinet/in.h:207: error: previous declaration of 'in6addr_loopback' was here The rest of this commit message borrows from the original try of 2df8d99: A fresh checkout on a RHEL 6 machine with these packages: kernel-headers-2.6.32-405.el6.x86_64 glibc-2.12-1.128.el6.x86_64 failed to configure with this message: checking for linux/if_bridge.h... no configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support Digging in config.log, we see that the problem is identical to what we fixed earlier in commit d12c2811: configure:98831: checking for linux/if_bridge.h configure:98853: gcc -std=gnu99 -c -g -O2 conftest.c 5 In file included from /usr/include/linux/if_bridge.h:17, from conftest.c:559: /usr/include/linux/in6.h:31: error: redefinition of 'struct in6_addr' /usr/include/linux/in6.h:48: error: redefinition of 'struct sockaddr_in6' /usr/include/linux/in6.h:56: error: redefinition of 'struct ipv6_mreq' configure:98860: $? = 1 I had not hit it earlier because I was using incremental builds, where config.cache had shielded me from the kernel-headers breakage. * configure.ac (if_bridge.h): Avoid conflicting type definitions. * src/util/virnetdevbridge.c (includes): Also sanitize for RHEL 5. Signed-off-by: Eric Blake ebl...@redhat.com --- Good thing I'm waiting for a review - that waiting time was enough for me to test on RHEL 5 and find another issue. v3: also work around RHEL 5 - yet ANOTHER symptom of broken if_bridge.h configure.ac | 12 +++- src/util/virnetdevbridge.c | 4 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a155790..d3219ce 100644 --- a/configure.ac +++ b/configure.ac @@ -997,7 +997,17 @@ if test $with_linux = yes; then if test $with_qemu = yes || test $with_lxc = yes ; then AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h linux/if_tun.h],, [AC_MSG_ERROR([You must install kernel-headers in order to compile libvirt with QEMU or LXC support])], - [[#include netinet/in.h + [[/* The kernel folks broke their headers when used with particular + * glibc versions; although the structs are ABI compatible, the + * C type system doesn't like struct redefinitions. We work around + * the problem here in the same manner as in virnetdevbridge.c. */ +#include netinet/in.h +#define in6_addr in6_addr_ +#define sockaddr_in6 sockaddr_in6_ +#define ipv6_mreq ipv6_mreq_ +#define in6addr_any in6addr_any_ +#define in6addr_loopback in6addr_loopback_ +#include linux/in6.h ]]) fi fi diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c index 5d52e23..e4daa27 100644 --- a/src/util/virnetdevbridge.c +++ b/src/util/virnetdevbridge.c @@ -46,11 +46,15 @@ # define in6_addr in6_addr_ # define sockaddr_in6 sockaddr_in6_ # define ipv6_mreq ipv6_mreq_ +# define in6addr_any in6addr_any_ +# define in6addr_loopback in6addr_loopback_ # include linux/in6.h # include linux/if_bridge.h /* SYSFS_BRIDGE_ATTR */ # undef in6_addr # undef sockaddr_in6 # undef ipv6_mreq +# undef in6addr_any +# undef in6addr_loopback # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv2] build: fix configure detection of if_bridge.h on RHEL 6, try 2
On 08/07/2013 10:50 AM, Eric Blake wrote: This is a second attempt at fixing the problem first attempted in commit 2df8d99; basically undoing the fact that it was reverted in commit 43cee32f, plus fixing one more issue: the code in configure.ac has to EXACTLY match virnetdevbridge.c with regards to declaring in6 types before using if_bridge.h. The rest of this commit message borrows from the original: New subject line for v3: https://www.redhat.com/archives/libvir-list/2013-August/msg00313.html -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 00/10] test: Mock snapshot APIs and misc improvements
This series implements snapshot APIs for the test driver, and adds some misc improvements, like specifying domain state in the passed in driver XML. Cole Robinson (10): test: Split object parsing into their own functions test: Simplify args passed to testDomainStartState test: Unify object XML parsing test: Allow specifying object runstate in driver XML test: Allow specifying object transient state in driver XML test: Wire up managed save APIs snapshot_conf: Allow parsing an XML node test: Allow specifying domainsnapshot XML test: Implement readonly snapshot APIs test: Implement snapshot create/delete/revert APIs src/conf/domain_conf.c |3 +- src/conf/snapshot_conf.c | 85 +- src/conf/snapshot_conf.h |6 + src/test/test_driver.c | 4871 +- tests/virshtest.c|2 +- 5 files changed, 3151 insertions(+), 1816 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 06/10] test: Wire up managed save APIs
Also add a hasmanagedsave element to set this data when starting the connection. --- src/test/test_driver.c | 125 - tests/virshtest.c | 2 +- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 3775906..09260ba 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -504,6 +504,7 @@ testDomainStartState(testConnPtr privconn, goto cleanup; } +dom-hasManagedSave = false; ret = 0; cleanup: if (ret 0) @@ -940,6 +941,7 @@ testParseDomains(testConnPtr privconn, for (i = 0; i num; i++) { unsigned int runstate; bool transient; +bool hasManagedSave; virDomainDefPtr def; xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, domain); if (!node) @@ -951,6 +953,9 @@ testParseDomains(testConnPtr privconn, goto error; if (testParseXMLObjectBool(ctxt, node, transient, transient) 0) goto error; +if (testParseXMLObjectBool(ctxt, node, + hasmanagedsave, hasManagedSave) 0) +goto error; if (testNodeUnlinkCustomXML(ctxt, node) 0) goto error; @@ -982,6 +987,7 @@ testParseDomains(testConnPtr privconn, testDomainShutdownState(NULL, obj, 0); } virDomainObjSetState(obj, runstate, 0); +obj-hasManagedSave = hasManagedSave; virObjectUnlock(obj); } @@ -2817,7 +2823,7 @@ static int testDomainUndefineFlags(virDomainPtr domain, virDomainEventPtr event = NULL; int ret = -1; -virCheckFlags(0, -1); +virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE, -1); testDriverLock(privconn); privdom = virDomainObjListFindByName(privconn-domains, @@ -2828,6 +2834,15 @@ static int testDomainUndefineFlags(virDomainPtr domain, goto cleanup; } +if (privdom-hasManagedSave +!(flags VIR_DOMAIN_UNDEFINE_MANAGED_SAVE)) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, + _(Refusing to undefine while domain managed + save image exists)); +goto cleanup; +} +privdom-hasManagedSave = false; + event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_UNDEFINED, VIR_DOMAIN_EVENT_UNDEFINED_REMOVED); @@ -5952,6 +5967,111 @@ testDomainScreenshot(virDomainPtr dom ATTRIBUTE_UNUSED, } +static int +testDomainManagedSave(virDomainPtr dom, unsigned int flags) +{ +testConnPtr privconn = dom-conn-privateData; +virDomainObjPtr vm = NULL; +virDomainEventPtr event = NULL; +int ret = -1; + +virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE | + VIR_DOMAIN_SAVE_RUNNING | + VIR_DOMAIN_SAVE_PAUSED, -1); + +testDriverLock(privconn); +vm = virDomainObjListFindByName(privconn-domains, dom-name); +testDriverUnlock(privconn); + +if (vm == NULL) { +virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto cleanup; +} + +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + %s, _(domain is not running)); +goto cleanup; +} + +if (!vm-persistent) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, + _(cannot do managed save for transient domain)); +goto cleanup; +} + +testDomainShutdownState(dom, vm, VIR_DOMAIN_SHUTOFF_SAVED); +event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_SAVED); +vm-hasManagedSave = true; + +ret = 0; +cleanup: +if (vm) +virObjectUnlock(vm); +if (event) { +testDriverLock(privconn); +testDomainEventQueue(privconn, event); +testDriverUnlock(privconn); +} + +return ret; +} + + +static int +testDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) +{ +testConnPtr privconn = dom-conn-privateData; +virDomainObjPtr vm; +int ret = -1; + +virCheckFlags(0, -1); + +testDriverLock(privconn); + +vm = virDomainObjListFindByName(privconn-domains, dom-name); +if (vm == NULL) { +virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto cleanup; +} + +ret = vm-hasManagedSave; +cleanup: +if (vm) +virObjectUnlock(vm); +testDriverUnlock(privconn); +return ret; +} + +static int +testDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) +{ +testConnPtr privconn = dom-conn-privateData; +virDomainObjPtr vm; +int ret = -1; + +virCheckFlags(0, -1); + +testDriverLock(privconn); + +vm = virDomainObjListFindByName(privconn-domains, dom-name); +if (vm == NULL) { +virReportError(VIR_ERR_INVALID_ARG,
[libvirt] [PATCH 01/10] test: Split object parsing into their own functions
The function that parses custom driver XML was getting pretty unruly, split the object parsing into their own functions. Rename some variables to be consistent across each function. This should be functionally identical. --- src/test/test_driver.c | 463 + 1 file changed, 276 insertions(+), 187 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index f7eaf06..718f83c 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -689,131 +689,13 @@ static char *testBuildFilename(const char *relativeTo, } } -static int testOpenVolumesForPool(xmlDocPtr xml, - xmlXPathContextPtr ctxt, - const char *file, - virStoragePoolObjPtr pool, - int poolidx) { -char *vol_xpath; -size_t i; -int ret, func_ret = -1; -xmlNodePtr *vols = NULL; -virStorageVolDefPtr def = NULL; - -/* Find storage volumes */ -if (virAsprintf(vol_xpath, /node/pool[%d]/volume, poolidx) 0) -goto error; - -ret = virXPathNodeSet(vol_xpath, ctxt, vols); -VIR_FREE(vol_xpath); -if (ret 0) { -goto error; -} - -for (i = 0; i ret; i++) { -char *relFile = virXMLPropString(vols[i], file); -if (relFile != NULL) { -char *absFile = testBuildFilename(file, relFile); -VIR_FREE(relFile); -if (!absFile) { -virReportError(VIR_ERR_INTERNAL_ERROR, %s, - _(resolving volume filename)); -goto error; -} - -def = virStorageVolDefParseFile(pool-def, absFile); -VIR_FREE(absFile); -if (!def) -goto error; -} else { -if ((def = virStorageVolDefParseNode(pool-def, xml, - vols[i])) == NULL) { -goto error; -} -} - -if (VIR_REALLOC_N(pool-volumes.objs, - pool-volumes.count+1) 0) -goto error; - -if (def-target.path == NULL) { -if (virAsprintf(def-target.path, %s/%s, -pool-def-target.path, -def-name) == -1) -goto error; -} - -if (!def-key VIR_STRDUP(def-key, def-target.path) 0) -goto error; - -pool-def-allocation += def-allocation; -pool-def-available = (pool-def-capacity - -pool-def-allocation); - -pool-volumes.objs[pool-volumes.count++] = def; -def = NULL; -} - -func_ret = 0; -error: -virStorageVolDefFree(def); -VIR_FREE(vols); -return func_ret; -} - -static int testOpenFromFile(virConnectPtr conn, -const char *file) { -size_t i; -int ret; -long l; +static int +testParseNodeInfo(virNodeInfoPtr nodeInfo, xmlXPathContextPtr ctxt) +{ char *str; -xmlDocPtr xml = NULL; -xmlNodePtr *domains = NULL, *networks = NULL, *ifaces = NULL, - *pools = NULL, *devs = NULL; -xmlXPathContextPtr ctxt = NULL; -virNodeInfoPtr nodeInfo; -virNetworkObjPtr net; -virInterfaceObjPtr iface; -virDomainObjPtr dom; -testConnPtr privconn; -if (VIR_ALLOC(privconn) 0) -return VIR_DRV_OPEN_ERROR; -if (virMutexInit(privconn-lock) 0) { -virReportError(VIR_ERR_INTERNAL_ERROR, - %s, _(cannot initialize mutex)); -VIR_FREE(privconn); -return VIR_DRV_OPEN_ERROR; -} - -testDriverLock(privconn); -conn-privateData = privconn; - -if (!(privconn-domains = virDomainObjListNew())) -goto error; - -if (!(privconn-caps = testBuildCapabilities(conn))) -goto error; - -if (!(privconn-xmlopt = testBuildXMLConfig())) -goto error; - -if (!(xml = virXMLParseFileCtxt(file, ctxt))) { -goto error; -} - -if (!xmlStrEqual(ctxt-node-name, BAD_CAST node)) { -virReportError(VIR_ERR_XML_ERROR, %s, - _(Root element is not 'node')); -goto error; -} - -privconn-nextDomID = 1; -privconn-numCells = 0; -if (VIR_STRDUP(privconn-path, file) 0) -goto error; -memmove(privconn-nodeInfo, defaultNodeInfo, sizeof(defaultNodeInfo)); +long l; +int ret; -nodeInfo = privconn-nodeInfo; ret = virXPathLong(string(/node/cpu/nodes[1]), ctxt, l); if (ret == 0) { nodeInfo-nodes = l; @@ -850,7 +732,8 @@ static int testOpenFromFile(virConnectPtr conn, goto error; } -nodeInfo-cpus = nodeInfo-cores * nodeInfo-threads * nodeInfo-sockets * nodeInfo-nodes; +nodeInfo-cpus = (nodeInfo-cores * nodeInfo-threads * + nodeInfo-sockets * nodeInfo-nodes); ret = virXPathLong(string(/node/cpu/active[1]), ctxt, l);
[libvirt] [PATCH 04/10] test: Allow specifying object runstate in driver XML
When passing in custom driver XML, allow a block like domain ... testdriver runstate3/runstate /testdriver /domain This is only read at initial driver start time, and sets the initial run state of the object. This is handy for UI testing. Wire it up for domains, networks, pools, and interfaces. The latter 3 only have a notion of active and inactive, which map to runstate 1 and 0 respectively. We also take care to unlink this testdriver block before passing the XML to the object parse function. Right now nothing complains, but if XML parsing became stricter in the future we don't want it to choke on this custom element. --- src/test/test_driver.c | 123 ++--- 1 file changed, 116 insertions(+), 7 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index d7b2e40..4be20b1 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -813,6 +813,80 @@ error: return -1; } +/* + * Parse object runstate from passed in XML, ex: + * domain + * ... + * testdriver + * runstate%d/runstate + * /testdriver + * /domain + */ +static int +testParseXMLObjectRunstate(xmlXPathContextPtr ctxt, + xmlNodePtr node, + unsigned int limit, + unsigned int def, + unsigned int *val) +{ +int tmp, ret = -1; +unsigned int tmpval; +char *xpath = NULL; + +if (virAsprintf(xpath, string(%s/testdriver/runstate), +xmlGetNodePath(node)) 0) +goto error; + +tmp = virXPathUInt(xpath, ctxt, tmpval); +if (tmp == 0) { +if (tmpval = limit) { +virReportError(VIR_ERR_XML_ERROR, + _(runstate '%d' out of range'), tmpval); +goto error; +} +*val = tmpval; +} else if (tmp == -1) { +*val = def; +} else if (tmp == -2) { +virReportError(VIR_ERR_XML_ERROR, %s, + _(invalid runstate)); +goto error; +} + +ret = 0; +error: +VIR_FREE(xpath); +return ret; +} + +/* + * Unlink custom testdriver XML before handing the node off + * to the object parsing handler, since it may complain about unrecognized + * elements (if not now, then in the future) + */ +static int +testNodeUnlinkCustomXML(xmlXPathContextPtr ctxt, xmlNodePtr node) +{ +int ret = -1; +char *xpath = NULL; +xmlNodePtr testnode; + +if (virAsprintf(xpath, %s/testdriver, +xmlGetNodePath(node)) 0) +goto error; + +testnode = virXPathNode(xpath, ctxt); +if (testnode) { +xmlUnlinkNode(testnode); +xmlFreeNode(testnode); +} + +ret = 0; +error: +VIR_FREE(xpath); +return ret; +} + static int testParseDomains(testConnPtr privconn, const char *file, @@ -829,11 +903,20 @@ testParseDomains(testConnPtr privconn, } for (i = 0; i num; i++) { +unsigned int runstate; virDomainDefPtr def; xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, domain); if (!node) goto error; +if (testParseXMLObjectRunstate(ctxt, node, + VIR_DOMAIN_LAST, VIR_DOMAIN_RUNNING, + runstate) 0) +goto error; + +if (testNodeUnlinkCustomXML(ctxt, node) 0) +goto error; + def = virDomainDefParseNode(ctxt-doc, node, privconn-caps, privconn-xmlopt, 1 VIR_DOMAIN_VIRT_TEST, @@ -851,11 +934,16 @@ testParseDomains(testConnPtr privconn, } obj-persistent = 1; -if (testDomainStartState(privconn, obj, - VIR_DOMAIN_RUNNING_BOOTED) 0) { -virObjectUnlock(obj); -goto error; +if (runstate != VIR_DOMAIN_SHUTOFF) { +if (testDomainStartState(privconn, obj, + VIR_DOMAIN_RUNNING_BOOTED) 0) { +virObjectUnlock(obj); +goto error; +} +} else { +testDomainShutdownState(NULL, obj, 0); } +virDomainObjSetState(obj, runstate, 0); virObjectUnlock(obj); } @@ -882,11 +970,18 @@ testParseNetworks(testConnPtr privconn, } for (i = 0; i num; i++) { +unsigned int runstate; virNetworkDefPtr def; xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, network); if (!node) goto error; +if (testParseXMLObjectRunstate(ctxt, node, 1, 1, runstate) 0) +goto error; + +if (testNodeUnlinkCustomXML(ctxt, node) 0) +goto error; + def = virNetworkDefParseNode(ctxt-doc, node); if (!def) goto error; @@ -897,7 +992,7 @@ testParseNetworks(testConnPtr privconn, }
[libvirt] [PATCH 03/10] test: Unify object XML parsing
Right now things are split a bit between parsing from a relative file path or parsing from inline XML. Unify it. This will simplify upcoming bits. --- src/test/test_driver.c | 236 + 1 file changed, 103 insertions(+), 133 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 960a58e..d7b2e40 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -687,6 +687,43 @@ static char *testBuildFilename(const char *relativeTo, } } +static xmlNodePtr +testParseXMLDocFromFile(xmlNodePtr node, const char *file, const char *type) +{ +xmlNodePtr ret = NULL; +xmlDocPtr doc = NULL; +char *absFile = NULL; +char *relFile = virXMLPropString(node, file); + +if (relFile != NULL) { +absFile = testBuildFilename(file, relFile); +VIR_FREE(relFile); +if (!absFile) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(resolving %s filename), type); +return NULL; +} + +if (!(doc = virXMLParse(absFile, NULL, type))) +goto error; + +ret = xmlCopyNode(xmlDocGetRootElement(doc), 1); +if (!ret) { +virReportOOMError(); +goto error; +} +xmlReplaceNode(node, ret); +xmlFreeNode(node); +} else { +ret = node; +} + +error: +xmlFreeDoc(doc); +VIR_FREE(absFile); +return ret; +} + static int testParseNodeInfo(virNodeInfoPtr nodeInfo, xmlXPathContextPtr ctxt) { @@ -777,8 +814,9 @@ error: } static int -testParseDomains(testConnPtr privconn, const char *file, - xmlDocPtr doc, xmlXPathContextPtr ctxt) +testParseDomains(testConnPtr privconn, + const char *file, + xmlXPathContextPtr ctxt) { int num, ret = -1; size_t i; @@ -792,29 +830,16 @@ testParseDomains(testConnPtr privconn, const char *file, for (i = 0; i num; i++) { virDomainDefPtr def; -char *relFile = virXMLPropString(nodes[i], file); -if (relFile != NULL) { -char *absFile = testBuildFilename(file, relFile); -VIR_FREE(relFile); -if (!absFile) { -virReportError(VIR_ERR_INTERNAL_ERROR, %s, - _(resolving domain filename)); -goto error; -} -def = virDomainDefParseFile(absFile, privconn-caps, -privconn-xmlopt, -1 VIR_DOMAIN_VIRT_TEST, -VIR_DOMAIN_XML_INACTIVE); -VIR_FREE(absFile); -if (!def) -goto error; -} else { -if ((def = virDomainDefParseNode(doc, nodes[i], - privconn-caps, privconn-xmlopt, - 1 VIR_DOMAIN_VIRT_TEST, - VIR_DOMAIN_XML_INACTIVE)) == NULL) -goto error; -} +xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, domain); +if (!node) +goto error; + +def = virDomainDefParseNode(ctxt-doc, node, +privconn-caps, privconn-xmlopt, +1 VIR_DOMAIN_VIRT_TEST, +VIR_DOMAIN_XML_INACTIVE); +if (!def) +goto error; if (testDomainGenerateIfnames(def) 0 || !(obj = virDomainObjListAdd(privconn-domains, @@ -842,8 +867,9 @@ error: } static int -testParseNetworks(testConnPtr privconn, const char *file, - xmlDocPtr doc, xmlXPathContextPtr ctxt) +testParseNetworks(testConnPtr privconn, + const char *file, + xmlXPathContextPtr ctxt) { int num, ret = -1; size_t i; @@ -857,24 +883,13 @@ testParseNetworks(testConnPtr privconn, const char *file, for (i = 0; i num; i++) { virNetworkDefPtr def; -char *relFile = virXMLPropString(nodes[i], file); -if (relFile != NULL) { -char *absFile = testBuildFilename(file, relFile); -VIR_FREE(relFile); -if (!absFile) { -virReportError(VIR_ERR_INTERNAL_ERROR, %s, - _(resolving network filename)); -goto error; -} +xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, network); +if (!node) +goto error; -def = virNetworkDefParseFile(absFile); -VIR_FREE(absFile); -if (!def) -goto error; -} else { -if ((def = virNetworkDefParseNode(doc, nodes[i])) == NULL) -goto error; -} +def = virNetworkDefParseNode(ctxt-doc, node); +if (!def) +goto error; if (!(obj =
[libvirt] [PATCH 07/10] snapshot_conf: Allow parsing an XML node
Similar to how other objects arrange their parse APIs. This will be used by the test driver. --- src/conf/snapshot_conf.c | 85 ++-- src/conf/snapshot_conf.h | 6 2 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 2a52418..45d6af4 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -166,15 +166,13 @@ cleanup: * If flags does not include VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE, then * caps and expectedVirtTypes are ignored. */ -virDomainSnapshotDefPtr -virDomainSnapshotDefParseString(const char *xmlStr, -virCapsPtr caps, -virDomainXMLOptionPtr xmlopt, -unsigned int expectedVirtTypes, -unsigned int flags) +static virDomainSnapshotDefPtr +virDomainSnapshotDefParse(xmlXPathContextPtr ctxt, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + unsigned int expectedVirtTypes, + unsigned int flags) { -xmlXPathContextPtr ctxt = NULL; -xmlDocPtr xml = NULL; virDomainSnapshotDefPtr def = NULL; virDomainSnapshotDefPtr ret = NULL; xmlNodePtr *nodes = NULL; @@ -184,26 +182,13 @@ virDomainSnapshotDefParseString(const char *xmlStr, struct timeval tv; int active; char *tmp; -int keepBlanksDefault = xmlKeepBlanksDefault(0); char *memorySnapshot = NULL; char *memoryFile = NULL; bool offline = !!(flags VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE); -xml = virXMLParseCtxt(NULL, xmlStr, _((domain_snapshot)), ctxt); -if (!xml) { -xmlKeepBlanksDefault(keepBlanksDefault); -return NULL; -} -xmlKeepBlanksDefault(keepBlanksDefault); - if (VIR_ALLOC(def) 0) goto cleanup; -if (!xmlStrEqual(ctxt-node-name, BAD_CAST domainsnapshot)) { -virReportError(VIR_ERR_XML_ERROR, %s, _(domainsnapshot)); -goto cleanup; -} - gettimeofday(tv, NULL); def-name = virXPathString(string(./name), ctxt); @@ -261,7 +246,8 @@ virDomainSnapshotDefParseString(const char *xmlStr, _(missing domain in snapshot)); goto cleanup; } -def-dom = virDomainDefParseNode(xml, domainNode, caps, xmlopt, +def-dom = virDomainDefParseNode(ctxt-node-doc, domainNode, + caps, xmlopt, expectedVirtTypes, (VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE)); @@ -348,10 +334,61 @@ cleanup: VIR_FREE(nodes); VIR_FREE(memorySnapshot); VIR_FREE(memoryFile); -xmlXPathFreeContext(ctxt); if (ret == NULL) virDomainSnapshotDefFree(def); -xmlFreeDoc(xml); + +return ret; +} + +virDomainSnapshotDefPtr +virDomainSnapshotDefParseNode(xmlDocPtr xml, + xmlNodePtr root, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + unsigned int expectedVirtTypes, + unsigned int flags) +{ +xmlXPathContextPtr ctxt = NULL; +virDomainSnapshotDefPtr def = NULL; + +if (!xmlStrEqual(root-name, BAD_CAST domainsnapshot)) { +virReportError(VIR_ERR_XML_ERROR, %s, _(domainsnapshot)); +goto cleanup; +} + +ctxt = xmlXPathNewContext(xml); +if (ctxt == NULL) { +virReportOOMError(); +goto cleanup; +} + +ctxt-node = root; +def = virDomainSnapshotDefParse(ctxt, caps, xmlopt, +expectedVirtTypes, flags); +cleanup: +xmlXPathFreeContext(ctxt); +return def; +} + +virDomainSnapshotDefPtr +virDomainSnapshotDefParseString(const char *xmlStr, +virCapsPtr caps, +virDomainXMLOptionPtr xmlopt, +unsigned int expectedVirtTypes, +unsigned int flags) +{ +virDomainSnapshotDefPtr ret = NULL; +xmlDocPtr xml; +int keepBlanksDefault = xmlKeepBlanksDefault(0); + +if ((xml = virXMLParse(NULL, xmlStr, _((domain_snapshot) { +xmlKeepBlanksDefault(keepBlanksDefault); +ret = virDomainSnapshotDefParseNode(xml, xmlDocGetRootElement(xml), +caps, xmlopt, +expectedVirtTypes, flags); +xmlFreeDoc(xml); +} +xmlKeepBlanksDefault(keepBlanksDefault); return ret; } diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h index 6d625a7..0b8d18a 100644 --- a/src/conf/snapshot_conf.h +++ b/src/conf/snapshot_conf.h @@ -104,6 +104,12 @@
[libvirt] [PATCH 02/10] test: Simplify args passed to testDomainStartState
Passing virConnectPtr is redundant, just pass testConnPtr and simplify certain callers. --- src/test/test_driver.c | 36 +--- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 718f83c..960a58e 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -379,8 +379,7 @@ testDomainGenerateIfnames(virDomainDefPtr domdef) /* Helper to update info for a single VCPU */ static int -testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED, - virDomainObjPtr dom, +testDomainUpdateVCPU(virDomainObjPtr dom, int vcpu, int maplen, int maxcpu) @@ -430,12 +429,11 @@ testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED, * @clear_all: If true, rebuild info for ALL vcpus, not just newly added vcpus */ static int -testDomainUpdateVCPUs(virConnectPtr conn, +testDomainUpdateVCPUs(testConnPtr privconn, virDomainObjPtr dom, int nvcpus, unsigned int clear_all) { -testConnPtr privconn = conn-privateData; testDomainObjPrivatePtr privdata = dom-privateData; size_t i; int ret = -1; @@ -453,13 +451,13 @@ testDomainUpdateVCPUs(virConnectPtr conn, /* Set running VCPU and cpumap state */ if (clear_all) { for (i = 0; i nvcpus; ++i) -if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) 0) +if (testDomainUpdateVCPU(dom, i, cpumaplen, maxcpu) 0) goto cleanup; } else if (nvcpus dom-def-vcpus) { /* VCPU amount has grown, populate info for the new vcpus */ for (i = dom-def-vcpus; i nvcpus; ++i) -if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) 0) +if (testDomainUpdateVCPU(dom, i, cpumaplen, maxcpu) 0) goto cleanup; } @@ -488,14 +486,13 @@ testDomainShutdownState(virDomainPtr domain, /* Set up domain runtime state */ static int -testDomainStartState(virConnectPtr conn, +testDomainStartState(testConnPtr privconn, virDomainObjPtr dom, virDomainRunningReason reason) { -testConnPtr privconn = conn-privateData; int ret = -1; -if (testDomainUpdateVCPUs(conn, dom, dom-def-vcpus, 1) 0) +if (testDomainUpdateVCPUs(privconn, dom, dom-def-vcpus, 1) 0) goto cleanup; virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, reason); @@ -587,7 +584,8 @@ static int testOpenDefault(virConnectPtr conn) { domdef = NULL; domobj-persistent = 1; -if (testDomainStartState(conn, domobj, VIR_DOMAIN_RUNNING_BOOTED) 0) { +if (testDomainStartState(privconn, domobj, + VIR_DOMAIN_RUNNING_BOOTED) 0) { virObjectUnlock(domobj); goto error; } @@ -779,8 +777,7 @@ error: } static int -testParseDomains(virConnectPtr conn, - testConnPtr privconn, const char *file, +testParseDomains(testConnPtr privconn, const char *file, xmlDocPtr doc, xmlXPathContextPtr ctxt) { int num, ret = -1; @@ -829,7 +826,8 @@ testParseDomains(virConnectPtr conn, } obj-persistent = 1; -if (testDomainStartState(conn, obj, VIR_DOMAIN_RUNNING_BOOTED) 0) { +if (testDomainStartState(privconn, obj, + VIR_DOMAIN_RUNNING_BOOTED) 0) { virObjectUnlock(obj); goto error; } @@ -1180,7 +1178,7 @@ testOpenFromFile(virConnectPtr conn, const char *file) if (testParseNodeInfo(privconn-nodeInfo, ctxt) 0) goto error; -if (testParseDomains(conn, privconn, file, doc, ctxt) 0) +if (testParseDomains(privconn, file, doc, ctxt) 0) goto error; if (testParseNetworks(privconn, file, doc, ctxt) 0) goto error; @@ -1428,7 +1426,7 @@ testDomainCreateXML(virConnectPtr conn, const char *xml, goto cleanup; def = NULL; -if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) 0) +if (testDomainStartState(privconn, dom, VIR_DOMAIN_RUNNING_BOOTED) 0) goto cleanup; event = virDomainEventNewFromObj(dom, @@ -2043,7 +2041,7 @@ testDomainRestoreFlags(virConnectPtr conn, goto cleanup; def = NULL; -if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_RESTORED) 0) +if (testDomainStartState(privconn, dom, VIR_DOMAIN_RUNNING_RESTORED) 0) goto cleanup; event = virDomainEventNewFromObj(dom, @@ -2342,11 +2340,11 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus, break; case VIR_DOMAIN_AFFECT_LIVE: -ret = testDomainUpdateVCPUs(domain-conn, privdom, nrCpus, 0); +ret = testDomainUpdateVCPUs(privconn, privdom, nrCpus, 0); break; case VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG: -ret =
[libvirt] [PATCH 09/10] test: Implement readonly snapshot APIs
This is just stolen from qemu_driver.c with tweaks to fit the test driver. --- src/test/test_driver.c | 392 + 1 file changed, 392 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 67c6d68..0d4cc85 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -44,6 +44,7 @@ #include interface_conf.h #include domain_conf.h #include domain_event.h +#include snapshot_conf.h #include fdstream.h #include storage_conf.h #include node_device_conf.h @@ -326,6 +327,27 @@ static const unsigned long long defaultPoolAlloc = 0; static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool); static int testNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info); +static virDomainObjPtr +testDomObjFromDomain(virDomainPtr domain) +{ +virDomainObjPtr vm; +testConnPtr driver = domain-conn-privateData; +char uuidstr[VIR_UUID_STRING_BUFLEN]; + +testDriverLock(driver); +vm = virDomainObjListFindByUUID(driver-domains, domain-uuid); +if (!vm) { +virUUIDFormat(domain-uuid, uuidstr); +virReportError(VIR_ERR_NO_DOMAIN, + _(no domain with matching uuid '%s' (%s)), + uuidstr, domain-name); +vm = NULL; +} + +testDriverUnlock(driver); +return vm; +} + static char * testDomainGenerateIfname(virDomainDefPtr domdef) { int maxif = 1024; @@ -6139,6 +6161,362 @@ cleanup: } +/* + * Snapshot APIs + */ + +static virDomainSnapshotObjPtr +testSnapObjFromName(virDomainObjPtr vm, +const char *name) +{ +virDomainSnapshotObjPtr snap = NULL; +snap = virDomainSnapshotFindByName(vm-snapshots, name); +if (!snap) +virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, + _(no domain snapshot with matching name '%s'), + name); +return snap; +} + +static virDomainSnapshotObjPtr +testSnapObjFromSnapshot(virDomainObjPtr vm, +virDomainSnapshotPtr snapshot) +{ +return testSnapObjFromName(vm, snapshot-name); +} + +static virDomainObjPtr +testDomObjFromSnapshot(virDomainSnapshotPtr snapshot) +{ +return testDomObjFromDomain(snapshot-domain); +} + +static int +testDomainSnapshotNum(virDomainPtr domain, unsigned int flags) +{ +virDomainObjPtr vm = NULL; +int n = -1; + +virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | + VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1); + +if (!(vm = testDomObjFromDomain(domain))) +goto cleanup; + +n = virDomainSnapshotObjListNum(vm-snapshots, NULL, flags); + +cleanup: +if (vm) +virObjectUnlock(vm); +return n; +} + +static int +testDomainSnapshotListNames(virDomainPtr domain, +char **names, +int nameslen, +unsigned int flags) +{ +virDomainObjPtr vm = NULL; +int n = -1; + +virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | + VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1); + +if (!(vm = testDomObjFromDomain(domain))) +goto cleanup; + +n = virDomainSnapshotObjListGetNames(vm-snapshots, NULL, names, nameslen, + flags); + +cleanup: +if (vm) +virObjectUnlock(vm); +return n; +} + +static int +testDomainListAllSnapshots(virDomainPtr domain, + virDomainSnapshotPtr **snaps, + unsigned int flags) +{ +virDomainObjPtr vm = NULL; +int n = -1; + +virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | + VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1); + +if (!(vm = testDomObjFromDomain(domain))) +goto cleanup; + +n = virDomainListSnapshots(vm-snapshots, NULL, domain, snaps, flags); + +cleanup: +if (vm) +virObjectUnlock(vm); +return n; +} + +static int +testDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, +char **names, +int nameslen, +unsigned int flags) +{ +virDomainObjPtr vm = NULL; +virDomainSnapshotObjPtr snap = NULL; +int n = -1; + +virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | + VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1); + +if (!(vm = testDomObjFromSnapshot(snapshot))) +goto cleanup; + +if (!(snap = testSnapObjFromSnapshot(vm, snapshot))) +goto cleanup; + +n = virDomainSnapshotObjListGetNames(vm-snapshots, snap, names, nameslen, + flags); + +cleanup: +if (vm) +virObjectUnlock(vm); +return n; +} + +static int +testDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, + unsigned int flags) +{ +virDomainObjPtr vm = NULL; +virDomainSnapshotObjPtr snap = NULL; +int n = -1; + +virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | +
[libvirt] [PATCH 10/10] test: Implement snapshot create/delete/revert APIs
Again stolen from qemu_driver.c, but dropping all the unneeded bits. This aims to copy all the current qemu validation checks since that's the most commonly used real driver, but some of the checks are completely artificial in the test driver. This only supports creation of internal snapshots for initial simplicity. --- src/conf/domain_conf.c | 3 +- src/test/test_driver.c | 504 - 2 files changed, 505 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7309877..debac4b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13371,7 +13371,8 @@ virDomainDefCheckABIStability(virDomainDefPtr src, virArchToString(src-os.arch)); return false; } -if (STRNEQ(src-os.machine, dst-os.machine)) { +if (src-os.machine dst-os.machine +STRNEQ(src-os.machine, dst-os.machine)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(Target domain OS type %s does not match source %s), dst-os.machine, src-os.machine); diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 0d4cc85..6b73e5b 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2910,9 +2910,11 @@ static int testDomainUndefineFlags(virDomainPtr domain, testConnPtr privconn = domain-conn-privateData; virDomainObjPtr privdom; virDomainEventPtr event = NULL; +int nsnapshots; int ret = -1; -virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE, -1); +virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE | + VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1); testDriverLock(privconn); privdom = virDomainObjListFindByName(privconn-domains, @@ -2932,6 +2934,24 @@ static int testDomainUndefineFlags(virDomainPtr domain, } privdom-hasManagedSave = false; +/* Requiring an inactive VM is part of the documented API for + * UNDEFINE_SNAPSHOTS_METADATA + */ +if (!virDomainObjIsActive(privdom) +(nsnapshots = virDomainSnapshotObjListNum(privdom-snapshots, + NULL, 0))) { +if (!(flags VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA)) { +virReportError(VIR_ERR_OPERATION_INVALID, + _(cannot delete inactive domain with %d + snapshots), + nsnapshots); +goto cleanup; +} + +/* There isn't actually anything to do, we are just emulating qemu + * behavior here. */ +} + event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_UNDEFINED, VIR_DOMAIN_EVENT_UNDEFINED_REMOVED); @@ -6516,6 +6536,485 @@ cleanup: return ret; } +static int +testDomainSnapshotAlignDisks(virDomainObjPtr vm, + virDomainSnapshotDefPtr def, + unsigned int flags) +{ +int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL; +int align_match = true; + +if (flags VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) { +align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL; +align_match = false; +if (virDomainObjIsActive(vm)) +def-state = VIR_DOMAIN_DISK_SNAPSHOT; +else +def-state = VIR_DOMAIN_SHUTOFF; +def-memory = VIR_DOMAIN_SNAPSHOT_LOCATION_NONE; +} else if (def-memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) { +def-state = virDomainObjGetState(vm, NULL); +align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL; +align_match = false; +} else { +def-state = virDomainObjGetState(vm, NULL); +def-memory = (def-state == VIR_DOMAIN_SHUTOFF ? + VIR_DOMAIN_SNAPSHOT_LOCATION_NONE : + VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL); +} + +return virDomainSnapshotAlignDisks(def, align_location, align_match); +} + +static virDomainSnapshotPtr +testDomainSnapshotCreateXML(virDomainPtr domain, +const char *xmlDesc, +unsigned int flags) +{ +testConnPtr privconn = domain-conn-privateData; +virDomainObjPtr vm = NULL; +virDomainSnapshotDefPtr def = NULL; +virDomainSnapshotObjPtr snap = NULL; +virDomainSnapshotPtr snapshot = NULL; +virDomainEventPtr event = NULL; +char *xml = NULL; +unsigned int parse_flags = VIR_DOMAIN_SNAPSHOT_PARSE_DISKS; + +/* + * REDEFINE + CURRENT: Not implemented yet + * DISK_ONLY: Not implemented yet + * REUSE_EXT: Not implemented yet + * + * NO_METADATA: Explicitly not implemented + * + * HALT: Implemented + * QUIESCE: Nothing to do + * ATOMIC: Nothing to do + * LIVE: Nothing to do + */ +virCheckFlags( +VIR_DOMAIN_SNAPSHOT_CREATE_HALT | +
[libvirt] [PATCH 05/10] test: Allow specifying object transient state in driver XML
Similar to the runstate commit, allow a block like: testdriver transient/ /testdriver Wire it up for domains and networks. Generalize the boolean lookup pattern since we are going to use it for other bits as well. --- src/test/test_driver.c | 45 +++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 4be20b1..3775906 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -860,6 +860,41 @@ error: } /* + * Parse object bool value from passed in XML, transient example: + * domain + * ... + * testdriver + * transient/ + * /testdriver + * /domain + */ +static int +testParseXMLObjectBool(xmlXPathContextPtr ctxt, + xmlNodePtr node, + const char *name, + bool *val) +{ +int ret = -1; +char *xpath = NULL; + +if (virAsprintf(xpath, boolean(%s/testdriver/%s), +xmlGetNodePath(node), name) 0) +goto error; + +ret = virXPathBoolean(xpath, ctxt); +if (ret == -1) { +virReportError(VIR_ERR_XML_ERROR, _(invalid %s), name); +goto error; +} +*val = ret; + +ret = 0; +error: +VIR_FREE(xpath); +return ret; +} + +/* * Unlink custom testdriver XML before handing the node off * to the object parsing handler, since it may complain about unrecognized * elements (if not now, then in the future) @@ -904,6 +939,7 @@ testParseDomains(testConnPtr privconn, for (i = 0; i num; i++) { unsigned int runstate; +bool transient; virDomainDefPtr def; xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, domain); if (!node) @@ -913,6 +949,8 @@ testParseDomains(testConnPtr privconn, VIR_DOMAIN_LAST, VIR_DOMAIN_RUNNING, runstate) 0) goto error; +if (testParseXMLObjectBool(ctxt, node, transient, transient) 0) +goto error; if (testNodeUnlinkCustomXML(ctxt, node) 0) goto error; @@ -933,7 +971,7 @@ testParseDomains(testConnPtr privconn, goto error; } -obj-persistent = 1; +obj-persistent = !transient; if (runstate != VIR_DOMAIN_SHUTOFF) { if (testDomainStartState(privconn, obj, VIR_DOMAIN_RUNNING_BOOTED) 0) { @@ -970,6 +1008,7 @@ testParseNetworks(testConnPtr privconn, } for (i = 0; i num; i++) { +bool transient; unsigned int runstate; virNetworkDefPtr def; xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, network); @@ -978,6 +1017,8 @@ testParseNetworks(testConnPtr privconn, if (testParseXMLObjectRunstate(ctxt, node, 1, 1, runstate) 0) goto error; +if (testParseXMLObjectBool(ctxt, node, transient, transient) 0) +goto error; if (testNodeUnlinkCustomXML(ctxt, node) 0) goto error; @@ -991,7 +1032,7 @@ testParseNetworks(testConnPtr privconn, goto error; } -obj-persistent = 1; +obj-persistent = !transient; obj-active = runstate; virNetworkObjUnlock(obj); } -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 08/10] test: Allow specifying domainsnapshot XML
The user can pass it in as a subelement of domain as we already do for storage volumes. --- src/test/test_driver.c | 67 ++ 1 file changed, 67 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 09260ba..67c6d68 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -924,6 +924,68 @@ error: } static int +testParseDomainSnapshots(testConnPtr privconn, + virDomainObjPtr domobj, + const char *file, + xmlXPathContextPtr ctxt, + xmlNodePtr rootnode) +{ +char *xpath; +size_t i; +int num, ret = -1; +xmlNodePtr *nodes = NULL; + +/* Find storage volumes */ +if (virAsprintf(xpath, %s/domainsnapshot, xmlGetNodePath(rootnode)) 0) +goto error; + +num = virXPathNodeSet(xpath, ctxt, nodes); +VIR_FREE(xpath); +if (num 0) { +goto error; +} + +for (i = 0; i num; i++) { +virDomainSnapshotObjPtr snap; +virDomainSnapshotDefPtr def; +xmlNodePtr node = testParseXMLDocFromFile(nodes[i], file, + domainsnapshot); +if (!node) +goto error; + +def = virDomainSnapshotDefParseNode(ctxt-doc, node, +privconn-caps, +privconn-xmlopt, +1 VIR_DOMAIN_VIRT_TEST, +VIR_DOMAIN_SNAPSHOT_PARSE_DISKS | +VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL | + VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE); +if (!def) +goto error; + +if (!(snap = virDomainSnapshotAssignDef(domobj-snapshots, def))) { +virDomainSnapshotDefFree(def); +goto error; +} + +if (def-current) { +if (domobj-current_snapshot) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(more than one snapshot claims to be active)); +goto error; +} + +domobj-current_snapshot = snap; +} +} + +ret = 0; +error: +VIR_FREE(nodes); +return ret; +} + +static int testParseDomains(testConnPtr privconn, const char *file, xmlXPathContextPtr ctxt) @@ -976,6 +1038,11 @@ testParseDomains(testConnPtr privconn, goto error; } +if (testParseDomainSnapshots(privconn, obj, file, ctxt, node) 0) { +virObjectUnlock(obj); +goto error; +} + obj-persistent = !transient; if (runstate != VIR_DOMAIN_SHUTOFF) { if (testDomainStartState(privconn, obj, -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] rhel 5 'make check' failure
I ran out of time to investigate today, in case someone wants to beat me to a fix: virsystemdmock.c: In function 'dbus_connection_send_with_reply_and_block': virsystemdmod.c:68: warning: implicit declaration of function 'dbus_message_set_serial' this failure occurred on RHEL 5; dbus-devel-1.1.2-20.el5. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/6] virsh: Print cephx and iscsi usage
When using virsh secret-list - if the secret types are cephx or iscsi, then allow fetch/print of the usage information. Prior to the change the following would print: UUID Usage --- 1b40a534-8301-45d5-b1aa-11894ebb1735 Unused a5ba3efe-6adf-4a6a-b243-f010a043e314 Unused Afterwards: UUID Usage --- 1b40a534-8301-45d5-b1aa-11894ebb1735 ceph ceph_example a5ba3efe-6adf-4a6a-b243-f010a043e314 iscsi libvirtiscsi --- tools/virsh-secret.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c index 9d34c1a..30027fe 100644 --- a/tools/virsh-secret.c +++ b/tools/virsh-secret.c @@ -38,6 +38,7 @@ #include virfile.h #include virutil.h #include virxml.h +#include conf/secret_conf.h static virSecretPtr vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name) @@ -536,23 +537,19 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) for (i = 0; i list-nsecrets; i++) { virSecretPtr sec = list-secrets[i]; -const char *usageType = NULL; - -switch (virSecretGetUsageType(sec)) { -case VIR_SECRET_USAGE_TYPE_VOLUME: -usageType = _(Volume); -break; -} - +int usageType = virSecretGetUsageType(sec); +const char *usageStr = virSecretUsageTypeTypeToString(usageType); char uuid[VIR_UUID_STRING_BUFLEN]; + if (virSecretGetUUIDString(list-secrets[i], uuid) 0) { vshError(ctl, %s, _(Failed to get uuid of secret)); goto cleanup; } -if (usageType) { +if (usageType VIR_SECRET_USAGE_TYPE_NONE +usageType VIR_SECRET_USAGE_TYPE_LAST) { vshPrint(ctl, %-36s %s %s\n, - uuid, usageType, + uuid, usageStr, virSecretGetUsageID(sec)); } else { vshPrint(ctl, %-36s %s\n, -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/6] Additional iSCSI/chap changes
These patches address a couple of issues I ran into while doing extra testing on the iSCSI chap authentication patches: https://www.redhat.com/archives/libvir-list/2013-July/msg01378.html The first 2 or 3 patches should be candidiates to be put into rhel7.0 as updates/fixes to issues. The last 3 patches update the documentation to show how to use secrets, pools, and iSCIS devices in the domain. John Ferlan (6): virsh: Print cephx and iscsi usage qemu_conf: Fix broken logic for adding passthrough iscsi lun Report secret usage error message similarly docs: Update the formatdomain disk examples docs: Update formatsecrets to include more examples of each type docs: Update iSCSI storage pool example docs/formatdomain.html.in | 57 +++-- docs/formatsecret.html.in | 156 +--- docs/formatstorage.html.in | 5 +- src/qemu/qemu_command.c | 28 +-- src/qemu/qemu_conf.c| 2 +- src/storage/storage_backend_iscsi.c | 28 +-- src/storage/storage_backend_rbd.c | 35 ++-- tools/virsh-secret.c| 17 ++-- 8 files changed, 278 insertions(+), 50 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/6] docs: Update the formatdomain disk examples
Add more iSCSI examples including having a secret attached. There are 4 new examples one for each way to have an iSCSI - a network disk using virtio, a passthrough network lun using scsi, a volume disk using mode='host', and a volume disk using mode='direct' --- docs/formatdomain.html.in | 57 --- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index dd22b6d..01253ef 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1514,6 +1514,42 @@ lt;source pool='blk-pool0' volume='blk-pool0-vol0'/gt; lt;target dev='hda' bus='ide'/gt; lt;/diskgt; +lt;disk type='network' device='disk'gt; + lt;driver name='qemu' type='raw'/gt; + lt;source protocol='iscsi' name='iqn.2013-06.com.example:iscsi/2'gt; +lt;host name='example.com' port='3260'/gt; + lt;sourcegt; + lt;auth username='myuser'gt; +lt;secret type='chap' usage='libvirtiscsi'/gt; + lt;/authgt; + lt;target dev='vda' bus='virtio'/gt; +lt;/diskgt; +lt;disk type='network' device='lun'gt; + lt;driver name='qemu' type='raw'/gt; + lt;source protocol='iscsi' name='iqn.2013-06.com.example:iscsi/1'gt; +lt;host name='example.com' port='3260'/gt; + lt;sourcegt; + lt;auth username='myuser'gt; +lt;secret type='chap' usage='libvirtiscsi'/gt; + lt;/authgt; + lt;target dev='sda' bus='scsi'/gt; +lt;/diskgt; +lt;disk type='volume' device='disk'gt; + lt;driver name='qemu' type='raw'/gt; + lt;source pool='iscsi-pool' volume='unit:0:0:1' mode='host'/gt; + lt;auth username='myuser'gt; +lt;secret type='chap' usage='libvirtiscsi'/gt; + lt;/authgt; + lt;target dev='vda' bus='virtio'/gt; +lt;/diskgt; +lt;disk type='volume' device='disk'gt; + lt;driver name='qemu' type='raw'/gt; + lt;source pool='iscsi-pool' volume='unit:0:0:2' mode='direct'/gt; + lt;auth username='myuser'gt; +lt;secret type='chap' usage='libvirtiscsi'/gt; + lt;/authgt; + lt;target dev='vda' bus='virtio'/gt; +lt;/diskgt; lt;/devicesgt; .../pre @@ -1602,15 +1638,20 @@ specifies the name of storage pool (managed by libvirt) where the disk source resides, and attribute codevolume/code specifies the name of storage volume (managed by libvirt) used as the disk source. For a -volume type disk, if the underlying storage pool is iscsi, attribute -codemode/code (span class=sincesince 1.1.1/span) can be used -to indicate how to represent the LUN as the disk source. The value -host indicates to use the LUN's path as it shows up on host, e.g. - /dev/disk/by-path/ip-10.11.12.9:3260-iscsi-iqn.2013-06.fc:iscsi.iscsi0-lun-1). -The value direct indicates to use the storage pool's -codesource/code element codehost/code attribute as the -disk source for the libiscsi URI, e.g. +volume codetype/code disk, if the underlying storage pool is +iscsi, then use the output of the value from the Name column of +the codevirsh vol-list [pool-name]/code command for the +codevolume/code attribute field. Use the attribute +codemode/code (span class=sincesince 1.1.1/span) to +indicate how to represent the LUN as the disk source. +Using direct as the codemode/code value indicates to use the +storage pool's codesource/code element codehost/code +attribute as the disk source to generate the libiscsi URI, e.g. file=iscsi://demo.org:6000/iqn.1992-01.com.example/1. +Using host as the codemode/code value indicates to use the +LUN's path as it shows up on host, e.g. + /dev/disk/by-path/ip-10.11.12.9:3260-iscsi-iqn.2013-06.fc:iscsi.iscsi0-lun-1). +If codemode/code is not specified, the default is to use host. span class=sinceSince 0.0.3; codetype='dir'/code since 0.7.5; codetype='network'/code since 0.8.7; codeprotocol='iscsi'/code since 1.0.4; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/6] qemu_conf: Fix broken logic for adding passthrough iscsi lun
Following XML would fail : disk type='network' device='lun' driver name='qemu' type='raw'/ source protocol='iscsi' name='iqn.2013-07.com.example:iscsi/1' host name='example.com' port='3260'/ /source target dev='sda' bus='scsi'/ /disk With the message: error: Failed to start domain iscsilun error: Unable to get device ID 'iqn.2013-07.com.example:iscsi/1': No such file or directory Cause was commit id '1f49b05a' which added 'virDomainDiskSourceIsBlockType' --- src/qemu/qemu_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 18e926c..86ed9ed 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1065,7 +1065,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) disk = dev-data.disk; if (disk-device != VIR_DOMAIN_DISK_DEVICE_LUN || -virDomainDiskSourceIsBlockType(disk)) +!virDomainDiskSourceIsBlockType(disk)) return 0; path = disk-src; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/6] Report secret usage error message similarly
Each of the modules handled reporting error messages from the secret fetching slightly differently with respect to the error. Provide a similar message for each error case and provide as much data as possible. --- src/qemu/qemu_command.c | 28 ++-- src/storage/storage_backend_iscsi.c | 28 ++-- src/storage/storage_backend_rbd.c | 35 --- 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b811e1d..24e891b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3043,18 +3043,34 @@ qemuGetSecretString(virConnectPtr conn, } if (!sec) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _(%s username '%s' specified but secret not found), - scheme, username); +if (diskSecretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) { +virReportError(VIR_ERR_NO_SECRET, + _(%s username '%s' specified but secret for + uuid '%s' not found), + scheme, username, uuid); +} else { +virReportError(VIR_ERR_NO_SECRET, + _(%s username '%s' specified but secret for + usage value '%s' not found), + scheme, username, usage); +} goto cleanup; } secret = (char *)conn-secretDriver-secretGetValue(sec, secret_size, 0, VIR_SECRET_GET_VALUE_INTERNAL_CALL); if (!secret) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _(could not get value of the secret for username %s), - username); +if (diskSecretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(could not get value of the secret for + username '%s' using uuid '%s'), + username, uuid); +} else { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(could not get value of the secret for + username '%s' using usage value '%s'), + username, usage); +} goto cleanup; } diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index ee8dd2e..55bf544 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -732,15 +732,31 @@ virStorageBackendISCSISetAuth(const char *portal, conn-secretDriver-secretGetValue(secret, secret_size, 0, VIR_SECRET_GET_VALUE_INTERNAL_CALL); if (!secret_value) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _(could not get the value of the secret - for username %s), chap.username); +if (chap.secret.uuidUsable) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(could not get the value of the secret + for username %s using uuid '%s'), + chap.username, chap.secret.uuid); +} else { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(could not get the value of the secret + for username %s using usage value '%s'), + chap.username, chap.secret.usage); +} goto cleanup; } } else { -virReportError(VIR_ERR_INTERNAL_ERROR, - _(username '%s' specified but secret not found), - chap.username); +if (chap.secret.uuidUsable) { +virReportError(VIR_ERR_NO_SECRET, + _(username '%s' specified but the secret for + uuid '%s' not found), + chap.username, chap.secret.uuid); +} else { +virReportError(VIR_ERR_NO_SECRET, + _(username '%s' specified but the secret for + usage value '%s' not found), + chap.username, chap.secret.usage); +} goto cleanup; } diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index e3340f6..9c6d179 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -91,19 +91,40 @@ static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr *ptr, } if (secret == NULL) { -virReportError(VIR_ERR_NO_SECRET, %s, - _(failed to find the secret)); +if (pool-def-source.auth.cephx.secret.uuidUsable) { +
[libvirt] [PATCH 6/6] docs: Update iSCSI storage pool example
Update the iSCSI storage pool example to include the secret --- docs/formatstorage.html.in | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index f4d561f..278f89b 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -480,7 +480,10 @@ lt;namegt;virtimageslt;/namegt; lt;sourcegt; lt;host name=iscsi.example.com/gt; - lt;device path=demo-target/gt; + lt;device path=iqn.2013-06.com.example:iscsi-pool/gt; + lt;auth type='chap' username='myuser'gt; +lt;secret usage='libvirtiscsi'/gt; + lt;/authgt; lt;/sourcegt; lt;targetgt; lt;pathgt;/dev/disk/by-pathlt;/pathgt; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/6] docs: Update formatsecrets to include more examples of each type
Update formatsecret docs to describe the various options and provide examples in order to set up secrets for each type of secret. --- docs/formatsecret.html.in | 156 ++ 1 file changed, 145 insertions(+), 11 deletions(-) diff --git a/docs/formatsecret.html.in b/docs/formatsecret.html.in index 3e306b5..7dd0927 100644 --- a/docs/formatsecret.html.in +++ b/docs/formatsecret.html.in @@ -46,18 +46,51 @@ /dd /dl -h3Usage type volume/h3 +h3a name=VolumeUsageTypeUsage type volume/a/h3 p This secret is associated with a volume, and it is safe to delete the secret after the volume is deleted. The codelt;usage type='volume'gt;/code element must contain a single codevolume/code element that specifies the key of the volume - this secret is associated with. + this secret is associated with. For example, create a demo-secret.xml + file as follows: /p -h3Usage type ceph/h3 +pre + lt;secret ephemeral='no' private='yes'gt; + lt;descriptiongt;LUKS passphrase for the main hard drive of our mail serverlt;/descriptiongt; + lt;uuidgt;0a81f5b2-8403-7b23-c8d6-21ccc2f80d6flt;/uuidgt; + lt;usage type='volume'gt; +lt;volumegt;/var/lib/libvirt/images/mail.imglt;/volumegt; + lt;/usagegt; + lt;/secretgt; +/pre + +p + Define the secret and set the pass phrase as follows: +/p +pre + # virsh secret-define demo-secret.xml + Secret 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f created + # + # MYSECRET=`printf %s open seseme | base64` + # virsh secret-set-value 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f $MYSECRET + Secret value set + # +/pre + +p + The volume can then be used in the XML for a disk volume + a href=formatstorageencryption.htmlencryption/a as follows: +/p +pre + lt;encryption format='qcow'gt; +lt;secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/gt; + lt;/encryptiongt; +/pre +h3a name=CephUsageTypeUsage type ceph/a/h3 p This secret is associated with a Ceph RBD (rados block device). The codelt;usage type='ceph'gt;/code element must contain @@ -66,10 +99,57 @@ this usage name via the codelt;authgt;/code element of a a href=formatdomain.html#elementsDisksdisk device/a or a a href=formatstorage.htmlstorage pool (rbd)/a. - span class=sinceSince 0.9.7/span. + span class=sinceSince 0.9.7/span. The following is an example + of the steps to be taken. First create a ceph-secret.xml file: +/p + +pre + lt;secret ephemeral='no' private='yes'gt; + lt;descriptiongt;CEPH passphrase examplelt;/descriptiongt; + lt;auth type='ceph' username='myname'/gt; + lt;usage type='ceph'gt; +lt;namegt;ceph_examplelt;/namegt; + lt;/usagegt; + lt;/secretgt; +/pre + +p + Next, use codevirsh secret-define ceph-secret.xml/code to define + the secret and codevirsh secret-set-value/code using the generated + UUID value and a base64 generated secret value in order to define the + chosen secret pass phrase. /p +pre + # virsh secret-define ceph-secret.xml + Secret 1b40a534-8301-45d5-b1aa-11894ebb1735 created + # + # virsh secret-list + UUID Usage + --- + 1b40a534-8301-45d5-b1aa-11894ebb1735 cephx ceph_example + # + # CEPHPHRASE=`printf %s pass phrase | base64` + # virsh secret-set-value 1b40a534-8301-45d5-b1aa-11894ebb1735 $CEPHPHRASE + Secret value set -h3Usage type iscsi/h3 + # +/pre + +p + The ceph secret can then be used by UUID or by the + usage name via the codelt;authgt;/code element in a + domain's codelt;diskgt;/code element as follows: +/p +pre + lt;source protocol='rbd' name='pool/image'gt; +lt;host name='mon1.example.org' port='6321'/gt; + lt;/sourcegt; + lt;auth username='myname'gt; +lt;secret type='ceph' usage='ceph_example'/gt; + lt;/authgt; +/pre + +h3a name=iSCSIUsageTypeUsage type iscsi/a/h3 p This secret is associated with an iSCSI target for CHAP authentication. @@ -82,14 +162,68 @@ span class=sinceSince 1.0.4/span. /p -h2a name=exampleExample/a/h2 - +p + The following is an example of the XML that may be used to generate + a secret for iSCSI CHAP authentication. First define an iscsi-secret.xml + file to describe the secret. Replace the codeusername/code field + with the username used in your iSCSI authentication configuration file. + The description field should contain configuration specific data. + The codetarget/code name may be any name of your choosing to + be used as the codeusage/code when used
[libvirt] [libvirt-sandbox][PATCH] Update man page about virt-sandbox-service
Add upgrade and remove start,stop,list --- bin/virt-sandbox-service.pod |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service.pod b/bin/virt-sandbox-service.pod index 32caad9..e8ab55e 100644 --- a/bin/virt-sandbox-service.pod +++ b/bin/virt-sandbox-service.pod @@ -4,7 +4,7 @@ virt-sandbox-service - Secure container tool =head1 SYNOPSIS - {create,clone,connect,delete,execute,list,reload,start,stop} + {create,clone,connect,delete,execute,reload,upgrade} commands: @@ -20,6 +20,8 @@ virt-sandbox-service - Secure container tool reload Reload a running sandbox container +upgrade Upgrade an existing Secure container + =head1 DESCRIPTION virt-sandbox-service is used to provision secure sandboxed system services. @@ -52,7 +54,7 @@ supported currently). =head1 SEE ALSO -Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1) +Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1), Cvirt-sandbox-service-upgrade(1) =head1 FILES -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-sandbox][PATCH] Update man page about virt-sandbox-service
On 08/08/2013 10:42 AM, Zhe Peng wrote: Add upgrade and remove start,stop,list --- bin/virt-sandbox-service.pod |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service.pod b/bin/virt-sandbox-service.pod index 32caad9..e8ab55e 100644 --- a/bin/virt-sandbox-service.pod +++ b/bin/virt-sandbox-service.pod @@ -4,7 +4,7 @@ virt-sandbox-service - Secure container tool =head1 SYNOPSIS - {create,clone,connect,delete,execute,list,reload,start,stop} + {create,clone,connect,delete,execute,reload,upgrade} commands: @@ -20,6 +20,8 @@ virt-sandbox-service - Secure container tool reload Reload a running sandbox container +upgrade Upgrade an existing Secure container s/Secure/sandbox/, to keep consistent with above contents. + =head1 DESCRIPTION virt-sandbox-service is used to provision secure sandboxed system services. @@ -52,7 +54,7 @@ supported currently). =head1 SEE ALSO -Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1) +Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1), Cvirt-sandbox-service-upgrade(1) =head1 FILES -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-sandbox][PATCH v2] Update man page about virt-sandbox-service
Add upgrade and remove start,stop,list --- bin/virt-sandbox-service.pod |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service.pod b/bin/virt-sandbox-service.pod index 32caad9..7752145 100644 --- a/bin/virt-sandbox-service.pod +++ b/bin/virt-sandbox-service.pod @@ -4,7 +4,7 @@ virt-sandbox-service - Secure container tool =head1 SYNOPSIS - {create,clone,connect,delete,execute,list,reload,start,stop} + {create,clone,connect,delete,execute,reload,upgrade} commands: @@ -20,6 +20,8 @@ virt-sandbox-service - Secure container tool reload Reload a running sandbox container +upgrade Upgrade an existing sandbox container + =head1 DESCRIPTION virt-sandbox-service is used to provision secure sandboxed system services. @@ -52,7 +54,7 @@ supported currently). =head1 SEE ALSO -Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1) +Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1), Cvirt-sandbox-service-upgrade(1) =head1 FILES -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-sandbox][PATCH v2] Update man page about virt-sandbox-service
On 08/08/2013 11:31 AM, Zhe Peng wrote: Add upgrade and remove start,stop,list ACK and pushed with comment update Remove obsolete 'list', 'start', 'stop' commands and add new 'upgrade' command. --- bin/virt-sandbox-service.pod |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/virt-sandbox-service.pod b/bin/virt-sandbox-service.pod index 32caad9..7752145 100644 --- a/bin/virt-sandbox-service.pod +++ b/bin/virt-sandbox-service.pod @@ -4,7 +4,7 @@ virt-sandbox-service - Secure container tool =head1 SYNOPSIS - {create,clone,connect,delete,execute,list,reload,start,stop} + {create,clone,connect,delete,execute,reload,upgrade} commands: @@ -20,6 +20,8 @@ virt-sandbox-service - Secure container tool reload Reload a running sandbox container +upgrade Upgrade an existing sandbox container + =head1 DESCRIPTION virt-sandbox-service is used to provision secure sandboxed system services. @@ -52,7 +54,7 @@ supported currently). =head1 SEE ALSO -Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1) +Clibvirt(8), Cselinux(8), Csystemd(8), Cvirt-sandbox(1), Cvirt-sandbox-service-create(1), Cvirt-sandbox-service-clone(1), Cvirt-sandbox-service-connect(1), Cvirt-sandbox-service-delete(1), Cvirt-sandbox-service-execute(1), Cvirt-sandbox-service-reload(1), Cvirt-sandbox-service-upgrade(1) =head1 FILES -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] virDomainCreateWithFlags error
Hi all, I'm using 'libvirt 1.1.1-1 amd64' undef debian wheezy, I found that the return code is 139 when I run command: $ sudo virsh start df1c4670-18eb-4520-b5d8-aa8a492eb876 --paused; echo $? 139 but the return code is OK(0) when run command: $ sudo virsh start df1c4670-18eb-4520-b5d8-aa8a492eb876; echo $? I found there is an error in libvirtd.log: 2013-08-08 05:40:23.983+: 16626: error : virNetSocketReadWire:1377 : End of file while reading data: Input/output error I found this issue by using openstack nova folsom, if I create an VM by nova, it will use dom.createWithFlags(0) to create the VM, but then the nova-compute process exited when this function is called, then I changed the createWithFlags(0) to create(), everything become OK. I also tried the function under python, and the python process exited, too. but the dom.create() method is OK, so I think this is a problem about libvirt. I want to know is this a reported bug? libvirt and kvm hypervisor version: Compiled against library: libvirt 1.1.1 Using library: libvirt 1.1.1 Using API: QEMU 1.1.1 Running hypervisor: QEMU 1.1.2 Thanks 2012-08-16 Wangpan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list