ia64/xen-unstable

changeset 4208:e194000fb445

bitkeeper revision 1.1159.258.61 (423ab8ffoSYKwCMKpGSklR9lHSby6g)

Merge http://xen.bkbits.net:8080/xen-2.0-testing.bk
into gandalf.hpl.hp.com:/var/bk/xen-2.0-testing.bk
author xenbk@gandalf.hpl.hp.com
date Fri Mar 18 11:18:23 2005 +0000 (2005-03-18)
parents 6ac7c6ea6fc2 504d405a48d6
children 3a5d8cd66c0b
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/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	Fri Mar 18 09:18:26 2005 +0000
     1.2 +++ b/.rootkeys	Fri Mar 18 11:18:23 2005 +0000
     1.3 @@ -321,6 +321,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  41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1
    1.11  40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2
     2.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c	Fri Mar 18 09:18:26 2005 +0000
     2.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c	Fri Mar 18 11:18:23 2005 +0000
     2.3 @@ -119,9 +119,13 @@ 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 +    if(create->vifname[0] == '\0'){
    2.12 +        snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
    2.13 +    } else {
    2.14 +        snprintf(name, IFNAMSIZ - 1, "%s", create->vifname);
    2.15 +    }
    2.16      dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
    2.17      if ( dev == NULL )
    2.18      {
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/examples/vnc/Xservers	Fri Mar 18 11:18:23 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 18 11:18:23 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
     5.1 --- a/tools/libxutil/sxpr.c	Fri Mar 18 09:18:26 2005 +0000
     5.2 +++ b/tools/libxutil/sxpr.c	Fri Mar 18 11:18:23 2005 +0000
     5.3 @@ -82,6 +82,30 @@ static SxprType types[1024] = {
     5.4  /** Number of entries in the types array. */
     5.5  static int type_sup = sizeof(types)/sizeof(types[0]);
     5.6  
     5.7 +/** Define a type.
     5.8 + * The tydef must have a non-zero type code.
     5.9 + * It is an error if the type code is out of range or already defined.
    5.10 + *
    5.11 + * @param tydef type definition
    5.12 + * @return 0 on success, error code otherwise
    5.13 + */
    5.14 +int def_sxpr_type(SxprType *tydef){
    5.15 +    int err = 0;
    5.16 +    int ty = tydef->type;
    5.17 +    if(ty < 0 || ty >= type_sup){
    5.18 +        err = -EINVAL;
    5.19 +        goto exit;
    5.20 +    }
    5.21 +    if(types[ty].type){
    5.22 +        err = -EEXIST;
    5.23 +        goto exit;
    5.24 +    }
    5.25 +    types[ty] = *tydef;
    5.26 +  exit:
    5.27 +    return err;
    5.28 +    
    5.29 +}
    5.30 +
    5.31  /** Get the type definition for a given type code.
    5.32   *
    5.33   * @param ty type code
     6.1 --- a/tools/libxutil/sxpr.h	Fri Mar 18 09:18:26 2005 +0000
     6.2 +++ b/tools/libxutil/sxpr.h	Fri Mar 18 11:18:23 2005 +0000
     6.3 @@ -307,6 +307,7 @@ typedef struct SxprType {
     6.4  } SxprType;
     6.5  
     6.6  
     6.7 +extern int def_sxpr_type(SxprType *tydef);
     6.8  extern SxprType *get_sxpr_type(int ty);
     6.9  
    6.10  /** Free the pointer in an sxpr.
     7.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Fri Mar 18 09:18:26 2005 +0000
     7.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Fri Mar 18 11:18:23 2005 +0000
     7.3 @@ -259,6 +259,7 @@ static PyTypeObject xu_notifier_type = {
     7.4   */
     7.5  
     7.6  #define TYPE(_x,_y) (((_x)<<8)|(_y))
     7.7 +
     7.8  #define P2C(_struct, _field, _ctype)                                      \
     7.9      do {                                                                  \
    7.10          PyObject *obj;                                                    \
    7.11 @@ -279,6 +280,29 @@ static PyTypeObject xu_notifier_type = {
    7.12          }                                                                 \
    7.13          xum->msg.length = sizeof(_struct);                                \
    7.14      } while ( 0 )
    7.15 +
    7.16 +/** Set a char[] field in a struct from a Python string.
    7.17 + * Can't do this in P2C because of the typing.
    7.18 + */
    7.19 +#define P2CSTRING(_struct, _field)                                        \
    7.20 +    do {                                                                  \
    7.21 +        PyObject *obj;                                                    \
    7.22 +        if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL )     \
    7.23 +        {                                                                 \
    7.24 +            if ( PyString_Check(obj) )                                    \
    7.25 +            {                                                             \
    7.26 +                _struct * _cobj = (_struct *)&xum->msg.msg[0];            \
    7.27 +                int _field_n = sizeof(_cobj->_field);                     \
    7.28 +                memset(_cobj->_field, 0, _field_n);                       \
    7.29 +                strncpy(_cobj->_field,                                    \
    7.30 +                        PyString_AsString(obj),                           \
    7.31 +                        _field_n - 1);                                    \
    7.32 +                dict_items_parsed++;                                      \
    7.33 +            }                                                             \
    7.34 +        }                                                                 \
    7.35 +        xum->msg.length = sizeof(_struct);                                \
    7.36 +    } while ( 0 )
    7.37 +
    7.38  #define C2P(_struct, _field, _pytype, _ctype)                             \
    7.39      do {                                                                  \
    7.40          PyObject *obj = Py ## _pytype ## _From ## _ctype                  \
    7.41 @@ -456,6 +480,7 @@ static PyObject *xu_message_get_payload(
    7.42          C2P(netif_be_create_t, domid,        Int, Long);
    7.43          C2P(netif_be_create_t, netif_handle, Int, Long);
    7.44          C2P(netif_be_create_t, status,       Int, Long);
    7.45 +        C2P(netif_be_create_t, vifname,      String, String);
    7.46          return dict;
    7.47      case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
    7.48          C2P(netif_be_destroy_t, domid,        Int, Long);
    7.49 @@ -623,6 +648,7 @@ static PyObject *xu_message_new(PyObject
    7.50          P2C(netif_be_create_t, mac[3],       u8);
    7.51          P2C(netif_be_create_t, mac[4],       u8);
    7.52          P2C(netif_be_create_t, mac[5],       u8);
    7.53 +        P2CSTRING(netif_be_create_t, vifname);
    7.54          break;
    7.55      case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
    7.56          P2C(netif_be_destroy_t, domid,        u32);
     8.1 --- a/tools/python/xen/xend/XendMigrate.py	Fri Mar 18 09:18:26 2005 +0000
     8.2 +++ b/tools/python/xen/xend/XendMigrate.py	Fri Mar 18 11:18:23 2005 +0000
     8.3 @@ -6,12 +6,14 @@ import errno
     8.4  import sys
     8.5  import socket
     8.6  import time
     8.7 +import types
     8.8  
     8.9  from twisted.internet import reactor
    8.10  from twisted.internet import defer
    8.11  #defer.Deferred.debug = 1
    8.12  from twisted.internet.protocol import Protocol
    8.13  from twisted.internet.protocol import ClientFactory
    8.14 +from twisted.python.failure import Failure
    8.15  
    8.16  import sxp
    8.17  import XendDB
    8.18 @@ -45,11 +47,9 @@ class Xfrd(Protocol):
    8.19          sxp.show(req, out=self.transport)
    8.20  
    8.21      def loseConnection(self):
    8.22 -        print 'Xfrd>loseConnection>'
    8.23          self.transport.loseConnection()
    8.24  
    8.25      def connectionLost(self, reason):
    8.26 -        print 'Xfrd>connectionLost>', reason
    8.27          self.xinfo.connectionLost(reason)
    8.28  
    8.29      def dataReceived(self, data):
    8.30 @@ -70,17 +70,15 @@ class XfrdClientFactory(ClientFactory):
    8.31          self.xinfo = xinfo
    8.32  
    8.33      def startedConnecting(self, connector):
    8.34 -        print 'Started to connect', 'self=', self, 'connector=', connector
    8.35 +        pass
    8.36  
    8.37      def buildProtocol(self, addr):
    8.38 -        print 'buildProtocol>', addr
    8.39          return Xfrd(self.xinfo)
    8.40  
    8.41      def clientConnectionLost(self, connector, reason):
    8.42 -        print 'clientConnectionLost>', 'connector=', connector, 'reason=', reason
    8.43 +        pass
    8.44  
    8.45      def clientConnectionFailed(self, connector, reason):
    8.46 -        print 'clientConnectionFailed>', 'connector=', connector, 'reason=', reason
    8.47          self.xinfo.error(reason)
    8.48  
    8.49  class XfrdInfo:
    8.50 @@ -90,7 +88,7 @@ class XfrdInfo:
    8.51  
    8.52      """Suspend timeout (seconds).
    8.53      We set a timeout because suspending a domain can hang."""
    8.54 -    timeout = 30
    8.55 +    timeout = 10
    8.56  
    8.57      def __init__(self):
    8.58          from xen.xend import XendDomain
    8.59 @@ -98,6 +96,9 @@ class XfrdInfo:
    8.60          self.deferred = defer.Deferred()
    8.61          self.suspended = {}
    8.62          self.paused = {}
    8.63 +        self.state = 'init'
    8.64 +        # List of errors encountered.
    8.65 +        self.errors = []
    8.66          
    8.67      def vmconfig(self):
    8.68          dominfo = self.xd.domain_get(self.src_dom)
    8.69 @@ -107,12 +108,38 @@ class XfrdInfo:
    8.70              val = None
    8.71          return val
    8.72  
    8.73 +    def add_error(self, err):
    8.74 +        """Add an error to the error list.
    8.75 +        Returns the error added (which may have been unwrapped if it
    8.76 +        was a Twisted Failure).
    8.77 +        """
    8.78 +        while isinstance(err, Failure):
    8.79 +            err = err.value
    8.80 +        if err not in self.errors:
    8.81 +            self.errors.append(err)
    8.82 +        return err
    8.83 +
    8.84 +    def error_summary(self, msg=None):
    8.85 +        """Get a XendError summarising the errors (if any).
    8.86 +        """
    8.87 +        if msg is None:
    8.88 +            msg = "errors"
    8.89 +        if self.errors:
    8.90 +            errmsg = msg + ': ' + ', '.join(map(str, self.errors))
    8.91 +        else:
    8.92 +            errmsg = msg
    8.93 +        return XendError(errmsg)
    8.94 +
    8.95 +    def get_errors(self):
    8.96 +        """Get the list of errors.
    8.97 +        """
    8.98 +        return self.errors
    8.99 +
   8.100      def error(self, err):
   8.101 -        print 'Error>', err
   8.102          self.state = 'error'
   8.103 +        self.add_error(err)
   8.104          if not self.deferred.called:
   8.105 -            print 'Error> calling errback'
   8.106 -            self.deferred.errback(err)
   8.107 +            self.deferred.errback(self.error_summary())
   8.108  
   8.109      def dispatch(self, xfrd, val):
   8.110          
   8.111 @@ -139,28 +166,23 @@ class XfrdInfo:
   8.112              cbok(val)
   8.113  
   8.114      def unknown(self, xfrd, val):
   8.115 -        print 'unknown>', val
   8.116          xfrd.loseConnection()
   8.117          return None
   8.118  
   8.119      def xfr_err(self, xfrd, val):
   8.120          # If we get an error with non-zero code the operation failed.
   8.121          # An error with code zero indicates hello success.
   8.122 -        print 'xfr_err>', val
   8.123          v = sxp.child0(val)
   8.124 -        print 'xfr_err>', type(v), v
   8.125          err = int(sxp.child0(val))
   8.126          if not err: return
   8.127 -        self.error(err);
   8.128 +        self.error("transfer daemon (xfrd) error: " + str(err))
   8.129          xfrd.loseConnection()
   8.130          return None
   8.131  
   8.132      def xfr_progress(self, xfrd, val):
   8.133 -        print 'xfr_progress>', val
   8.134          return None
   8.135  
   8.136      def xfr_vm_destroy(self, xfrd, val):
   8.137 -        print 'xfr_vm_destroy>', val
   8.138          try:
   8.139              vmid = sxp.child0(val)
   8.140              val = self.xd.domain_destroy(vmid)
   8.141 @@ -168,28 +190,32 @@ class XfrdInfo:
   8.142                  del self.paused[vmid]
   8.143              if vmid in self.suspended:
   8.144                  del self.suspended[vmid]
   8.145 -        except:
   8.146 +        except StandardError, err:
   8.147 +            self.add_error("vm_destroy failed")
   8.148 +            self.add_error(err)
   8.149              val = errno.EINVAL
   8.150          return ['xfr.err', val]
   8.151      
   8.152      def xfr_vm_pause(self, xfrd, val):
   8.153 -        print 'xfr_vm_pause>', val
   8.154          try:
   8.155              vmid = sxp.child0(val)
   8.156              val = self.xd.domain_pause(vmid)
   8.157              self.paused[vmid] = 1
   8.158 -        except:
   8.159 +        except StandardError, err:
   8.160 +            self.add_error("vm_pause failed")
   8.161 +            self.add_error(err)
   8.162              val = errno.EINVAL
   8.163          return ['xfr.err', val]
   8.164  
   8.165      def xfr_vm_unpause(self, xfrd, val):
   8.166 -        print 'xfr_vm_unpause>', val
   8.167          try:
   8.168              vmid = sxp.child0(val)
   8.169              val = self.xd.domain_unpause(vmid)
   8.170              if vmid in self.paused:
   8.171                  del self.paused[vmid]
   8.172 -        except:
   8.173 +        except StandardError, err:
   8.174 +            self.add_error("vm_unpause failed")
   8.175 +            self.add_error(err)
   8.176              val = errno.EINVAL
   8.177          return ['xfr.err', val]
   8.178  
   8.179 @@ -199,7 +225,6 @@ class XfrdInfo:
   8.180          Suspending can hang, so we set a timeout and fail if it
   8.181          takes too long.
   8.182          """
   8.183 -        print 'xfr_vm_suspend>', val
   8.184          try:
   8.185              vmid = sxp.child0(val)
   8.186              d = defer.Deferred()
   8.187 @@ -208,15 +233,15 @@ class XfrdInfo:
   8.188              # the domain died. Set a timeout and error handler so the subscriptions
   8.189              # will be cleaned up if suspending hangs or there is an error.
   8.190              def onSuspended(e, v):
   8.191 -                print 'xfr_vm_suspend>onSuspended>', e, v
   8.192                  if v[1] != vmid: return
   8.193                  subscribe(on=0)
   8.194 -                d.callback(v)
   8.195 +                if not d.called:
   8.196 +                    d.callback(v)
   8.197                  
   8.198              def onDied(e, v):
   8.199 -                print 'xfr_vm_suspend>onDied>', e, v
   8.200                  if v[1] != vmid: return
   8.201 -                d.errback(XendError('Domain died'))
   8.202 +                if not d.called:
   8.203 +                    d.errback(XendError('Domain %s died while suspending' % vmid))
   8.204                  
   8.205              def subscribe(on=1):
   8.206                  if on:
   8.207 @@ -227,24 +252,25 @@ class XfrdInfo:
   8.208                  action('xend.domain.died', onDied)
   8.209  
   8.210              def cberr(err):
   8.211 -                print 'xfr_vm_suspend>cberr>', err
   8.212                  subscribe(on=0)
   8.213 +                self.add_error("suspend failed")
   8.214 +                self.add_error(err)
   8.215                  return err
   8.216  
   8.217 +            d.addErrback(cberr)
   8.218 +            d.setTimeout(self.timeout)
   8.219              subscribe()
   8.220              val = self.xd.domain_shutdown(vmid, reason='suspend')
   8.221              self.suspended[vmid] = 1
   8.222 -            d.addErrback(cberr)
   8.223 -            d.setTimeout(self.timeout)
   8.224              return d
   8.225          except Exception, err:
   8.226 -            print 'xfr_vm_suspend> Exception', err
   8.227 +            self.add_error("suspend failed")
   8.228 +            self.add_error(err)
   8.229              traceback.print_exc()
   8.230              val = errno.EINVAL
   8.231          return ['xfr.err', val]
   8.232  
   8.233      def connectionLost(self, reason=None):
   8.234 -        print 'XfrdInfo>connectionLost>', reason
   8.235          for vmid in self.suspended:
   8.236              try:
   8.237                  self.xd.domain_destroy(vmid)
   8.238 @@ -279,7 +305,7 @@ class XendMigrateInfo(XfrdInfo):
   8.239                  ['id',    self.xid   ],
   8.240                  ['state', self.state ],
   8.241                  ['live',  self.live  ],
   8.242 -                ['resource', self.resource] ]
   8.243 +                ['resource', self.resource ] ]
   8.244          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
   8.245          sxpr.append(sxpr_src)
   8.246          sxpr_dst = ['dst', ['host', self.dst_host] ]
   8.247 @@ -291,12 +317,12 @@ class XendMigrateInfo(XfrdInfo):
   8.248      def request(self, xfrd):
   8.249          vmconfig = self.vmconfig()
   8.250          if not vmconfig:
   8.251 +            self.error(XendError("vm config not found"))
   8.252              xfrd.loseConnection()
   8.253              return
   8.254 -        log.info('Migrate BEGIN: ' + str(self.sxpr()))
   8.255 +        log.info('Migrate BEGIN: %s' % str(self.sxpr()))
   8.256          eserver.inject('xend.domain.migrate',
   8.257 -                       [ self.dominfo.name, self.dominfo.id,
   8.258 -                         "begin", self.sxpr() ])
   8.259 +                       [ self.dominfo.name, self.dominfo.id, "begin", self.sxpr() ])
   8.260          xfrd.request(['xfr.migrate',
   8.261                        self.src_dom,
   8.262                        vmconfig,
   8.263 @@ -305,19 +331,6 @@ class XendMigrateInfo(XfrdInfo):
   8.264                        self.live,
   8.265                        self.resource ])
   8.266          
   8.267 -##     def xfr_vm_suspend(self, xfrd, val):
   8.268 -##         def cbok(val):
   8.269 -##             # Special case for localhost: destroy devices early.
   8.270 -##             if self.dst_host in ["localhost", "127.0.0.1"]:
   8.271 -##                 self.dominfo.restart_cancel()
   8.272 -##                 self.dominfo.cleanup()
   8.273 -##                 self.dominfo.destroy_console()
   8.274 -##             return val
   8.275 -            
   8.276 -##         d = XfrdInfo.xfr_vm_suspend(self, xfrd, val)
   8.277 -##         d.addCallback(cbok)
   8.278 -##         return d
   8.279 -    
   8.280      def xfr_migrate_ok(self, xfrd, val):
   8.281          dom = int(sxp.child0(val))
   8.282          self.state = 'ok'
   8.283 @@ -327,17 +340,15 @@ class XendMigrateInfo(XfrdInfo):
   8.284              self.deferred.callback(self)
   8.285  
   8.286      def connectionLost(self, reason=None):
   8.287 -        print 'XfrdMigrateInfo>connectionLost>', reason
   8.288          XfrdInfo.connectionLost(self, reason)
   8.289          if self.state =='ok':
   8.290              log.info('Migrate OK: ' + str(self.sxpr()))
   8.291          else:
   8.292              self.state = 'error'
   8.293 -            self.error(XendError("migrate failed"))
   8.294 +            self.error("migrate failed")
   8.295              log.info('Migrate ERROR: ' + str(self.sxpr()))
   8.296          eserver.inject('xend.domain.migrate',
   8.297 -                       [ self.dominfo.name, self.dominfo.id,
   8.298 -                         self.state, self.sxpr() ])
   8.299 +                       [ self.dominfo.name, self.dominfo.id, self.state, self.sxpr() ])
   8.300  
   8.301  class XendSaveInfo(XfrdInfo):
   8.302      """Representation of a save in-progress and its interaction with xfrd.
   8.303 @@ -361,16 +372,15 @@ class XendSaveInfo(XfrdInfo):
   8.304          return sxpr
   8.305  
   8.306      def request(self, xfrd):
   8.307 -        print '***request>', self.vmconfig()
   8.308          vmconfig = self.vmconfig()
   8.309          if not vmconfig:
   8.310 +            self.error(XendError("vm config not found"))
   8.311              xfrd.loseConnection()
   8.312              return
   8.313 -        print '***request> begin'
   8.314          log.info('Save BEGIN: ' + str(self.sxpr()))
   8.315          eserver.inject('xend.domain.save',
   8.316 -                       [self.dominfo.name, self.dominfo.id,
   8.317 -                        "begin", self.sxpr()])
   8.318 +                       [ self.dominfo.name, self.dominfo.id,
   8.319 +                         "begin", self.sxpr() ])
   8.320          xfrd.request(['xfr.save', self.src_dom, vmconfig, self.file ])
   8.321          
   8.322      def xfr_save_ok(self, xfrd, val):
   8.323 @@ -380,13 +390,12 @@ class XendSaveInfo(XfrdInfo):
   8.324              self.deferred.callback(self)
   8.325  
   8.326      def connectionLost(self, reason=None):
   8.327 -        print 'XfrdSaveInfo>connectionLost>', reason
   8.328          XfrdInfo.connectionLost(self, reason)
   8.329          if self.state =='ok':
   8.330              log.info('Save OK: ' + str(self.sxpr()))
   8.331          else:
   8.332              self.state = 'error'
   8.333 -            self.error(XendError("save failed"))
   8.334 +            self.error("save failed")
   8.335              log.info('Save ERROR: ' + str(self.sxpr()))
   8.336          eserver.inject('xend.domain.save',
   8.337                         [ self.dominfo.name, self.dominfo.id,
   8.338 @@ -409,8 +418,9 @@ class XendRestoreInfo(XfrdInfo):
   8.339           return sxpr
   8.340  
   8.341      def request(self, xfrd):
   8.342 -        print '***request>', self.file
   8.343          log.info('restore BEGIN: ' + str(self.sxpr()))
   8.344 +        eserver.inject('xend.restore', [ 'begin', self.sxpr()])
   8.345 +                       
   8.346          xfrd.request(['xfr.restore', self.file ])
   8.347          
   8.348      def xfr_restore_ok(self, xfrd, val):
   8.349 @@ -419,8 +429,17 @@ class XendRestoreInfo(XfrdInfo):
   8.350          self.state = 'ok'
   8.351          if not self.deferred.called:
   8.352              self.deferred.callback(dominfo)
   8.353 +         
   8.354 +    def connectionLost(self, reason=None):
   8.355 +        XfrdInfo.connectionLost(self, reason)
   8.356 +        if self.state =='ok':
   8.357 +            log.info('Restore OK: ' + self.file)
   8.358 +        else:
   8.359 +            self.state = 'error'
   8.360 +            self.error("restore failed")
   8.361 +            log.info('Restore ERROR: ' + str(self.sxpr()))
   8.362 +        eserver.inject('xend.restore', [ self.state,  self.sxpr()])
   8.363  
   8.364 -         
   8.365  class XendMigrate:
   8.366      """External api for interaction with xfrd for migrate and save.
   8.367      Singleton.
   8.368 @@ -445,7 +464,6 @@ class XendMigrate:
   8.369          self.db.saveall("", self.session_db)
   8.370  
   8.371      def sync_session(self, xid):
   8.372 -        print 'sync_session>', type(xid), xid, self.session_db[xid]
   8.373          self.db.save(xid, self.session_db[xid])
   8.374  
   8.375      def close(self):
   8.376 @@ -458,7 +476,6 @@ class XendMigrate:
   8.377          self.sync_session(xid)
   8.378  
   8.379      def _delete_session(self, xid):
   8.380 -        print '***_delete_session>', xid
   8.381          if xid in self.session:
   8.382              del self.session[xid]
   8.383          if xid in self.session_db:
   8.384 @@ -482,16 +499,23 @@ class XendMigrate:
   8.385          @param info: session
   8.386          @return: deferred
   8.387          """
   8.388 -        def cbremove(val):
   8.389 -            print '***cbremove>', val
   8.390 +        dfr = defer.Deferred()
   8.391 +        def cbok(val):
   8.392              self._delete_session(info.xid)
   8.393 +            if not dfr.called:
   8.394 +                dfr.callback(val)
   8.395              return val
   8.396 +        def cberr(err):
   8.397 +            self._delete_session(info.xid)
   8.398 +            if not dfr.called:
   8.399 +                dfr.errback(err)
   8.400 +            return err
   8.401          self._add_session(info)
   8.402 -        info.deferred.addCallback(cbremove)
   8.403 -        info.deferred.addErrback(cbremove)
   8.404 +        info.deferred.addCallback(cbok)
   8.405 +        info.deferred.addErrback(cberr)
   8.406          xcf = XfrdClientFactory(info)
   8.407          reactor.connectTCP('localhost', XFRD_PORT, xcf)
   8.408 -        return info.deferred
   8.409 +        return dfr
   8.410      
   8.411      def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0):
   8.412          """Begin to migrate a domain to another host.
     9.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Fri Mar 18 09:18:26 2005 +0000
     9.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Fri Mar 18 11:18:23 2005 +0000
     9.3 @@ -29,13 +29,8 @@ class SrvDomain(SrvDir):
     9.4                      [['dom', 'int'],
     9.5                       ['config', 'sxpr']])
     9.6          deferred = fn(req.args, {'dom': self.dom.dom})
     9.7 -        deferred.addErrback(self._op_configure_err, req)
     9.8          return deferred
     9.9  
    9.10 -    def _op_configure_err(self, err, req):
    9.11 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
    9.12 -        return str(err)
    9.13 -        
    9.14      def op_unpause(self, op, req):
    9.15          val = self.xd.domain_unpause(self.dom.name)
    9.16          return val
    9.17 @@ -68,16 +63,11 @@ class SrvDomain(SrvDir):
    9.18                       ['file', 'str']])
    9.19          deferred = fn(req.args, {'dom': self.dom.id})
    9.20          deferred.addCallback(self._op_save_cb, req)
    9.21 -        deferred.addErrback(self._op_save_err, req)
    9.22          return deferred
    9.23  
    9.24      def _op_save_cb(self, val, req):
    9.25          return 0
    9.26  
    9.27 -    def _op_save_err(self, err, req):
    9.28 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
    9.29 -        return str(err)
    9.30 -        
    9.31      def op_migrate(self, op, req):
    9.32          fn = FormFn(self.xd.domain_migrate,
    9.33                      [['dom', 'str'],
    9.34 @@ -85,9 +75,7 @@ class SrvDomain(SrvDir):
    9.35                       ['live', 'int'],
    9.36                       ['resource', 'int']])
    9.37          deferred = fn(req.args, {'dom': self.dom.id})
    9.38 -        print 'op_migrate>', deferred
    9.39          deferred.addCallback(self._op_migrate_cb, req)
    9.40 -        deferred.addErrback(self._op_migrate_err, req)
    9.41          return deferred
    9.42  
    9.43      def _op_migrate_cb(self, info, req):
    9.44 @@ -101,11 +89,6 @@ class SrvDomain(SrvDir):
    9.45          print '_op_migrate_cb> url=', url
    9.46          return url
    9.47  
    9.48 -    def _op_migrate_err(self, err, req):
    9.49 -        print '_op_migrate_err>', err, req
    9.50 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
    9.51 -        return str(err)
    9.52 -
    9.53      def op_pincpu(self, op, req):
    9.54          fn = FormFn(self.xd.domain_pincpu,
    9.55                      [['dom', 'str'],
    10.1 --- a/tools/python/xen/xend/server/blkif.py	Fri Mar 18 09:18:26 2005 +0000
    10.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Mar 18 11:18:23 2005 +0000
    10.3 @@ -181,6 +181,8 @@ class BlkifBackendInterface(controller.B
    10.4              self.close()
    10.5          d = defer.Deferred()
    10.6          d.addCallback(cb_destroy)
    10.7 +        if self.evtchn:
    10.8 +            channel.eventChannelClose(self.evtchn)
    10.9          self.send_be_disconnect(response=d)
   10.10          
   10.11      def send_be_disconnect(self, response=None):
    11.1 --- a/tools/python/xen/xend/server/channel.py	Fri Mar 18 09:18:26 2005 +0000
    11.2 +++ b/tools/python/xen/xend/server/channel.py	Fri Mar 18 11:18:23 2005 +0000
    11.3 @@ -11,7 +11,31 @@ VIRQ_CONSOLE    = 3  # (DOM0) bytes rece
    11.4  VIRQ_DOM_EXC    = 4  # (DOM0) Exceptional event for some domain.
    11.5  
    11.6  def eventChannel(dom1, dom2):
    11.7 -    return xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
    11.8 +    """Create an event channel between domains.
    11.9 +    The returned dict contains dom1, dom2, port1 and port2 on success.
   11.10 +
   11.11 +    @return dict (empty on error)
   11.12 +    """
   11.13 +    evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
   11.14 +    if evtchn:
   11.15 +        evtchn['dom1'] = dom1
   11.16 +        evtchn['dom2'] = dom2
   11.17 +    return evtchn
   11.18 +
   11.19 +def eventChannelClose(evtchn):
   11.20 +    """Close an event channel that was opened by eventChannel().
   11.21 +    """
   11.22 +    def evtchn_close(dom, port):
   11.23 +        if (dom is None) or (port is None): return
   11.24 +        try:
   11.25 +            xc.evtchn_close(dom=dom, port=port)
   11.26 +        except Exception, ex:
   11.27 +            pass
   11.28 +        
   11.29 +    if not evtchn: return
   11.30 +    evtchn_close(evtchn.get('dom1'), evtchn.get('port1'))
   11.31 +    evtchn_close(evtchn.get('dom2'), evtchn.get('port2'))
   11.32 +    
   11.33  
   11.34  class ChannelFactory:
   11.35      """Factory for creating channels.
    12.1 --- a/tools/python/xen/xend/server/netif.py	Fri Mar 18 09:18:26 2005 +0000
    12.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Mar 18 11:18:23 2005 +0000
    12.3 @@ -130,7 +130,13 @@ class NetDev(controller.SplitDev):
    12.4          self.bridge = None
    12.5          self.script = None
    12.6          self.ipaddr = []
    12.7 +        self.vifname = None
    12.8  
    12.9 +        self.vifname = sxp.child_value(config, 'vifname')
   12.10 +        if self.vifname is None:
   12.11 +            self.vifname = "vif%d.%d" % (self.controller.dom, self.vif)
   12.12 +        if len(self.vifname) > 15:
   12.13 +            raise XendError('invalid vifname: too long: ' + self.vifname)
   12.14          mac = self._get_config_mac(config)
   12.15          if mac is None:
   12.16              raise XendError("invalid mac")
   12.17 @@ -189,7 +195,9 @@ class NetDev(controller.SplitDev):
   12.18          val = ['vif',
   12.19                 ['idx', self.idx],
   12.20                 ['vif', vif],
   12.21 -               ['mac', mac]]
   12.22 +               ['mac', mac],
   12.23 +               ['vifname', self.vifname],
   12.24 +               ]
   12.25          if self.bridge:
   12.26              val.append(['bridge', self.bridge])
   12.27          if self.script:
   12.28 @@ -207,7 +215,7 @@ class NetDev(controller.SplitDev):
   12.29      def get_vifname(self):
   12.30          """Get the virtual interface device name.
   12.31          """
   12.32 -        return "vif%d.%d" % (self.controller.dom, self.vif)
   12.33 +        return self.vifname
   12.34  
   12.35      def get_mac(self):
   12.36          """Get the MAC address as a string.
   12.37 @@ -267,7 +275,9 @@ class NetDev(controller.SplitDev):
   12.38          msg = packMsg('netif_be_create_t',
   12.39                        { 'domid'        : self.controller.dom,
   12.40                          'netif_handle' : self.vif,
   12.41 -                        'mac'          : self.mac })
   12.42 +                        'mac'          : self.mac,
   12.43 +                        'vifname'      : self.vifname
   12.44 +                        })
   12.45          self.getBackendInterface().writeRequest(msg, response=d)
   12.46          return d
   12.47  
   12.48 @@ -288,6 +298,8 @@ class NetDev(controller.SplitDev):
   12.49              if change:
   12.50                  self.reportStatus()
   12.51          log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
   12.52 +        if self.evtchn:
   12.53 +            channel.eventChannelClose(self.evtchn)
   12.54          self.vifctl('down')
   12.55          d = self.send_be_disconnect()
   12.56          d.addCallback(cb_destroy)
    13.1 --- a/tools/python/xen/xm/create.py	Fri Mar 18 09:18:26 2005 +0000
    13.2 +++ b/tools/python/xen/xm/create.py	Fri Mar 18 11:18:23 2005 +0000
    13.3 @@ -5,6 +5,7 @@
    13.4  import random
    13.5  import string
    13.6  import sys
    13.7 +import socket
    13.8  
    13.9  from xen.xend import sxp
   13.10  from xen.xend import PrettyPrint
   13.11 @@ -81,6 +82,13 @@ gopts.opt('console_autoconnect', short='
   13.12            fn=set_true, default=0,
   13.13            use="Connect to the console after the domain is created.")
   13.14  
   13.15 +gopts.opt('vnc', val='DISPLAY',
   13.16 +          fn=set_int, default=None,
   13.17 +          use="""Spawn a vncviewer listening for a vnc server in the domain.
   13.18 +          The address of the vncviewer is passed to the domain on the kernel command
   13.19 +          line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
   13.20 +          """)
   13.21 +
   13.22  gopts.var('name', val='NAME',
   13.23            fn=set_value, default=None,
   13.24            use="Domain name. Must be unique.")
   13.25 @@ -151,7 +159,7 @@ gopts.var('ipaddr', val="IPADDR",
   13.26            fn=append_value, default=[],
   13.27            use="Add an IP address to the domain.")
   13.28  
   13.29 -gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
   13.30 +gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM,vifname=NAME",
   13.31            fn=append_value, default=[],
   13.32            use="""Add a network interface with the given MAC address and bridge.
   13.33            The vif is configured by calling the given configuration script.
   13.34 @@ -159,6 +167,8 @@ gopts.var('vif', val="mac=MAC,bridge=BRI
   13.35            If bridge is not specified the default bridge is used.
   13.36            If script is not specified the default script is used.
   13.37            If backend is not specified the default backend driver domain is used.
   13.38 +          If vifname is not specified the backend virtual interface will have name vifD.N
   13.39 +          where D is the domain id and N is the interface id.
   13.40            This option may be repeated to add more than one vif.
   13.41            Specifying vifs will increase the number of interfaces as needed.""")
   13.42  
   13.43 @@ -289,14 +299,18 @@ def configure_vifs(config_devs, vals):
   13.44              script = d.get('script')
   13.45              backend = d.get('backend')
   13.46              ip = d.get('ip')
   13.47 +            vifname = d.get('vifname')
   13.48          else:
   13.49              mac = randomMAC()
   13.50              bridge = None
   13.51              script = None
   13.52              backend = None
   13.53              ip = None
   13.54 +            vifname = None
   13.55          config_vif = ['vif']
   13.56          config_vif.append(['mac', mac])
   13.57 +        if vifname:
   13.58 +            config_vif.append(['vifname', vifname])
   13.59          if bridge:
   13.60              config_vif.append(['bridge', bridge])
   13.61          if script:
   13.62 @@ -383,7 +397,7 @@ def preprocess_vifs(opts, vals):
   13.63              (k, v) = b.strip().split('=', 1)
   13.64              k = k.strip()
   13.65              v = v.strip()
   13.66 -            if k not in ['mac', 'bridge', 'script', 'backend', 'ip']:
   13.67 +            if k not in ['mac', 'bridge', 'script', 'backend', 'ip', 'vifname']:
   13.68                  opts.err('Invalid vif specifier: ' + vif)
   13.69              d[k] = v
   13.70          vifs.append(d)
   13.71 @@ -409,6 +423,27 @@ def preprocess_nfs(opts, vals):
   13.72          opts.err('Must set nfs root and nfs server')
   13.73      nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root
   13.74      vals.extra = nfs + ' ' + vals.extra
   13.75 +
   13.76 +
   13.77 +def get_host_addr():
   13.78 +    host = socket.gethostname()
   13.79 +    addr = socket.gethostbyname(host)
   13.80 +    return addr
   13.81 +
   13.82 +def spawn_vnc(display):
   13.83 +    os.system("vncviewer -listen %d &" % display)
   13.84 +    return 5500 + display
   13.85 +    
   13.86 +def preprocess_vnc(opts, vals):
   13.87 +    """If vnc was specified, spawn a vncviewer in listen mode
   13.88 +    and pass its address to the domain on the kernel command line.
   13.89 +    """
   13.90 +    if vals.vnc is None: return
   13.91 +    vnc_host = get_host_addr()
   13.92 +    vnc_port = spawn_vnc(vals.vnc)
   13.93 +    if vnc_port > 0:
   13.94 +        vnc = 'VNC_VIEWER=%s:%d' % (vnc_host, vnc_port)
   13.95 +        vals.extra = vnc + ' ' + vals.extra
   13.96      
   13.97  def preprocess(opts, vals):
   13.98      if not vals.kernel:
   13.99 @@ -418,6 +453,7 @@ def preprocess(opts, vals):
  13.100      preprocess_vifs(opts, vals)
  13.101      preprocess_ip(opts, vals)
  13.102      preprocess_nfs(opts, vals)
  13.103 +    preprocess_vnc(opts, vals)
  13.104           
  13.105  def make_domain(opts, config):
  13.106      """Create, build and start a domain.
    14.1 --- a/xen/include/public/io/domain_controller.h	Fri Mar 18 09:18:26 2005 +0000
    14.2 +++ b/xen/include/public/io/domain_controller.h	Fri Mar 18 11:18:23 2005 +0000
    14.3 @@ -466,9 +466,10 @@ typedef struct {
    14.4      u32        netif_handle;  /*  4: Domain-specific interface handle.   */
    14.5      u8         mac[6];        /*  8 */
    14.6      u16        __pad1;        /* 14 */
    14.7 +    char       vifname[16];   /* 16 */
    14.8      /* OUT */
    14.9 -    u32        status;        /* 16 */
   14.10 -} PACKED netif_be_create_t; /* 20 bytes */
   14.11 +    u32        status;        /* 32 */
   14.12 +} PACKED netif_be_create_t; /* 36 bytes */
   14.13  
   14.14  /*
   14.15   * CMSG_NETIF_BE_DESTROY: