ia64/xen-unstable

changeset 7617:7f8db234e9db

Rewritten handling of child stderr to avoid deadlock.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Wed Nov 02 16:42:29 2005 +0100 (2005-11-02)
parents 99f4ba74763e
children 4321438e92a7
files tools/python/xen/xend/XendCheckpoint.py
line diff
     1.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Tue Nov 01 16:02:43 2005 +0100
     1.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Wed Nov 02 16:42:29 2005 +0100
     1.3 @@ -7,9 +7,9 @@
     1.4  
     1.5  import os
     1.6  import re
     1.7 -import select
     1.8  import string
     1.9  import sxp
    1.10 +import threading
    1.11  from struct import pack, unpack, calcsize
    1.12  
    1.13  from xen.util.xpopen import xPopen3
    1.14 @@ -81,6 +81,7 @@ def save(fd, dominfo, live):
    1.15                  log.info("Domain %d suspended.", dominfo.getDomid())
    1.16                  tochild.write("done\n")
    1.17                  tochild.flush()
    1.18 +                log.debug('Written done')
    1.19  
    1.20          forkHelper(cmd, fd, saveInputHandler, False)
    1.21  
    1.22 @@ -176,43 +177,42 @@ def forkHelper(cmd, fd, inputHandler, cl
    1.23      if closeToChild:
    1.24          child.tochild.close()
    1.25  
    1.26 -    lasterr = "error unknown"
    1.27 +    thread = threading.Thread(target = slurp, args = (child.childerr))
    1.28 +    thread.start()
    1.29 +
    1.30      try:
    1.31 -        fds = [child.fromchild.fileno(),
    1.32 -               child.childerr.fileno()]
    1.33 -        p = select.poll()
    1.34 -        map(p.register, fds)
    1.35 -        while len(fds) > 0:
    1.36 -            r = p.poll()
    1.37 -            for (fd, event) in r:
    1.38 -                if event & select.POLLIN:
    1.39 -                    if fd == child.childerr.fileno():
    1.40 -                        lasterr = child.childerr.readline().rstrip()
    1.41 -                        log.error('%s', lasterr)
    1.42 -                    else:
    1.43 -                        l = child.fromchild.readline().rstrip()
    1.44 -                        while l:
    1.45 -                            log.debug('%s', l)
    1.46 -                            inputHandler(l, child.tochild)
    1.47 -                            try:
    1.48 -                                l = child.fromchild.readline().rstrip()
    1.49 -                            except:
    1.50 -                                l = None
    1.51 +        try:
    1.52 +            while 1:
    1.53 +                line = child.fromchild.readline()
    1.54 +                if line == "":
    1.55 +                    break
    1.56 +                else:
    1.57 +                    line = line.rstrip()
    1.58 +                    log.debug('%s', line)
    1.59 +                    inputHandler(line, child.tochild)
    1.60  
    1.61 -                if event & select.POLLERR:
    1.62 -                    raise XendError('Error reading from child process for %s',
    1.63 -                                    cmd)
    1.64 +            thread.join()
    1.65  
    1.66 -                if event & select.POLLHUP:
    1.67 -                    fds.remove(fd)
    1.68 -                    p.unregister(fd)
    1.69 +        except IOError, exn:
    1.70 +            raise XendError('Error reading from child process for %s: %s' %
    1.71 +                            (cmd, exn))
    1.72      finally:
    1.73          child.fromchild.close()
    1.74          child.childerr.close()
    1.75          if not closeToChild:
    1.76              child.tochild.close()
    1.77  
    1.78 -    if child.wait() >> 8 == 127:
    1.79 -        lasterr = "popen failed"
    1.80 -    if child.wait() != 0:
    1.81 -        raise XendError("%s failed: %s" % (string.join(cmd), lasterr))
    1.82 +    status = child.wait()
    1.83 +    if status >> 8 == 127:
    1.84 +        raise XendError("%s failed: popen failed" % string.join(cmd))
    1.85 +    elif status != 0:
    1.86 +        raise XendError("%s failed" % string.join(cmd))
    1.87 +
    1.88 +
    1.89 +def slurp(file):
    1.90 +    while 1:
    1.91 +        line = file.readline()
    1.92 +        if line == "":
    1.93 +            break
    1.94 +        else:
    1.95 +            log.error('%s', line)