direct-io.hg

changeset 4319:dae9d4fb9a3c

bitkeeper revision 1.1236.43.6 (4243f3f3rPSrXq5qC_rXYAkeTrQ7dQ)

manual merge
author iap10@freefall.cl.cam.ac.uk
date Fri Mar 25 11:20:19 2005 +0000 (2005-03-25)
parents 818774e72986 27081126eb42
children fbb28076d427
files .rootkeys linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c tools/examples/vnc/Xservers tools/examples/vnc/Xvnc-xen tools/examples/xend-config.sxp tools/libxutil/sxpr.c tools/libxutil/sxpr.h tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/Vifctl.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/create.py xen/include/public/io/domain_controller.h
line diff
     1.1 --- a/.rootkeys	Thu Mar 24 21:52:56 2005 +0000
     1.2 +++ b/.rootkeys	Fri Mar 25 11:20:19 2005 +0000
     1.3 @@ -465,6 +465,8 @@ 41e661e1giIEKbJ25qfiP-ke8u8hFA tools/exa
     1.4  40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge
     1.5  41fc0c18AFAVXA1uGm1JFWHMeeznVw tools/examples/vif-nat
     1.6  41e661e1ooiRKlOfwumG6wwzc0PdhQ tools/examples/vif-route
     1.7 +423ab2eaNCzxk3c-9yU1BwzxWvsDCQ tools/examples/vnc/Xservers
     1.8 +423ab2ea7ajZLdZOI-8Z-bpNdNhhAQ tools/examples/vnc/Xvnc-xen
     1.9  40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp
    1.10  41dde8af6M2Pm1Rrv_f5jEFC_BIOIA tools/examples/xmexample.vmx
    1.11  41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1
     2.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c	Thu Mar 24 21:52:56 2005 +0000
     2.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c	Fri Mar 25 11:20:19 2005 +0000
     2.3 @@ -119,7 +119,7 @@ void netif_create(netif_be_create_t *cre
     2.4      unsigned int       handle = create->netif_handle;
     2.5      struct net_device *dev;
     2.6      netif_t          **pnetif, *netif;
     2.7 -    char               name[IFNAMSIZ];
     2.8 +    char               name[IFNAMSIZ] = {};
     2.9  
    2.10      snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
    2.11      dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/examples/vnc/Xservers	Fri Mar 25 11:20:19 2005 +0000
     3.3 @@ -0,0 +1,5 @@
     3.4 +# Configuration lines to go in /etc/X11/xdm/Xservers to
     3.5 +# start Xvnc and connect back to a vncviewer in domain-0.
     3.6 +# See 'man xdm' under 'LOCAL SERVER SPECIFICATION' for format details.
     3.7 +
     3.8 +:1 Xvnc local /usr/X11R6/bin/Xvnc-xen :1
     3.9 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/examples/vnc/Xvnc-xen	Fri Mar 25 11:20:19 2005 +0000
     4.3 @@ -0,0 +1,53 @@
     4.4 +#!/bin/bash
     4.5 +#============================================================================
     4.6 +# This script should be installed in /usr/X11R6/bin/Xvnc-xen.
     4.7 +#============================================================================
     4.8 +#
     4.9 +# Start Xvnc and use vncconnect to connect back to a vncviewer listening in
    4.10 +# domain 0. The host and port to connect to are given by
    4.11 +#
    4.12 +#    VNC_VIEWER=<host>:<port>
    4.13 +#
    4.14 +# in the kernel command line (/proc/cmdline). 
    4.15 +#
    4.16 +# The '--vnc' option to 'xm create' will start a vncviewer and
    4.17 +# pass its address in VNC_VIEWER for this script to find.
    4.18 +#
    4.19 +# Usage:
    4.20 +#        Xvnc-xen [args]
    4.21 +#
    4.22 +# Any arguments are passed to Xvnc.
    4.23 +#
    4.24 +#============================================================================
    4.25 +
    4.26 +# Prefix for messages.
    4.27 +M="[$(basename $0)]"
    4.28 +
    4.29 +# Usage: vnc_addr
    4.30 +# Print <host>:<port> for the vncviewer given in
    4.31 +# the kernel command line.
    4.32 +vnc_addr () {
    4.33 +    sed -n -e "s/.*VNC_VIEWER=\([^ ]*\).*/\1/p" /proc/cmdline
    4.34 +}
    4.35 +
    4.36 +# Usage: vnc_connect
    4.37 +# If a vncviewer address was given on the kernel command line,
    4.38 +# run vncconnect for it.
    4.39 +vnc_connect () {
    4.40 +    local addr=$(vnc_addr)
    4.41 +
    4.42 +    if [ -n "${addr}" ] ; then
    4.43 +        echo "$M Connecting to ${addr}."
    4.44 +        vncconnect ${addr}
    4.45 +    else
    4.46 +        echo "$M No VNC_VIEWER in kernel command line."
    4.47 +        echo "$M Create the domain with 'xm create --vnc <display>'."
    4.48 +        return 1
    4.49 +    fi
    4.50 +}
    4.51 +
    4.52 +# Start the vnc server.
    4.53 +Xvnc "$@" >/dev/null 2>&1 &
    4.54 +
    4.55 +# Connect back to the viewer in domain-0.
    4.56 +vnc_connect
     6.1 --- a/tools/libxutil/sxpr.c	Thu Mar 24 21:52:56 2005 +0000
     6.2 +++ b/tools/libxutil/sxpr.c	Fri Mar 25 11:20:19 2005 +0000
     6.3 @@ -82,6 +82,30 @@ static SxprType types[1024] = {
     6.4  /** Number of entries in the types array. */
     6.5  static int type_sup = sizeof(types)/sizeof(types[0]);
     6.6  
     6.7 +/** Define a type.
     6.8 + * The tydef must have a non-zero type code.
     6.9 + * It is an error if the type code is out of range or already defined.
    6.10 + *
    6.11 + * @param tydef type definition
    6.12 + * @return 0 on success, error code otherwise
    6.13 + */
    6.14 +int def_sxpr_type(SxprType *tydef){
    6.15 +    int err = 0;
    6.16 +    int ty = tydef->type;
    6.17 +    if(ty < 0 || ty >= type_sup){
    6.18 +        err = -EINVAL;
    6.19 +        goto exit;
    6.20 +    }
    6.21 +    if(types[ty].type){
    6.22 +        err = -EEXIST;
    6.23 +        goto exit;
    6.24 +    }
    6.25 +    types[ty] = *tydef;
    6.26 +  exit:
    6.27 +    return err;
    6.28 +    
    6.29 +}
    6.30 +
    6.31  /** Get the type definition for a given type code.
    6.32   *
    6.33   * @param ty type code
     7.1 --- a/tools/libxutil/sxpr.h	Thu Mar 24 21:52:56 2005 +0000
     7.2 +++ b/tools/libxutil/sxpr.h	Fri Mar 25 11:20:19 2005 +0000
     7.3 @@ -307,6 +307,7 @@ typedef struct SxprType {
     7.4  } SxprType;
     7.5  
     7.6  
     7.7 +extern int def_sxpr_type(SxprType *tydef);
     7.8  extern SxprType *get_sxpr_type(int ty);
     7.9  
    7.10  /** Free the pointer in an sxpr.
     8.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Thu Mar 24 21:52:56 2005 +0000
     8.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Fri Mar 25 11:20:19 2005 +0000
     8.3 @@ -477,6 +477,7 @@ static PyTypeObject xu_notifier_type = {
     8.4   */
     8.5  
     8.6  #define TYPE(_x,_y) (((_x)<<8)|(_y))
     8.7 +
     8.8  #define P2C(_struct, _field, _ctype)                                      \
     8.9      do {                                                                  \
    8.10          PyObject *obj;                                                    \
    8.11 @@ -497,6 +498,29 @@ static PyTypeObject xu_notifier_type = {
    8.12          }                                                                 \
    8.13          xum->msg.length = sizeof(_struct);                                \
    8.14      } while ( 0 )
    8.15 +
    8.16 +/** Set a char[] field in a struct from a Python string.
    8.17 + * Can't do this in P2C because of the typing.
    8.18 + */
    8.19 +#define P2CSTRING(_struct, _field)                                        \
    8.20 +    do {                                                                  \
    8.21 +        PyObject *obj;                                                    \
    8.22 +        if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL )     \
    8.23 +        {                                                                 \
    8.24 +            if ( PyString_Check(obj) )                                    \
    8.25 +            {                                                             \
    8.26 +                _struct * _cobj = (_struct *)&xum->msg.msg[0];            \
    8.27 +                int _field_n = sizeof(_cobj->_field);                     \
    8.28 +                memset(_cobj->_field, 0, _field_n);                       \
    8.29 +                strncpy(_cobj->_field,                                    \
    8.30 +                        PyString_AsString(obj),                           \
    8.31 +                        _field_n - 1);                                    \
    8.32 +                dict_items_parsed++;                                      \
    8.33 +            }                                                             \
    8.34 +        }                                                                 \
    8.35 +        xum->msg.length = sizeof(_struct);                                \
    8.36 +    } while ( 0 )
    8.37 +
    8.38  #define C2P(_struct, _field, _pytype, _ctype)                             \
    8.39      do {                                                                  \
    8.40          PyObject *obj = Py ## _pytype ## _From ## _ctype                  \
     9.1 --- a/tools/python/xen/xend/Vifctl.py	Thu Mar 24 21:52:56 2005 +0000
     9.2 +++ b/tools/python/xen/xend/Vifctl.py	Fri Mar 25 11:20:19 2005 +0000
     9.3 @@ -37,6 +37,19 @@ def network(op, script=None, bridge=None
     9.4      args = ' '.join(args)
     9.5      os.system(script + ' ' + args)
     9.6  
     9.7 +def set_vif_name(vif_old, vif_new):
     9.8 +    if vif_old == vif_new:
     9.9 +        vif = view_new
    9.10 +    if os.system("ip link show %s" % vif_old) == 0:
    9.11 +        os.system("ip link set %s down" % vif_old)
    9.12 +        os.system("ip link set %s name %s" % (vif_old, vif_new))
    9.13 +        os.system("ip link set %s up" % vif_new)
    9.14 +    if os.system("ip link show %s" % vif_new) == 0:
    9.15 +        vif = vif_new
    9.16 +    else:
    9.17 +        vif = vif_old
    9.18 +    return vif
    9.19 +
    9.20  def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=[]):
    9.21      """Call a vif control script.
    9.22      Xend calls this when bringing vifs up or down.
    10.1 --- a/tools/python/xen/xend/XendMigrate.py	Thu Mar 24 21:52:56 2005 +0000
    10.2 +++ b/tools/python/xen/xend/XendMigrate.py	Fri Mar 25 11:20:19 2005 +0000
    10.3 @@ -6,12 +6,14 @@ import errno
    10.4  import sys
    10.5  import socket
    10.6  import time
    10.7 +import types
    10.8  
    10.9  from twisted.internet import reactor
   10.10  from twisted.internet import defer
   10.11  #defer.Deferred.debug = 1
   10.12  from twisted.internet.protocol import Protocol
   10.13  from twisted.internet.protocol import ClientFactory
   10.14 +from twisted.python.failure import Failure
   10.15  
   10.16  import sxp
   10.17  import XendDB
   10.18 @@ -45,11 +47,9 @@ class Xfrd(Protocol):
   10.19          sxp.show(req, out=self.transport)
   10.20  
   10.21      def loseConnection(self):
   10.22 -        print 'Xfrd>loseConnection>'
   10.23          self.transport.loseConnection()
   10.24  
   10.25      def connectionLost(self, reason):
   10.26 -        print 'Xfrd>connectionLost>', reason
   10.27          self.xinfo.connectionLost(reason)
   10.28  
   10.29      def dataReceived(self, data):
   10.30 @@ -70,17 +70,15 @@ class XfrdClientFactory(ClientFactory):
   10.31          self.xinfo = xinfo
   10.32  
   10.33      def startedConnecting(self, connector):
   10.34 -        print 'Started to connect', 'self=', self, 'connector=', connector
   10.35 +        pass
   10.36  
   10.37      def buildProtocol(self, addr):
   10.38 -        print 'buildProtocol>', addr
   10.39          return Xfrd(self.xinfo)
   10.40  
   10.41      def clientConnectionLost(self, connector, reason):
   10.42 -        print 'clientConnectionLost>', 'connector=', connector, 'reason=', reason
   10.43 +        pass
   10.44  
   10.45      def clientConnectionFailed(self, connector, reason):
   10.46 -        print 'clientConnectionFailed>', 'connector=', connector, 'reason=', reason
   10.47          self.xinfo.error(reason)
   10.48  
   10.49  class XfrdInfo:
   10.50 @@ -90,7 +88,7 @@ class XfrdInfo:
   10.51  
   10.52      """Suspend timeout (seconds).
   10.53      We set a timeout because suspending a domain can hang."""
   10.54 -    timeout = 30
   10.55 +    timeout = 10
   10.56  
   10.57      def __init__(self):
   10.58          from xen.xend import XendDomain
   10.59 @@ -98,6 +96,9 @@ class XfrdInfo:
   10.60          self.deferred = defer.Deferred()
   10.61          self.suspended = {}
   10.62          self.paused = {}
   10.63 +        self.state = 'init'
   10.64 +        # List of errors encountered.
   10.65 +        self.errors = []
   10.66          
   10.67      def vmconfig(self):
   10.68          dominfo = self.xd.domain_get(self.src_dom)
   10.69 @@ -107,12 +108,38 @@ class XfrdInfo:
   10.70              val = None
   10.71          return val
   10.72  
   10.73 +    def add_error(self, err):
   10.74 +        """Add an error to the error list.
   10.75 +        Returns the error added (which may have been unwrapped if it
   10.76 +        was a Twisted Failure).
   10.77 +        """
   10.78 +        while isinstance(err, Failure):
   10.79 +            err = err.value
   10.80 +        if err not in self.errors:
   10.81 +            self.errors.append(err)
   10.82 +        return err
   10.83 +
   10.84 +    def error_summary(self, msg=None):
   10.85 +        """Get a XendError summarising the errors (if any).
   10.86 +        """
   10.87 +        if msg is None:
   10.88 +            msg = "errors"
   10.89 +        if self.errors:
   10.90 +            errmsg = msg + ': ' + ', '.join(map(str, self.errors))
   10.91 +        else:
   10.92 +            errmsg = msg
   10.93 +        return XendError(errmsg)
   10.94 +
   10.95 +    def get_errors(self):
   10.96 +        """Get the list of errors.
   10.97 +        """
   10.98 +        return self.errors
   10.99 +
  10.100      def error(self, err):
  10.101 -        print 'Error>', err
  10.102          self.state = 'error'
  10.103 +        self.add_error(err)
  10.104          if not self.deferred.called:
  10.105 -            print 'Error> calling errback'
  10.106 -            self.deferred.errback(err)
  10.107 +            self.deferred.errback(self.error_summary())
  10.108  
  10.109      def dispatch(self, xfrd, val):
  10.110          
  10.111 @@ -139,28 +166,23 @@ class XfrdInfo:
  10.112              cbok(val)
  10.113  
  10.114      def unknown(self, xfrd, val):
  10.115 -        print 'unknown>', val
  10.116          xfrd.loseConnection()
  10.117          return None
  10.118  
  10.119      def xfr_err(self, xfrd, val):
  10.120          # If we get an error with non-zero code the operation failed.
  10.121          # An error with code zero indicates hello success.
  10.122 -        print 'xfr_err>', val
  10.123          v = sxp.child0(val)
  10.124 -        print 'xfr_err>', type(v), v
  10.125          err = int(sxp.child0(val))
  10.126          if not err: return
  10.127 -        self.error(err);
  10.128 +        self.error("transfer daemon (xfrd) error: " + str(err))
  10.129          xfrd.loseConnection()
  10.130          return None
  10.131  
  10.132      def xfr_progress(self, xfrd, val):
  10.133 -        print 'xfr_progress>', val
  10.134          return None
  10.135  
  10.136      def xfr_vm_destroy(self, xfrd, val):
  10.137 -        print 'xfr_vm_destroy>', val
  10.138          try:
  10.139              vmid = sxp.child0(val)
  10.140              val = self.xd.domain_destroy(vmid)
  10.141 @@ -168,28 +190,32 @@ class XfrdInfo:
  10.142                  del self.paused[vmid]
  10.143              if vmid in self.suspended:
  10.144                  del self.suspended[vmid]
  10.145 -        except:
  10.146 +        except StandardError, err:
  10.147 +            self.add_error("vm_destroy failed")
  10.148 +            self.add_error(err)
  10.149              val = errno.EINVAL
  10.150          return ['xfr.err', val]
  10.151      
  10.152      def xfr_vm_pause(self, xfrd, val):
  10.153 -        print 'xfr_vm_pause>', val
  10.154          try:
  10.155              vmid = sxp.child0(val)
  10.156              val = self.xd.domain_pause(vmid)
  10.157              self.paused[vmid] = 1
  10.158 -        except:
  10.159 +        except StandardError, err:
  10.160 +            self.add_error("vm_pause failed")
  10.161 +            self.add_error(err)
  10.162              val = errno.EINVAL
  10.163          return ['xfr.err', val]
  10.164  
  10.165      def xfr_vm_unpause(self, xfrd, val):
  10.166 -        print 'xfr_vm_unpause>', val
  10.167          try:
  10.168              vmid = sxp.child0(val)
  10.169              val = self.xd.domain_unpause(vmid)
  10.170              if vmid in self.paused:
  10.171                  del self.paused[vmid]
  10.172 -        except:
  10.173 +        except StandardError, err:
  10.174 +            self.add_error("vm_unpause failed")
  10.175 +            self.add_error(err)
  10.176              val = errno.EINVAL
  10.177          return ['xfr.err', val]
  10.178  
  10.179 @@ -199,7 +225,6 @@ class XfrdInfo:
  10.180          Suspending can hang, so we set a timeout and fail if it
  10.181          takes too long.
  10.182          """
  10.183 -        print 'xfr_vm_suspend>', val
  10.184          try:
  10.185              vmid = sxp.child0(val)
  10.186              d = defer.Deferred()
  10.187 @@ -208,15 +233,15 @@ class XfrdInfo:
  10.188              # the domain died. Set a timeout and error handler so the subscriptions
  10.189              # will be cleaned up if suspending hangs or there is an error.
  10.190              def onSuspended(e, v):
  10.191 -                print 'xfr_vm_suspend>onSuspended>', e, v
  10.192                  if v[1] != vmid: return
  10.193                  subscribe(on=0)
  10.194 -                d.callback(v)
  10.195 +                if not d.called:
  10.196 +                    d.callback(v)
  10.197                  
  10.198              def onDied(e, v):
  10.199 -                print 'xfr_vm_suspend>onDied>', e, v
  10.200                  if v[1] != vmid: return
  10.201 -                d.errback(XendError('Domain died'))
  10.202 +                if not d.called:
  10.203 +                    d.errback(XendError('Domain %s died while suspending' % vmid))
  10.204                  
  10.205              def subscribe(on=1):
  10.206                  if on:
  10.207 @@ -227,24 +252,25 @@ class XfrdInfo:
  10.208                  action('xend.domain.died', onDied)
  10.209  
  10.210              def cberr(err):
  10.211 -                print 'xfr_vm_suspend>cberr>', err
  10.212                  subscribe(on=0)
  10.213 +                self.add_error("suspend failed")
  10.214 +                self.add_error(err)
  10.215                  return err
  10.216  
  10.217 +            d.addErrback(cberr)
  10.218 +            d.setTimeout(self.timeout)
  10.219              subscribe()
  10.220              val = self.xd.domain_shutdown(vmid, reason='suspend')
  10.221              self.suspended[vmid] = 1
  10.222 -            d.addErrback(cberr)
  10.223 -            d.setTimeout(self.timeout)
  10.224              return d
  10.225          except Exception, err:
  10.226 -            print 'xfr_vm_suspend> Exception', err
  10.227 +            self.add_error("suspend failed")
  10.228 +            self.add_error(err)
  10.229              traceback.print_exc()
  10.230              val = errno.EINVAL
  10.231          return ['xfr.err', val]
  10.232  
  10.233      def connectionLost(self, reason=None):
  10.234 -        print 'XfrdInfo>connectionLost>', reason
  10.235          for vmid in self.suspended:
  10.236              try:
  10.237                  self.xd.domain_destroy(vmid)
  10.238 @@ -279,7 +305,7 @@ class XendMigrateInfo(XfrdInfo):
  10.239                  ['id',    self.xid   ],
  10.240                  ['state', self.state ],
  10.241                  ['live',  self.live  ],
  10.242 -                ['resource', self.resource] ]
  10.243 +                ['resource', self.resource ] ]
  10.244          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
  10.245          sxpr.append(sxpr_src)
  10.246          sxpr_dst = ['dst', ['host', self.dst_host] ]
  10.247 @@ -291,12 +317,12 @@ class XendMigrateInfo(XfrdInfo):
  10.248      def request(self, xfrd):
  10.249          vmconfig = self.vmconfig()
  10.250          if not vmconfig:
  10.251 +            self.error(XendError("vm config not found"))
  10.252              xfrd.loseConnection()
  10.253              return
  10.254 -        log.info('Migrate BEGIN: ' + str(self.sxpr()))
  10.255 +        log.info('Migrate BEGIN: %s' % str(self.sxpr()))
  10.256          eserver.inject('xend.domain.migrate',
  10.257 -                       [ self.dominfo.name, self.dominfo.id,
  10.258 -                         "begin", self.sxpr() ])
  10.259 +                       [ self.dominfo.name, self.dominfo.id, "begin", self.sxpr() ])
  10.260          xfrd.request(['xfr.migrate',
  10.261                        self.src_dom,
  10.262                        vmconfig,
  10.263 @@ -305,19 +331,6 @@ class XendMigrateInfo(XfrdInfo):
  10.264                        self.live,
  10.265                        self.resource ])
  10.266          
  10.267 -##     def xfr_vm_suspend(self, xfrd, val):
  10.268 -##         def cbok(val):
  10.269 -##             # Special case for localhost: destroy devices early.
  10.270 -##             if self.dst_host in ["localhost", "127.0.0.1"]:
  10.271 -##                 self.dominfo.restart_cancel()
  10.272 -##                 self.dominfo.cleanup()
  10.273 -##                 self.dominfo.destroy_console()
  10.274 -##             return val
  10.275 -            
  10.276 -##         d = XfrdInfo.xfr_vm_suspend(self, xfrd, val)
  10.277 -##         d.addCallback(cbok)
  10.278 -##         return d
  10.279 -    
  10.280      def xfr_migrate_ok(self, xfrd, val):
  10.281          dom = int(sxp.child0(val))
  10.282          self.state = 'ok'
  10.283 @@ -327,17 +340,15 @@ class XendMigrateInfo(XfrdInfo):
  10.284              self.deferred.callback(self)
  10.285  
  10.286      def connectionLost(self, reason=None):
  10.287 -        print 'XfrdMigrateInfo>connectionLost>', reason
  10.288          XfrdInfo.connectionLost(self, reason)
  10.289          if self.state =='ok':
  10.290              log.info('Migrate OK: ' + str(self.sxpr()))
  10.291          else:
  10.292              self.state = 'error'
  10.293 -            self.error(XendError("migrate failed"))
  10.294 +            self.error("migrate failed")
  10.295              log.info('Migrate ERROR: ' + str(self.sxpr()))
  10.296          eserver.inject('xend.domain.migrate',
  10.297 -                       [ self.dominfo.name, self.dominfo.id,
  10.298 -                         self.state, self.sxpr() ])
  10.299 +                       [ self.dominfo.name, self.dominfo.id, self.state, self.sxpr() ])
  10.300  
  10.301  class XendSaveInfo(XfrdInfo):
  10.302      """Representation of a save in-progress and its interaction with xfrd.
  10.303 @@ -361,16 +372,15 @@ class XendSaveInfo(XfrdInfo):
  10.304          return sxpr
  10.305  
  10.306      def request(self, xfrd):
  10.307 -        print '***request>', self.vmconfig()
  10.308          vmconfig = self.vmconfig()
  10.309          if not vmconfig:
  10.310 +            self.error(XendError("vm config not found"))
  10.311              xfrd.loseConnection()
  10.312              return
  10.313 -        print '***request> begin'
  10.314          log.info('Save BEGIN: ' + str(self.sxpr()))
  10.315          eserver.inject('xend.domain.save',
  10.316 -                       [self.dominfo.name, self.dominfo.id,
  10.317 -                        "begin", self.sxpr()])
  10.318 +                       [ self.dominfo.name, self.dominfo.id,
  10.319 +                         "begin", self.sxpr() ])
  10.320          xfrd.request(['xfr.save', self.src_dom, vmconfig, self.file ])
  10.321          
  10.322      def xfr_save_ok(self, xfrd, val):
  10.323 @@ -380,13 +390,12 @@ class XendSaveInfo(XfrdInfo):
  10.324              self.deferred.callback(self)
  10.325  
  10.326      def connectionLost(self, reason=None):
  10.327 -        print 'XfrdSaveInfo>connectionLost>', reason
  10.328          XfrdInfo.connectionLost(self, reason)
  10.329          if self.state =='ok':
  10.330              log.info('Save OK: ' + str(self.sxpr()))
  10.331          else:
  10.332              self.state = 'error'
  10.333 -            self.error(XendError("save failed"))
  10.334 +            self.error("save failed")
  10.335              log.info('Save ERROR: ' + str(self.sxpr()))
  10.336          eserver.inject('xend.domain.save',
  10.337                         [ self.dominfo.name, self.dominfo.id,
  10.338 @@ -409,8 +418,9 @@ class XendRestoreInfo(XfrdInfo):
  10.339           return sxpr
  10.340  
  10.341      def request(self, xfrd):
  10.342 -        print '***request>', self.file
  10.343          log.info('restore BEGIN: ' + str(self.sxpr()))
  10.344 +        eserver.inject('xend.restore', [ 'begin', self.sxpr()])
  10.345 +                       
  10.346          xfrd.request(['xfr.restore', self.file ])
  10.347          
  10.348      def xfr_restore_ok(self, xfrd, val):
  10.349 @@ -419,8 +429,17 @@ class XendRestoreInfo(XfrdInfo):
  10.350          self.state = 'ok'
  10.351          if not self.deferred.called:
  10.352              self.deferred.callback(dominfo)
  10.353 +         
  10.354 +    def connectionLost(self, reason=None):
  10.355 +        XfrdInfo.connectionLost(self, reason)
  10.356 +        if self.state =='ok':
  10.357 +            log.info('Restore OK: ' + self.file)
  10.358 +        else:
  10.359 +            self.state = 'error'
  10.360 +            self.error("restore failed")
  10.361 +            log.info('Restore ERROR: ' + str(self.sxpr()))
  10.362 +        eserver.inject('xend.restore', [ self.state,  self.sxpr()])
  10.363  
  10.364 -         
  10.365  class XendMigrate:
  10.366      """External api for interaction with xfrd for migrate and save.
  10.367      Singleton.
  10.368 @@ -445,7 +464,6 @@ class XendMigrate:
  10.369          self.db.saveall("", self.session_db)
  10.370  
  10.371      def sync_session(self, xid):
  10.372 -        print 'sync_session>', type(xid), xid, self.session_db[xid]
  10.373          self.db.save(xid, self.session_db[xid])
  10.374  
  10.375      def close(self):
  10.376 @@ -458,7 +476,6 @@ class XendMigrate:
  10.377          self.sync_session(xid)
  10.378  
  10.379      def _delete_session(self, xid):
  10.380 -        print '***_delete_session>', xid
  10.381          if xid in self.session:
  10.382              del self.session[xid]
  10.383          if xid in self.session_db:
  10.384 @@ -482,16 +499,23 @@ class XendMigrate:
  10.385          @param info: session
  10.386          @return: deferred
  10.387          """
  10.388 -        def cbremove(val):
  10.389 -            print '***cbremove>', val
  10.390 +        dfr = defer.Deferred()
  10.391 +        def cbok(val):
  10.392              self._delete_session(info.xid)
  10.393 +            if not dfr.called:
  10.394 +                dfr.callback(val)
  10.395              return val
  10.396 +        def cberr(err):
  10.397 +            self._delete_session(info.xid)
  10.398 +            if not dfr.called:
  10.399 +                dfr.errback(err)
  10.400 +            return err
  10.401          self._add_session(info)
  10.402 -        info.deferred.addCallback(cbremove)
  10.403 -        info.deferred.addErrback(cbremove)
  10.404 +        info.deferred.addCallback(cbok)
  10.405 +        info.deferred.addErrback(cberr)
  10.406          xcf = XfrdClientFactory(info)
  10.407          reactor.connectTCP('localhost', XFRD_PORT, xcf)
  10.408 -        return info.deferred
  10.409 +        return dfr
  10.410      
  10.411      def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0):
  10.412          """Begin to migrate a domain to another host.
    11.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Thu Mar 24 21:52:56 2005 +0000
    11.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Fri Mar 25 11:20:19 2005 +0000
    11.3 @@ -29,13 +29,8 @@ class SrvDomain(SrvDir):
    11.4                      [['dom', 'int'],
    11.5                       ['config', 'sxpr']])
    11.6          deferred = fn(req.args, {'dom': self.dom.dom})
    11.7 -        deferred.addErrback(self._op_configure_err, req)
    11.8          return deferred
    11.9  
   11.10 -    def _op_configure_err(self, err, req):
   11.11 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   11.12 -        return str(err)
   11.13 -        
   11.14      def op_unpause(self, op, req):
   11.15          val = self.xd.domain_unpause(self.dom.name)
   11.16          return val
   11.17 @@ -68,16 +63,11 @@ class SrvDomain(SrvDir):
   11.18                       ['file', 'str']])
   11.19          deferred = fn(req.args, {'dom': self.dom.id})
   11.20          deferred.addCallback(self._op_save_cb, req)
   11.21 -        deferred.addErrback(self._op_save_err, req)
   11.22          return deferred
   11.23  
   11.24      def _op_save_cb(self, val, req):
   11.25          return 0
   11.26  
   11.27 -    def _op_save_err(self, err, req):
   11.28 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   11.29 -        return str(err)
   11.30 -        
   11.31      def op_migrate(self, op, req):
   11.32          fn = FormFn(self.xd.domain_migrate,
   11.33                      [['dom', 'str'],
   11.34 @@ -85,9 +75,7 @@ class SrvDomain(SrvDir):
   11.35                       ['live', 'int'],
   11.36                       ['resource', 'int']])
   11.37          deferred = fn(req.args, {'dom': self.dom.id})
   11.38 -        print 'op_migrate>', deferred
   11.39          deferred.addCallback(self._op_migrate_cb, req)
   11.40 -        deferred.addErrback(self._op_migrate_err, req)
   11.41          return deferred
   11.42  
   11.43      def _op_migrate_cb(self, info, req):
   11.44 @@ -101,11 +89,6 @@ class SrvDomain(SrvDir):
   11.45          print '_op_migrate_cb> url=', url
   11.46          return url
   11.47  
   11.48 -    def _op_migrate_err(self, err, req):
   11.49 -        print '_op_migrate_err>', err, req
   11.50 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   11.51 -        return str(err)
   11.52 -
   11.53      def op_pincpu(self, op, req):
   11.54          fn = FormFn(self.xd.domain_pincpu,
   11.55                      [['dom', 'str'],
    12.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Mar 24 21:52:56 2005 +0000
    12.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Mar 25 11:20:19 2005 +0000
    12.3 @@ -181,6 +181,8 @@ class BlkifBackendInterface(controller.B
    12.4              self.close()
    12.5          d = defer.Deferred()
    12.6          d.addCallback(cb_destroy)
    12.7 +        if self.evtchn:
    12.8 +            channel.eventChannelClose(self.evtchn)
    12.9          self.send_be_disconnect(response=d)
   12.10          
   12.11      def send_be_disconnect(self, response=None):
    13.1 --- a/tools/python/xen/xend/server/channel.py	Thu Mar 24 21:52:56 2005 +0000
    13.2 +++ b/tools/python/xen/xend/server/channel.py	Fri Mar 25 11:20:19 2005 +0000
    13.3 @@ -11,7 +11,31 @@ VIRQ_CONSOLE    = 3  # (DOM0) bytes rece
    13.4  VIRQ_DOM_EXC    = 4  # (DOM0) Exceptional event for some domain.
    13.5  
    13.6  def eventChannel(dom1, dom2):
    13.7 -    return xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
    13.8 +    """Create an event channel between domains.
    13.9 +    The returned dict contains dom1, dom2, port1 and port2 on success.
   13.10 +
   13.11 +    @return dict (empty on error)
   13.12 +    """
   13.13 +    evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
   13.14 +    if evtchn:
   13.15 +        evtchn['dom1'] = dom1
   13.16 +        evtchn['dom2'] = dom2
   13.17 +    return evtchn
   13.18 +
   13.19 +def eventChannelClose(evtchn):
   13.20 +    """Close an event channel that was opened by eventChannel().
   13.21 +    """
   13.22 +    def evtchn_close(dom, port):
   13.23 +        if (dom is None) or (port is None): return
   13.24 +        try:
   13.25 +            xc.evtchn_close(dom=dom, port=port)
   13.26 +        except Exception, ex:
   13.27 +            pass
   13.28 +        
   13.29 +    if not evtchn: return
   13.30 +    evtchn_close(evtchn.get('dom1'), evtchn.get('port1'))
   13.31 +    evtchn_close(evtchn.get('dom2'), evtchn.get('port2'))
   13.32 +    
   13.33  
   13.34  class ChannelFactory:
   13.35      """Factory for creating channels.
    14.1 --- a/tools/python/xen/xend/server/netif.py	Thu Mar 24 21:52:56 2005 +0000
    14.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Mar 25 11:20:19 2005 +0000
    14.3 @@ -138,7 +138,13 @@ class NetDev(controller.SplitDev):
    14.4          self.bridge = None
    14.5          self.script = None
    14.6          self.ipaddr = []
    14.7 +        self.vifname = None
    14.8  
    14.9 +        self.vifname = sxp.child_value(config, 'vifname')
   14.10 +        if self.vifname is None:
   14.11 +            self.vifname = self.default_vifname()
   14.12 +        if len(self.vifname) > 15:
   14.13 +            raise XendError('invalid vifname: too long: ' + self.vifname)
   14.14          mac = self._get_config_mac(config)
   14.15          if mac is None:
   14.16              raise XendError("invalid mac")
   14.17 @@ -201,7 +207,10 @@ class NetDev(controller.SplitDev):
   14.18          val = ['vif',
   14.19                 ['idx', self.idx],
   14.20                 ['vif', vif],
   14.21 -               ['mac', mac]]
   14.22 +               ['mac', mac],
   14.23 +               ['vifname', self.vifname],
   14.24 +               ]
   14.25 +
   14.26          if self.be_mac:
   14.27              val.append(['be_mac', self.get_be_mac()])
   14.28          if self.bridge:
   14.29 @@ -221,8 +230,11 @@ class NetDev(controller.SplitDev):
   14.30      def get_vifname(self):
   14.31          """Get the virtual interface device name.
   14.32          """
   14.33 +        return self.vifname
   14.34 +
   14.35 +    def default_vifname(self):
   14.36          return "vif%d.%d" % (self.controller.dom, self.vif)
   14.37 -
   14.38 +    
   14.39      def get_mac(self):
   14.40          """Get the MAC address as a string.
   14.41          """
   14.42 @@ -259,6 +271,8 @@ class NetDev(controller.SplitDev):
   14.43          @param op: operation name (up, down)
   14.44          @param vmname: vmname
   14.45          """
   14.46 +        if op == 'up':
   14.47 +            Vifctl.set_vif_name(self.default_vifname(), self.vifname)
   14.48          Vifctl.vifctl(op, **self.vifctl_params(vmname=vmname))
   14.49          vnet = XendVnet.instance().vnet_of_bridge(self.bridge)
   14.50          if vnet:
   14.51 @@ -287,7 +301,9 @@ class NetDev(controller.SplitDev):
   14.52                        { 'domid'        : self.controller.dom,
   14.53                          'netif_handle' : self.vif,
   14.54                          'be_mac'       : self.be_mac or [0, 0, 0, 0, 0, 0],
   14.55 -                        'mac'          : self.mac })
   14.56 +                        'mac'          : self.mac,
   14.57 +                        #'vifname'      : self.vifname
   14.58 +                        })
   14.59          self.getBackendInterface().writeRequest(msg, response=d)
   14.60          return d
   14.61  
   14.62 @@ -308,6 +324,8 @@ class NetDev(controller.SplitDev):
   14.63              if change:
   14.64                  self.reportStatus()
   14.65          log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
   14.66 +        if self.evtchn:
   14.67 +            channel.eventChannelClose(self.evtchn)
   14.68          self.vifctl('down')
   14.69          d = self.send_be_disconnect()
   14.70          d.addCallback(cb_destroy)
    15.1 --- a/tools/python/xen/xm/create.py	Thu Mar 24 21:52:56 2005 +0000
    15.2 +++ b/tools/python/xen/xm/create.py	Fri Mar 25 11:20:19 2005 +0000
    15.3 @@ -5,6 +5,7 @@
    15.4  import random
    15.5  import string
    15.6  import sys
    15.7 +import socket
    15.8  
    15.9  from xen.xend import sxp
   15.10  from xen.xend import PrettyPrint
   15.11 @@ -81,6 +82,14 @@ gopts.opt('console_autoconnect', short='
   15.12            fn=set_true, default=0,
   15.13            use="Connect to the console after the domain is created.")
   15.14  
   15.15 +gopts.var('vnc', val='no|yes',
   15.16 +          fn=set_bool, default=None,
   15.17 +          use="""Spawn a vncviewer listening for a vnc server in the domain.
   15.18 +          The address of the vncviewer is passed to the domain on the kernel command
   15.19 +          line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
   15.20 +          A display value with a free port is chosen if possible.
   15.21 +          """)
   15.22 +
   15.23  gopts.var('name', val='NAME',
   15.24            fn=set_value, default=None,
   15.25            use="Domain name. Must be unique.")
   15.26 @@ -160,7 +169,7 @@ gopts.var('ipaddr', val="IPADDR",
   15.27            fn=append_value, default=[],
   15.28            use="Add an IP address to the domain.")
   15.29  
   15.30 -gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
   15.31 +gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM,vifname=NAME",
   15.32            fn=append_value, default=[],
   15.33            use="""Add a network interface with the given MAC address and bridge.
   15.34            The vif is configured by calling the given configuration script.
   15.35 @@ -170,6 +179,8 @@ gopts.var('vif', val="mac=MAC,be_mac=MAC
   15.36            If bridge is not specified the default bridge is used.
   15.37            If script is not specified the default script is used.
   15.38            If backend is not specified the default backend driver domain is used.
   15.39 +          If vifname is not specified the backend virtual interface will have name vifD.N
   15.40 +          where D is the domain id and N is the interface id.
   15.41            This option may be repeated to add more than one vif.
   15.42            Specifying vifs will increase the number of interfaces as needed.""")
   15.43  
   15.44 @@ -321,6 +332,7 @@ def configure_vifs(config_devs, vals):
   15.45              script = d.get('script')
   15.46              backend = d.get('backend')
   15.47              ip = d.get('ip')
   15.48 +            vifname = d.get('vifname')
   15.49          else:
   15.50              mac = randomMAC()
   15.51              be_mac = None
   15.52 @@ -328,8 +340,11 @@ def configure_vifs(config_devs, vals):
   15.53              script = None
   15.54              backend = None
   15.55              ip = None
   15.56 +            vifname = None
   15.57          config_vif = ['vif']
   15.58          config_vif.append(['mac', mac])
   15.59 +        if vifname:
   15.60 +            config_vif.append(['vifname', vifname])
   15.61          if be_mac:
   15.62              config_vif.append(['be_mac', be_mac])
   15.63          if bridge:
   15.64 @@ -429,7 +444,7 @@ def preprocess_vifs(opts, vals):
   15.65              (k, v) = b.strip().split('=', 1)
   15.66              k = k.strip()
   15.67              v = v.strip()
   15.68 -            if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip']:
   15.69 +            if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip', 'vifname']:
   15.70                  opts.err('Invalid vif specifier: ' + vif)
   15.71              d[k] = v
   15.72          vifs.append(d)
   15.73 @@ -455,6 +470,58 @@ def preprocess_nfs(opts, vals):
   15.74          opts.err('Must set nfs root and nfs server')
   15.75      nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root
   15.76      vals.extra = nfs + ' ' + vals.extra
   15.77 +
   15.78 +
   15.79 +def get_host_addr():
   15.80 +    host = socket.gethostname()
   15.81 +    addr = socket.gethostbyname(host)
   15.82 +    return addr
   15.83 +
   15.84 +VNC_BASE_PORT = 5500
   15.85 +
   15.86 +def choose_vnc_display():
   15.87 +    """Try to choose a free vnc display.
   15.88 +    """
   15.89 +    def netstat_local_ports():
   15.90 +        """Run netstat to get a list of the local ports in use.
   15.91 +        """
   15.92 +        l = os.popen("netstat -nat").readlines()
   15.93 +        r = []
   15.94 +        # Skip 2 lines of header.
   15.95 +        for x in l[2:]:
   15.96 +            # Local port is field 3.
   15.97 +            y = x.split()[3]
   15.98 +            # Field is addr:port, split off the port.
   15.99 +            y = y.split(':')[1]
  15.100 +            r.append(int(y))
  15.101 +        return r
  15.102 +
  15.103 +    ports = netstat_local_ports()
  15.104 +    for d in range(1, 100):
  15.105 +        port = VNC_BASE_PORT + d
  15.106 +        if port in ports: continue
  15.107 +        return d
  15.108 +    return None
  15.109 +
  15.110 +def spawn_vnc(display):
  15.111 +    os.system("vncviewer -listen %d &" % display)
  15.112 +    return VNC_BASE_PORT + display
  15.113 +    
  15.114 +def preprocess_vnc(opts, vals):
  15.115 +    """If vnc was specified, spawn a vncviewer in listen mode
  15.116 +    and pass its address to the domain on the kernel command line.
  15.117 +    """
  15.118 +    if not vals.vnc: return
  15.119 +    vnc_display = choose_vnc_display()
  15.120 +    if not vnc_display:
  15.121 +        opts.warn("No free vnc display")
  15.122 +        return
  15.123 +    print 'VNC=', vnc_display
  15.124 +    vnc_port = spawn_vnc(vnc_display)
  15.125 +    if vnc_port > 0:
  15.126 +        vnc_host = get_host_addr()
  15.127 +        vnc = 'VNC_VIEWER=%s:%d' % (vnc_host, vnc_port)
  15.128 +        vals.extra = vnc + ' ' + vals.extra
  15.129      
  15.130  def preprocess(opts, vals):
  15.131      if not vals.kernel:
  15.132 @@ -464,6 +531,7 @@ def preprocess(opts, vals):
  15.133      preprocess_vifs(opts, vals)
  15.134      preprocess_ip(opts, vals)
  15.135      preprocess_nfs(opts, vals)
  15.136 +    preprocess_vnc(opts, vals)
  15.137           
  15.138  def make_domain(opts, config):
  15.139      """Create, build and start a domain.