[Libvir] PATCH: Check for /usr/bin/qemu* binaries before starting guest

Richard W.M. Jones rjones at redhat.com
Mon Apr 16 10:49:38 UTC 2007


Daniel P. Berrange wrote:
> The attached patch fixes two issues
> 
>  - It explicitly checks to see if the requested /usr/bin/qemu* binary
>    actually exists before fork()/exec()'ing it. While its technically
>    possible to catch the execve() failure of ENOENT, its a real pain to
>    feed this error back to the qemu daemon because we're in a sub-process
>    at that point. The obvious & easy solution is to thus check to see if
>    the binary exists before trying to fork.

This is quite a hard problem to fix properly, as I'm sure you know.

If we were to change to use execvp, so making libvirt less dependent on 
the precise location of qemu binaries[1] then a complete test would also 
need to parse $PATH.

With SELinux an exec can fail for a lot more reasons than just lack of 
the binary or lack of execute bit.

And additionally, just because we manage to execvp the qemu-* binary, 
that doesn't mean that it initialises fully.  In Real Life rpm ensures 
that we can't install libvirt without having qemu, so qemu 
initialisation failures are likely to be far more common than 
cannot-exec-qemu failures.

Olwm (the old OpenLook window manager) solved both problems in this way. 
  From the olwm man page[2]:

      -syncpid process-id
           When olwm has completed  its  initialization,  it  will
           send  a  signal (SIGALRM by default) to process-id. The
           signal will be sent only if  this  option  is  present.
           This  is  useful  for  running  olwm from shell scripts
           (such as .xinitrc) in such a way that the script  waits
           for  olwm  to  finish its initialization, while leaving
           olwm as a child process of the shell script.  This  can
           be done using the following sh(1) construct:

                sleep 15 & pid=$!
                olwm -syncpid $pid &
                wait $pid


      -syncsignal signal
           Specifies the signal to send instead of  SIGALRM.   The
           signal is specified as a number, not symbolically.

(In the shell-script example shown there is no way to catch errors, but 
you can easily extend this by sending SIGALRM to the parent -- 
indicating correct exec + initialisation -- or timing out).

OK, so this requires an upstream patch to qemu.  Worth getting this in 
now with the view that a few years down the line it'll be useful?

In the present, qemu has two features which seem to allow us to detect 
partial or full initialisation.

The -daemonize flag in qemu explicitly allows you to do this.  They use 
a pipe from the child back to the parent which sends a signal back to 
the parent after full initialisation has happened.  Unfortunately this 
means that qemu is not only not a child of libvirt, but also we no 
longer have access to stdin/stdout (ie. console).  We would need to make 
   another (good) change to allow qemu to write console sockets into a 
well-known directory using qemu -monitor unix:/var/...

The -pidfile flag is a more immediate, partial solution.  The pidfile is 
written part way through initialisation -- the qemu process has been 
exec'd and has done some work, and then works its way through the 
command line arguments until it reaches this one, whereupon it creates 
the file immediately.  After parsing command line arguments, some 
further initialisation is done, so this is not a full solution.

What do people think?  Worth me working on fixing this problem properly?

Rich.

[1] It's arguable whether we should do that, or rely on configure-time 
detection of the binaries.  Perhaps configure-time configuration is more 
secure.

[2] http://www.umanitoba.ca/cgi-bin/man.cgi?section=1&topic=olwm




More information about the libvir-list mailing list