Red Hat Bugzilla – Bug 1142693
[RFE] Add a qemu resume hook that is able to preprocess the domain XML
Last modified: 2015-03-05 02:44:41 EST
+++ This bug was initially created as a clone of Bug #1142684 +++ Description of problem: We would like to be able to preprocess the XML that is used when domain is resumed. It should work very similarly to how migrate hook does. Rationale: The min_guarantee change (ignore -> fail) affects long running VMs. We can workaround this by making sure the offending element is removed from the XML during migration or resume. Currently only migration destination allows us to do that, but if a VM is never migrated, then suspended and resumed on host with new enough libvirt - it will fail to start.
Added upstream: commit 4f3c2e39e5c898c533ddf58b62b452a674df794d Author: Peter Krempa <pkrempa@redhat.com> Date: Wed Sep 17 11:38:39 2014 +0200 qemu: hook: Provide hook when restoring a domain save image (and a few refactors before that). v1.2.8-218-g4f3c2e3
Hi Peter If add a qemu hook with empty output, it is failed to restore domain . But according to the following doc , The domain should be successfully restored. "Empty output is identical to copying the input XML without changing it." # cat /etc/libvirt/hooks/qemu #! /usr/bin/python import sys import os hooklog = '/tmp/hook.log' log = open(hooklog, 'w') def read_in(): lines = sys.stdin.readlines() for i in range(len(lines)): log.write(lines[i]) def main(): if sys.argv[1] == 'r7' and sys.argv[2] == 'restore': read_in() if __name__ == '__main__': main() # virsh start r7 Domain r7 started # virsh save r7 r7.save Domain r7 saved to r7.save [root@localhost images]# virsh restore r7.save error: Failed to restore domain from r7.save error: (domain_definition):1: Document is empty (null) ^ [root@localhost images]# cat /tmp/hook.log <domain type='kvm'> <name>r7</name> <uuid>1eff705e-a316-42f4-92c9-262d14322f72</uuid> <memory unit='KiB'>1048576</memory> <currentMemory unit='KiB'>1048576</currentMemory> <vcpu placement='static'>1</vcpu> ...... </domain>
Hmm, yes. Unfortunately the hook execution code returns a string buffer for the output even if the output was empty. The buffer needs to be checked for contents. I need to fix the issue upstream.
Fixed upstream with: commit e38677993734e9af3dbd0589e1cecd0b75f7e757 Author: Peter Krempa <pkrempa@redhat.com> Date: Wed Oct 22 11:22:08 2014 +0200 qemu: restore: Fix restoring of VM when the restore hook returns empty XML The documentation for the restore hook states that returning an empty XML is equivalent with copying the input. There was a bug in the code checking the returned string by checking the string instead of the contents. Use the new helper to check if the string is empty. commit 0eeafeedebe4469fce33d7942551957853856619 Author: Peter Krempa <pkrempa@redhat.com> Date: Wed Oct 22 10:26:42 2014 +0200 util: string: Add helper to check whether string is empty The helper checks whether a string contains only whitespace or is NULL. This will be helpful to skip cases where a user string is optional, but may be provided empty with the same meaning.
Verify it as follows. 1. Test a qemu hook with empty output # rpm -q libvirt libvirt-1.2.8-6.el7.x86_64 # cat /etc/libvirt/hooks/qemu #! /bin/bash if [ $1 = r7 -a $2 = restore ]; then echo "$0" "$@" >> /tmp/qemu.log fi exit 0 # virsh start r7 Domain r7 started # cat /tmp/qemu.log # virsh save r7 r7.save Domain r7 saved to r7.save # virsh restore r7.save Domain restored from r7.save # cat /tmp/qemu.log /etc/libvirt/hooks/qemu r7 restore begin - ============================================================================= 2. Test a qemu hook for modifying boot order when restoring a domain # cat /etc/libvirt/hooks/qemu #! /usr/bin/python import sys def input_xml(): xml = "" lines = sys.stdin.readlines() xml = "".join(lines) xml = xml.replace("<source file='/var/lib/libvirt/images/r7.img'/>\n" , "<source file='/r7.img'/>\n") sys.stdout.write(xml) def main(): if sys.argv[1] == 'r7' and sys.argv[2] == 'restore': input_xml() if __name__ == '__main__': main() # virsh list Id Name State ---------------------------------------------------- 5 r7 running # virsh save r7 r7.save Domain r7 saved to r7.save # virsh dumpxml r7|grep 'source file' <source file='/var/lib/libvirt/images/r7.img'/> # cp /var/lib/libvirt/images/r7.img /r7.img # virsh restore r7.save Domain restored from r7.save # virsh dumpxml r7|grep 'source file' <source file='/r7.img'/>
> > 2. Test a qemu hook for modifying boot order when restoring a domain Sorry. the scenario2 is actually modifying disk path when restoring a domain. The result in Comment 10 is expected.
Add a verification for restoring a managed save domain. 1. Test a qemu hook with empty output when restoring managedsaved domain # cat /etc/libvirt/hooks/qemu #! /bin/bash if [ $1 = r7 -a $2 = restore ]; then echo "$0" "$@" >> /tmp/qemu.log fi exit 0 # virsh managedsave r7 Domain r7 state saved by libvirt # cat /tmp/qemu.log # virsh start r7 Domain r7 started # cat /tmp/qemu.log /etc/libvirt/hooks/qemu r7 restore begin - ================================================================================ 2. Test a qemu hook for modifying disk path when restoring a managedsaved domain # cat /etc/libvirt/hooks/qemu #! /usr/bin/python import sys def input_xml(): xml = "" lines = sys.stdin.readlines() xml = "".join(lines) xml = xml.replace("<source file='/var/lib/libvirt/images/r7.img'/>\n" , "<source file='/r7.img'/>\n") sys.stdout.write(xml) def main(): if sys.argv[1] == 'r7' and sys.argv[2] == 'restore': input_xml() if __name__ == '__main__': main() # virsh list Id Name State ---------------------------------------------------- 9 r7 running # virsh managedsave r7 Domain r7 state saved by libvirt # virsh dumpxml r7|grep 'source file' <source file='/var/lib/libvirt/images/r7.img'/> # cp /var/lib/libvirt/images/r7.img /r7.img # virsh start r7 Domain r7 started # virsh dumpxml r7|grep 'source file' <source file='/r7.img'/>
Hi Martin The resume and restore are different operations in libvirt. The restore hook only is called when restoring a saved image. It can't be called when resuming a suspended domain. Please review the following results. Is it your expected result ? # cat /etc/libvirt/hooks/qemu #! /bin/bash if [ $1 = r7 -a $2 = restore ]; then echo "$0" "$@" >> /tmp/qemu.log fi exit 0 # virsh save r7 r7.save Domain r7 saved to r7.save # virsh restore r7.save Domain restored from r7.save # cat /tmp/qemu.log /etc/libvirt/hooks/qemu r7 restore begin - # > /tmp/qemu.log # virsh suspend r7 Domain r7 suspended # virsh resume r7 Domain r7 resumed # cat /tmp/qemu.log #
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHSA-2015-0323.html