I am trying to use /etc/libvirt/hooks/qemu to control the startup of several 
guests with interdependencies.  The goal is to delay the start of guest B until 
the DNS server on guest A is running.  To accomplish this, I wrote a qemu hook 
script that detects the normal startup of guest B and start a second script in 
the background to wait until the preconditions to start B are fulfilled, then 
start B using a call to the virsh command.

For this strategy to work, it must handle the case where libvirt has chosen 
guest B as the first guest to attempt to start.  (Although renaming the 
symlinks in /etc/libvirt/qemu/autostart to force starting the guests in a 
particular order might work, I do not want to rely on this undocumented 
behavior).  In the case where libvirt happens to attempt to start guest B 
before it starts guest A, the hook script needs to somehow tell libvirt to skip 
guest B and go on to starting the next guest.  Otherwise a deadlock would 
result as libvirt waited for B to start, but B was waiting for A to start.   I 
have tried to handle this by returning failure from the hook script for the 
initial attempt to start B once the background script has been started to 
implement the DNS check and eventually the delayed start of B.

Unfortunately, I cannot find a way to force libvirt to continue until the 
background script exits.  No combination of background execution, nohup, 
disown, setsid -f, or at seems to detach the process sufficiently to "fool" 
libvirt into acting on the "exit 1" line in the qemu script and proceed on to 
start other guests.  As a result, the dependency of B on A deadlocks, and 
neither guest ever starts.

Can someone please either find an error in my approach or propose a different 
strategy to implement this customized dependency of the startup of one guest on 
another?

Thanks -

======

Here is my qemu script:

#!/bin/bash
if [[ "$2" == 'start' ]]; then
        echo "$0: Starting $1..." |& logger
        if [[ "$1" == 'B' ]]; then
            # The next line is where the background script is invoked
                /bin/bash /usr/local/bin/startB &
            # These also don't work:
            # (/bin/bash /usr/local/bin/startB) & ; disown
# setsid -f (/bin/bash /usr/local/bin/startB) & ; disown
            # Unfortunately, the exit in the following line doesn't force 
libvirt to move on to the next guest to start until the background command has 
itself exited
                exit 1;
        fi
fi

Here is the startB script, including a call to a program named in the 
$dnssuccess variable that does the testing of DNS availability on guest A:

#!/bin/bash
until $dnssuccess
do
    echo "$0: Delaying start of guest B 10 seconds" |& logger
    sleep 10;
done
# It's now OK to start guest
echo "$0: Now starting guest B" |& logger
virsh start B;

=====
_______________________________________________
libvirt-users mailing list
libvirt-users@redhat.com
https://www.redhat.com/mailman/listinfo/libvirt-users

Reply via email to