Without the following patch, this command would hang
printf 'domuuid fc4\ndomstate fc4\n' \
| ./virsh --connect test://$PWD/../docs/testnode.xml
with this stack trace:
__lll_lock_wait ...
_L_lock_105 ...
__pthread_mutex_lock ...
virUnrefDomain (domain=0x6a8b30) at hash.c:884
virDomainFree (domain=0x6a8b30) at libvirt.c:1211
cmdDomstate (ctl=0x7fffea723390, cmd=0x6a8b10) at virsh.c:677
vshCommandRun (ctl=0x7fffea723390, cmd=0x6a8b10) at virsh.c:4033
main (argc=3, argv=0x7fffea7234e8) at virsh.c:5015
The problem is that cmdDomuuid didn't call virDomainFree(dom), so
cmdDomstate hangs trying to do the Unref.
I then did a mind-numbing audit of all of the other cmd* functions in
virsh.c and found two other cases in which a "dom" may not be released.
Here's the patch:
Avoid virsh hang due to missing virDomainFree(dom) calls
* src/virsh.c (cmdDomuuid): Add missing virDomainFree call.
(cmdAttachDevice): Likewise.
(cmdDetachDevice): Likewise.
---
src/virsh.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/virsh.c b/src/virsh.c
index 0d93fb6..487f256 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -2161,6 +2161,7 @@ cmdDomuuid(vshControl * ctl, vshCmd * cmd)
else
vshError(ctl, FALSE, "%s", _("failed to get domain UUID"));
+ virDomainFree(dom);
return TRUE;
}
@@ -3038,8 +3039,10 @@ cmdAttachDevice(vshControl * ctl, vshCmd * cmd)
return FALSE;
}
- if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
+ if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
+ virDomainFree(dom);
return FALSE;
+ }
ret = virDomainAttachDevice(dom, buffer);
free (buffer);
@@ -3092,8 +3095,10 @@ cmdDetachDevice(vshControl * ctl, vshCmd * cmd)
return FALSE;
}
- if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
+ if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
+ virDomainFree(dom);
return FALSE;
+ }
ret = virDomainDetachDevice(dom, buffer);
free (buffer);
--
1.5.4.rc5.1.g0fa73