<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
font-weight:normal;
font-style:normal;
text-decoration:none none;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:12.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Thanks –<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">======<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Here is my qemu script:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">#!/bin/bash<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">if [[ "$2" == 'start' ]]; then<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> echo "$0: Starting $1..." |& logger<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> if [[ "$1" == 'B' ]]; then<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> # The next line is where the background script is invoked<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> /bin/bash /usr/local/bin/startB &<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> # These also don’t work:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> # (/bin/bash /usr/local/bin/startB) & ; disown<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt"># setsid -f (/bin/bash /usr/local/bin/startB) & ; disown<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> # 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<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> exit 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> fi<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">fi<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">#!/bin/bash<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">until $dnssuccess<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">do<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> echo "$0: Delaying start of guest B 10 seconds" |& logger<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> sleep 10;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">done<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"># It’s now OK to start guest<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">echo "$0: Now starting guest B" |& logger<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">virsh start B;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">===== <o:p></o:p></span></p>
</div>
</body>
</html>