I spent a while chasing an issue where running 'virsh destroy foo' on an HVM domain would result in an error being returned by the HV ioctl. What I eventually discovered is that the code was doing a destroy op via XenD and then also doing it via the hypervisor backend. It didn't typically show as a problem for PV domains because it seems they took longer to destroy - so were still around by the time the HV destroy was was called. I tracked this issue down to the main dispatch methods in src/libvirt.c which would indeed call both the XenD and HV driver backends for pause destroy & shutdown methods. The patch attached simply returns as soon as one of the driver methods returns a success return code. Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
diff -c -b -r1.41 libvirt.c *** src/libvirt.c 9 Aug 2006 15:21:16 -0000 1.41 --- src/libvirt.c 9 Aug 2006 22:58:47 -0000 *************** *** 720,726 **** int virDomainDestroy(virDomainPtr domain) { ! int ret = -1, i; virConnectPtr conn; if (!VIR_IS_CONNECTED_DOMAIN(domain)) { --- 720,726 ---- int virDomainDestroy(virDomainPtr domain) { ! int i; virConnectPtr conn; if (!VIR_IS_CONNECTED_DOMAIN(domain)) { *************** *** 743,749 **** (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainDestroy != NULL)) { if (conn->drivers[i]->domainDestroy(domain) == 0) ! ret = 0; } } for (i = 0;i < conn->nb_drivers;i++) { --- 743,749 ---- (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainDestroy != NULL)) { if (conn->drivers[i]->domainDestroy(domain) == 0) ! return (0); } } for (i = 0;i < conn->nb_drivers;i++) { *************** *** 751,766 **** (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainDestroy != NULL)) { if (conn->drivers[i]->domainDestroy(domain) == 0) ! ret = 0; } } - if (ret != 0) { virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__); ! return (ret); ! } ! ! return (ret); } /** --- 751,762 ---- (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainDestroy != NULL)) { if (conn->drivers[i]->domainDestroy(domain) == 0) ! return (0); } } virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__); ! return (-1); } /** *************** *** 799,805 **** int virDomainSuspend(virDomainPtr domain) { ! int ret = -1, i; virConnectPtr conn; if (!VIR_IS_CONNECTED_DOMAIN(domain)) { --- 795,801 ---- int virDomainSuspend(virDomainPtr domain) { ! int i; virConnectPtr conn; if (!VIR_IS_CONNECTED_DOMAIN(domain)) { *************** *** 822,828 **** (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainSuspend != NULL)) { if (conn->drivers[i]->domainSuspend(domain) == 0) ! ret = 0; } } for (i = 0;i < conn->nb_drivers;i++) { --- 818,824 ---- (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainSuspend != NULL)) { if (conn->drivers[i]->domainSuspend(domain) == 0) ! return (0); } } for (i = 0;i < conn->nb_drivers;i++) { *************** *** 830,845 **** (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainSuspend != NULL)) { if (conn->drivers[i]->domainSuspend(domain) == 0) ! ret = 0; } } - if (ret != 0) { virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__); ! return (ret); ! } ! ! return (ret); } /** --- 826,837 ---- (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) && (conn->drivers[i]->domainSuspend != NULL)) { if (conn->drivers[i]->domainSuspend(domain) == 0) ! return (0); } } virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__); ! return (-1); } /**