ia64/xen-unstable

changeset 19230:0c61a377c627

pygrub: fix for NetBSD

Signed-off-by: Frank van der Linden <frank.vanderlinden@sun.com>
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 19 10:53:46 2009 +0000 (2009-02-19)
parents b29a64d04a01
children bd991b0431aa
files tools/python/xen/xend/XendBootloader.py
line diff
     1.1 --- a/tools/python/xen/xend/XendBootloader.py	Wed Feb 18 08:59:26 2009 +0000
     1.2 +++ b/tools/python/xen/xend/XendBootloader.py	Thu Feb 19 10:53:46 2009 +0000
     1.3 @@ -67,9 +67,23 @@ def bootloader(blexec, disk, dom, quiet 
     1.4      # listening on the bootloader's fifo for the results.
     1.5  
     1.6      (m1, s1) = pty.openpty()
     1.7 -    tty.setraw(m1);
     1.8 -    fcntl.fcntl(m1, fcntl.F_SETFL, os.O_NDELAY);
     1.9 -    os.close(s1)
    1.10 +
    1.11 +    # On Solaris, the pty master side will get cranky if we try
    1.12 +    # to write to it while there is no slave. To work around this,
    1.13 +    # keep the slave descriptor open until we're done. Set it
    1.14 +    # to raw terminal parameters, otherwise it will echo back
    1.15 +    # characters, which will confuse the I/O loop below.
    1.16 +    # Furthermore, a raw master pty device has no terminal
    1.17 +    # semantics on Solaris, so don't try to set any attributes
    1.18 +    # for it.
    1.19 +    if os.uname()[0] != 'SunOS' and os.uname()[0] != 'NetBSD':
    1.20 +        tty.setraw(m1)
    1.21 +        os.close(s1)
    1.22 +    else:
    1.23 +        tty.setraw(s1)
    1.24 +
    1.25 +    fcntl.fcntl(m1, fcntl.F_SETFL, os.O_NDELAY)
    1.26 +
    1.27      slavename = ptsname.ptsname(m1)
    1.28      dom.storeDom("console/tty", slavename)
    1.29  
    1.30 @@ -108,7 +122,11 @@ def bootloader(blexec, disk, dom, quiet 
    1.31      # record that this domain is bootloading
    1.32      dom.bootloader_pid = child
    1.33  
    1.34 -    tty.setraw(m2);
    1.35 +    # On Solaris, the master pty side does not have terminal semantics,
    1.36 +    # so don't try to set any attributes, as it will fail.
    1.37 +    if os.uname()[0] != 'SunOS':
    1.38 +        tty.setraw(m2);
    1.39 +
    1.40      fcntl.fcntl(m2, fcntl.F_SETFL, os.O_NDELAY);
    1.41      while True:
    1.42          try:
    1.43 @@ -117,32 +135,55 @@ def bootloader(blexec, disk, dom, quiet 
    1.44              if e.errno == errno.EINTR:
    1.45                  continue
    1.46          break
    1.47 +
    1.48 +    fcntl.fcntl(r, fcntl.F_SETFL, os.O_NDELAY);
    1.49 +
    1.50      ret = ""
    1.51      inbuf=""; outbuf="";
    1.52 +    # filedescriptors:
    1.53 +    #   r - input from the bootloader (bootstring output)
    1.54 +    #   m1 - input/output from/to xenconsole
    1.55 +    #   m2 - input/output from/to pty that controls the bootloader
    1.56 +    # The filedescriptors are NDELAY, so it's ok to try to read
    1.57 +    # bigger chunks than may be available, to keep e.g. curses
    1.58 +    # screen redraws in the bootloader efficient. m1 is the side that
    1.59 +    # gets xenconsole input, which will be keystrokes, so a small number
    1.60 +    # is sufficient. m2 is pygrub output, which will be curses screen
    1.61 +    # updates, so a larger number (1024) is appropriate there.
    1.62 +    #
    1.63 +    # For writeable descriptors, only include them in the set for select
    1.64 +    # if there is actual data to write, otherwise this would loop too fast,
    1.65 +    # eating up CPU time.
    1.66 +
    1.67      while True:
    1.68 -        sel = select.select([r, m1, m2], [m1, m2], [])
    1.69 +        wsel = []
    1.70 +        if len(outbuf) != 0:
    1.71 +            wsel = wsel + [m1]
    1.72 +        if len(inbuf) != 0:
    1.73 +            wsel = wsel + [m2]
    1.74 +        sel = select.select([r, m1, m2], wsel, [])
    1.75          try: 
    1.76              if m1 in sel[0]:
    1.77 -                s = os.read(m1, 1)
    1.78 +                s = os.read(m1, 16)
    1.79                  inbuf += s
    1.80 -            if m2 in sel[1] and len(inbuf) != 0:
    1.81 -                os.write(m2, inbuf[0])
    1.82 -                inbuf = inbuf[1:]
    1.83 +            if m2 in sel[1]:
    1.84 +                n = os.write(m2, inbuf)
    1.85 +                inbuf = inbuf[n:]
    1.86          except OSError, e:
    1.87              if e.errno == errno.EIO:
    1.88                  pass
    1.89          try:
    1.90              if m2 in sel[0]:
    1.91 -                s = os.read(m2, 1)
    1.92 +                s = os.read(m2, 1024)
    1.93                  outbuf += s
    1.94 -            if m1 in sel[1] and len(outbuf) != 0:
    1.95 -                os.write(m1, outbuf[0])
    1.96 -                outbuf = outbuf[1:]
    1.97 +            if m1 in sel[1]:
    1.98 +                n = os.write(m1, outbuf)
    1.99 +                outbuf = outbuf[n:]
   1.100          except OSError, e:
   1.101              if e.errno == errno.EIO:
   1.102                  pass
   1.103          if r in sel[0]:
   1.104 -            s = os.read(r, 1)
   1.105 +            s = os.read(r, 128)
   1.106              ret = ret + s
   1.107              if len(s) == 0:
   1.108                  break
   1.109 @@ -152,6 +193,8 @@ def bootloader(blexec, disk, dom, quiet 
   1.110      os.close(r)
   1.111      os.close(m2)
   1.112      os.close(m1)
   1.113 +    if os.uname()[0] == 'SunOS' or os.uname()[0] == 'NetBSD':
   1.114 +        os.close(s1)
   1.115      os.unlink(fifo)
   1.116  
   1.117      # Re-acquire the lock to cover the changes we're about to make