2017-03-14 11:23+0100, Thomas Huth: > To be able to do simple migration tests with kvm-unit-tests, too, > add a helper script that does all the necessary work: Start two > instances of QEMU (source and destination) with QMP sockets for > sending commands to them, then trigger the migration from one > instance to the other and finally signal the end of the migration > to the guest by injecting an NMI. > This helper script is now used automatically for powerpc tests > if the test is put into the "migration" group in the unittests.cfg > file. > > Signed-off-by: Thomas Huth <thuth@xxxxxxxxxx> > --- > powerpc/run | 4 +++ > scripts/qemu-migration-helper.sh | 68 ++++++++++++++++++++++++++++++++++++++++ > scripts/runtime.bash | 3 ++ > 3 files changed, 75 insertions(+) > create mode 100755 scripts/qemu-migration-helper.sh > > diff --git a/powerpc/run b/powerpc/run > index 6269abb..f1528ed 100755 > --- a/powerpc/run > +++ b/powerpc/run > @@ -41,6 +41,10 @@ if ! $qemu -machine '?' 2>&1 | grep 'pseries' > /dev/null; then > exit 2 > fi > > +if [ "$MIGRATION" = "yes" ]; then > + qemu="scripts/qemu-migration-helper.sh $qemu" > +fi I think this script could be useful for other architectures as well ... what about adding migration_cmd to scripts/arch-run.bash migration_cmd () { if [ "$MIGRATION" = "yes" ]; then echo "scripts/qemu-migration-helper.sh" fi } and using only command="$(timeout_cmd) $(migration_cmd) $command" in arch scripts? > + > M='-machine pseries' > M+=",accel=$ACCEL" > command="$qemu -nodefaults $M -bios $FIRMWARE" > diff --git a/scripts/qemu-migration-helper.sh b/scripts/qemu-migration-helper.sh > new file mode 100755 > index 0000000..5842026 > --- /dev/null > +++ b/scripts/qemu-migration-helper.sh This doesn't seem to work with standalone tests, because they don't bundle scripts/qemu-migration-helper.sh ... Any reason why we couldn't turn it into a qemu-migration-helper () { ... } wrapper (likely inside scripts/arch-run.bash), so it would get sourced into the standalone test? > @@ -0,0 +1,68 @@ > +#!/bin/bash > +# This script runs two instances of QEMU and then migrates the guest from one > +# instance to the other. The end of the migration is signalled to the guest by > +# injecting an NMI. > + > +if ! command -v nc >/dev/null 2>&1; then > + echo "$0 needs nc (netcat)" > + exit 1 > +fi > + > +qemu=$1 > +shift > + > +if ! command -v "$qemu" >/dev/null 2>&1; then > + echo "The first parameter must be pointing to the QEMU executable" > + exit 1 > +fi > + > +migsock=`mktemp -u -t mig-helper-socket.XXXXXXXXXX` > +stdout1=`mktemp -t mig-helper-stdout1.XXXXXXXXXX` > +stdout2=`mktemp -t mig-helper-stdout2.XXXXXXXXXX` > +qmpout1=`mktemp -t mig-helper-qmpout1.XXXXXXXXXX` > +qmpout2=`mktemp -t mig-helper-qmpout2.XXXXXXXXXX` > +qmp1=`mktemp -u -t mig-helper-qmp1.XXXXXXXXXX` > +qmp2=`mktemp -u -t mig-helper-qmp2.XXXXXXXXXX` > + > +cleanup() > +{ > + rm -f ${stdout1} ${stdout2} ${migsock} > + rm -f ${qmpout1} ${qmpout2} ${qmp1} ${qmp2} > +} > +trap cleanup EXIT > + > +qmp_cmd() > +{ > + echo '{ "execute": "qmp_capabilities" }{ "execute":' "$2" '}' | nc -U $1 > +} > + > +$qemu $* -chardev socket,id=mon1,path=${qmp1},server,nowait \ I have a bad feeling about $*, please use "$@" instead. The difference can be seen in: # f () { g $*; } # g () {echo $#; } # f 1 2; f "1 2" 2 2 # f () { g "$@"; } # f 1 2; f "1 2" 2 1 > + -mon chardev=mon1,mode=control > ${stdout1} & > + > +$qemu $* -chardev socket,id=mon2,path=${qmp2},server,nowait \ > + -mon chardev=mon2,mode=control -incoming unix:${migsock} > ${stdout2} & > + > +# The test must prompt the user to migrate, so wait for the "migrate" keyword > +while ! grep -q -i "migrate" < ${stdout1} ; do > + sleep 1 > +done > + > +qmp_cmd ${qmp1} '"migrate", "arguments": { "uri": "unix:'${migsock}'" }' > ${qmpout1} > + > +# Wait for the migration to complete > +migstatus=`qmp_cmd ${qmp1} '"query-migrate"' | grep return` > +while ! grep -q '"completed"' <<<"$migstatus" ; do > + sleep 1 > + migstatus=`qmp_cmd ${qmp1} '"query-migrate"' | grep return` > + if grep -q '"failed"' <<<"$migstatus" ; then > + echo "ERROR: Migration failed." > + exit 1 > + fi > +done > +qmp_cmd ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null > + > +qmp_cmd ${qmp2} '"inject-nmi"'> ${qmpout2} qmpout* seems unused ... couldn't we just redirect to /dev/null? > + > +wait > + > +cat ${stdout1} ${stdout2} The test might hang and we would never see its output ... I think that stdout1 could be duplicated using a crazy technique similar to what run_qemu() uses. And do we need to capture stdout2 at all? Thanks.