ia64/xen-unstable

changeset 1720:06e9774f9633

bitkeeper revision 1.1052 (40ed38a6k6vT2ycbqz1BZA6U9KRVgg)

Start of save support in xfrd.
author mjw@wray-m-3.hpl.hp.com
date Thu Jul 08 12:05:58 2004 +0000 (2004-07-08)
parents 430a2d09d6ad
children 3b98f6df869f
files .rootkeys tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/packing.py tools/xfrd/xfrdClient.py
line diff
     1.1 --- a/.rootkeys	Thu Jul 08 12:00:59 2004 +0000
     1.2 +++ b/.rootkeys	Thu Jul 08 12:05:58 2004 +0000
     1.3 @@ -242,7 +242,6 @@ 40c9c4686jruMyZIqiaZRMiMoqMJtg tools/pyt
     1.4  40c9c468xzANp6o2D_MeCYwNmOIUsQ tools/python/xen/xend/XendVnet.py
     1.5  40c9c468x191zetrVlMnExfsQWHxIQ tools/python/xen/xend/__init__.py
     1.6  40c9c468S2YnCEKmk4ey8XQIST7INg tools/python/xen/xend/encode.py
     1.7 -40e9808elkoRulOo1GxRTp5ulJGVNw tools/python/xen/xend/packing.py
     1.8  40c9c468DCpMe542varOolW1Xc68ew tools/python/xen/xend/server/SrvBase.py
     1.9  40c9c468IxQabrKJSWs0aEjl-27mRQ tools/python/xen/xend/server/SrvConsole.py
    1.10  40c9c4689Io5bxfbYIfRiUvsiLX0EQ tools/python/xen/xend/server/SrvConsoleDir.py
     2.1 --- a/tools/python/xen/xend/XendMigrate.py	Thu Jul 08 12:00:59 2004 +0000
     2.2 +++ b/tools/python/xen/xend/XendMigrate.py	Thu Jul 08 12:05:58 2004 +0000
     2.3 @@ -19,79 +19,41 @@ XFRD_PORT = 8002
     2.4  XFR_PROTO_MAJOR = 1
     2.5  XFR_PROTO_MINOR = 0
     2.6  
     2.7 -class Migrate(Protocol):
     2.8 +class Xfrd(Protocol):
     2.9 +    """Protocol handler for a connection to the migration/save daemon xfrd.
    2.10 +    """
    2.11  
    2.12 -    def __init__(self, minfo):
    2.13 +    def __init__(self, xinfo):
    2.14          self.parser = sxp.Parser()
    2.15 -        self.minfo = minfo
    2.16 +        self.xinfo = xinfo
    2.17  
    2.18      def connectionMade(self):
    2.19          # Send hello.
    2.20          self.request(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
    2.21 -        # Send migrate.
    2.22 -        vmconfig = self.minfo.vmconfig()
    2.23 -        if not vmconfig:
    2.24 -            self.loseConnection()
    2.25 -            return
    2.26 -        self.request(['xfr.migrate',
    2.27 -                      self.minfo.src_dom,
    2.28 -                      vmconfig,
    2.29 -                      self.minfo.dst_host,
    2.30 -                      self.minfo.dst_port])
    2.31 +        # Send request.
    2.32 +        self.xinfo.request(self)
    2.33  
    2.34      def request(self, req):
    2.35          sxp.show(req, out=self.transport)
    2.36 -        self.transport.write(' \n')
    2.37  
    2.38      def loseConnection(self):
    2.39          self.transport.loseConnection()
    2.40  
    2.41      def connectionLost(self, reason):
    2.42 -        self.minfo.closed(reason)
    2.43 -
    2.44 -    def dispatch(self, val):
    2.45 -        op = sxp.name(val)
    2.46 -        op = op.replace('.', '_')
    2.47 -        if op.startswith('xfr_'):
    2.48 -            fn = getattr(self, op, self.unknown)
    2.49 -        else:
    2.50 -            fn = self.unknown()
    2.51 -        fn(val)
    2.52 +        self.xinfo.connectionLost(reason)
    2.53  
    2.54      def dataReceived(self, data):
    2.55          self.parser.input(data)
    2.56          if self.parser.ready():
    2.57              val = self.parser.get_val()
    2.58 -            self.dispatch(val)
    2.59 +            self.xinfo.dispatch(val)
    2.60          if self.parser.at_eof():
    2.61              self.loseConnection()
    2.62              
    2.63 -    def unknown(self, val):
    2.64 -        print 'unknown>', val
    2.65  
    2.66 -    def xfr_progress(self, val):
    2.67 -        print 'xfr_progress>', val
    2.68 -
    2.69 -    def xfr_err(self, val):
    2.70 -        # If we get an error with non-zero code the migrate failed.
    2.71 -        # An error with code zero indicates hello success.
    2.72 -        print 'xfr_err>', val
    2.73 -        v = sxp.child(val)
    2.74 -        print 'xfr_err>', type(v), v
    2.75 -        err = int(sxp.child(val))
    2.76 -        if not err: return
    2.77 -        self.minfo.error(err);
    2.78 -        self.loseConnection()
    2.79 -
    2.80 -    def xfr_ok(self, val):
    2.81 -        # An ok indicates migrate completed successfully, and contains
    2.82 -        # the new domain id on the remote system.
    2.83 -        print 'xfr_ok>', val
    2.84 -        dom = int(sxp.child(val))
    2.85 -        self.minfo.ok(dom)
    2.86 -        self.loseConnection()
    2.87 -
    2.88 -class MigrateClientFactory(ClientFactory):
    2.89 +class XfrdClientFactory(ClientFactory):
    2.90 +    """Factory for clients of the migration/save daemon xfrd.
    2.91 +    """
    2.92  
    2.93      def __init__(self, minfo):
    2.94          #ClientFactory.__init__(self)
    2.95 @@ -110,38 +72,11 @@ class MigrateClientFactory(ClientFactory
    2.96      def clientConnectionFailed(self, connector, reason):
    2.97          print 'clientConnectionFailed>', 'connector=', connector, 'reason=', reason
    2.98  
    2.99 -
   2.100 -class XendMigrateInfo:
   2.101 -
   2.102 -    # states: begin, active, failed, succeeded?
   2.103 -
   2.104 -    def __init__(self, id, dom, host, port):
   2.105 -        self.id = id
   2.106 -        self.state = 'begin'
   2.107 -        self.src_host = socket.gethostname()
   2.108 -        self.src_dom = dom
   2.109 -        self.dst_host = host
   2.110 -        self.dst_port = port
   2.111 -        self.dst_dom = None
   2.112 -        self.start = 0
   2.113 -        self.deferred = defer.Deferred()
   2.114 -        
   2.115 -    def set_state(self, state):
   2.116 -        self.state = state
   2.117 -
   2.118 -    def get_state(self):
   2.119 -        return self.state
   2.120 -
   2.121 -    def sxpr(self):
   2.122 -        sxpr = ['migrate', ['id', self.id], ['state', self.state] ]
   2.123 -        sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
   2.124 -        sxpr.append(sxpr_src)
   2.125 -        sxpr_dst = ['dst', ['host', self.dst_host] ]
   2.126 -        if self.dst_dom:
   2.127 -            sxpr_dst.append(['domain', self.dst_dom])
   2.128 -        sxpr.append(sxpr_dst)
   2.129 -        return sxpr
   2.130 -
   2.131 +class XfrdInfo:
   2.132 +    """Abstract class for info about a session with xfrd.
   2.133 +    Has subclasses for save and migrate.
   2.134 +    """
   2.135 +    
   2.136      def vmconfig(self):
   2.137          print 'vmconfig>'
   2.138          from xen.xend import XendDomain
   2.139 @@ -159,18 +94,129 @@ class XendMigrateInfo:
   2.140      def error(self, err):
   2.141          self.state = 'error'
   2.142  
   2.143 -    def ok(self, dom):
   2.144 +    def dispatch(self, xfrd, val):
   2.145 +        op = sxp.name(val)
   2.146 +        op = op.replace('.', '_')
   2.147 +        if op.startswith('xfr_'):
   2.148 +            fn = getattr(self, op, self.unknown)
   2.149 +        else:
   2.150 +            fn = self.unknown()
   2.151 +        fn(xfrd, val)
   2.152 +
   2.153 +    def unknown(self, xfrd, val):
   2.154 +        print 'unknown>', val
   2.155 +
   2.156 +    def xfr_err(self, xfrd, val):
   2.157 +        # If we get an error with non-zero code the migrate failed.
   2.158 +        # An error with code zero indicates hello success.
   2.159 +        print 'xfr_err>', val
   2.160 +        v = sxp.child(val)
   2.161 +        print 'xfr_err>', type(v), v
   2.162 +        err = int(sxp.child(val))
   2.163 +        if not err: return
   2.164 +        self.error(err);
   2.165 +        xfrd.loseConnection()
   2.166 +
   2.167 +    def xfr_progress(self, val):
   2.168 +        print 'xfr_progress>', val
   2.169 +
   2.170 +    def xfr_domain_pause(self, val):
   2.171 +        print 'xfr__domain_pause>', val
   2.172 +
   2.173 +    def xfr_domain_suspend(self, val):
   2.174 +        print 'xfr_domain_suspend>', val
   2.175 +
   2.176 +class XendMigrateInfo(XfrdInfo):
   2.177 +    """Representation of a migrate in-progress and its interaction with xfrd.
   2.178 +    """
   2.179 +
   2.180 +    def __init__(self, id, dom, host, port):
   2.181 +        self.id = id
   2.182 +        self.state = 'begin'
   2.183 +        self.src_host = socket.gethostname()
   2.184 +        self.src_dom = dom
   2.185 +        self.dst_host = host
   2.186 +        self.dst_port = port
   2.187 +        self.dst_dom = None
   2.188 +        self.start = 0
   2.189 +        self.deferred = defer.Deferred()
   2.190 +        
   2.191 +    def sxpr(self):
   2.192 +        sxpr = ['migrate', ['id', self.id], ['state', self.state] ]
   2.193 +        sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
   2.194 +        sxpr.append(sxpr_src)
   2.195 +        sxpr_dst = ['dst', ['host', self.dst_host] ]
   2.196 +        if self.dst_dom:
   2.197 +            sxpr_dst.append(['domain', self.dst_dom])
   2.198 +        sxpr.append(sxpr_dst)
   2.199 +        return sxpr
   2.200 +
   2.201 +    def request(self, xfrd):
   2.202 +        vmconfig = self.vmconfig()
   2.203 +        if not vmconfig:
   2.204 +            xfrd.loseConnection()
   2.205 +            return
   2.206 +        xfrd.request(['xfr.migrate',
   2.207 +                      self.src_dom,
   2.208 +                      vmconfig,
   2.209 +                      self.dst_host,
   2.210 +                      self.d.dst_port])
   2.211 +        
   2.212 +    def xfr_migrate_ok(self, val):
   2.213 +        dom = int(sxp.child0(val))
   2.214          self.state = 'ok'
   2.215          self.dst_dom = dom
   2.216  
   2.217 -    def closed(self, reason=None):
   2.218 +    def connectionLost(self, reason=None):
   2.219          if self.state =='ok':
   2.220              eserver.inject('xend.migrate.ok', self.sxpr())
   2.221          else:
   2.222              self.state = 'error'
   2.223              eserver.inject('xend.migrate.error', self.sxpr())
   2.224  
   2.225 +class XendSaveInfo(XfrdInfo):
   2.226 +    """Representation of a save in-progress and its interaction with xfrd.
   2.227 +    """
   2.228 +    
   2.229 +    def __init__(self, id, dom, file):
   2.230 +        self.id = id
   2.231 +        self.state = 'begin'
   2.232 +        self.src_dom = dom
   2.233 +        self.file = file
   2.234 +        self.start = 0
   2.235 +        self.deferred = defer.Deferred()
   2.236 +        
   2.237 +    def sxpr(self):
   2.238 +        sxpr = ['save',
   2.239 +                ['id', self.id],
   2.240 +                ['state', self.state],
   2.241 +                ['domain', self.src_dom],
   2.242 +                ['file', self.file] ]
   2.243 +        return sxpr
   2.244 +
   2.245 +    def request(self, xfrd):
   2.246 +        vmconfig = self.vmconfig()
   2.247 +        if not vmconfig:
   2.248 +            xfrd.loseConnection()
   2.249 +            return
   2.250 +        xfrd.request(['xfr.save', self.src_dom, vmconfig, self.file ])
   2.251 +        
   2.252 +    def xfr_save_ok(self, val):
   2.253 +        dom = int(sxp.child0(val))
   2.254 +        self.state = 'ok'
   2.255 +
   2.256 +    def connectionLost(self, reason=None):
   2.257 +        if self.state =='ok':
   2.258 +            eserver.inject('xend.save.ok', self.sxpr())
   2.259 +        else:
   2.260 +            self.state = 'error'
   2.261 +            eserver.inject('xend.save.error', self.sxpr())
   2.262 +    
   2.263 +
   2.264  class XendMigrate:
   2.265 +    """External api for interaction with xfrd for migrate and save.
   2.266 +    Singleton.
   2.267 +    """
   2.268      # Represents migration in progress.
   2.269      # Use log for indications of begin/end/errors?
   2.270      # Need logging of: domain create/halt, migrate begin/end/fail
   2.271 @@ -224,7 +270,7 @@ class XendMigrate:
   2.272          id = self.nextid()
   2.273          info = XendMigrateInfo(id, dom, host, port)
   2.274          self._add_migrate(id, info)
   2.275 -        mcf = MigrateClientFactory(info)
   2.276 +        mcf = XfrdClientFactory(info)
   2.277          reactor.connectTCP('localhost', XFRD_PORT, mcf)
   2.278          return info
   2.279  
     3.1 --- a/tools/python/xen/xend/packing.py	Thu Jul 08 12:00:59 2004 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,329 +0,0 @@
     3.4 -
     3.5 -# XDR-style packer/unpacker for sxpr.
     3.6 -#
     3.7 -# string -> [STRING] [len:u16] <len bytes>
     3.8 -# atom   -> [ATOM]   [len:u16] <len bytes>
     3.9 -# int    -> [UINT]   [value]
    3.10 -# list   -> [LIST]   {1 elt}* 0
    3.11 -# null   -> [NULL]
    3.12 -# none   -> [NONE]
    3.13 -# bool   -> [BOOL]   { 0:u8 | 1:u8 }
    3.14 -#
    3.15 -# types packed as u16.
    3.16 -#
    3.17 -# So (a b c) -> [LIST] 1 a 1 b 1 c 0
    3.18 -#    ()      -> [LIST] 0
    3.19 -
    3.20 -import struct
    3.21 -
    3.22 -try:
    3.23 -    from cStringIO import StringIO as _StringIO
    3.24 -except ImportError:
    3.25 -    from StringIO import StringIO as _StringIO
    3.26 -
    3.27 -import types
    3.28 -
    3.29 -class Error(Exception):
    3.30 -    
    3.31 -    def __init__(self, msg):
    3.32 -        self.msg = msg
    3.33 -        
    3.34 -    def __repr__(self):
    3.35 -        return repr(self.msg)
    3.36 -    
    3.37 -    def __str__(self):
    3.38 -        return str(self.msg)
    3.39 -
    3.40 -
    3.41 -class ConversionError(Error):
    3.42 -    pass
    3.43 -
    3.44 -BOOL_SIZE   = 1
    3.45 -BOOL_FMT    = '>B'
    3.46 -
    3.47 -BYTE_SIZE   = 1
    3.48 -BYTE_FMT    = '>b'
    3.49 -UBYTE_FMT   = '>B'
    3.50 -
    3.51 -SHORT_SIZE  = 2
    3.52 -SHORT_FMT   = '>h'
    3.53 -USHORT_FMT  = '>H'
    3.54 -
    3.55 -INT_SIZE   =  4
    3.56 -INT_FMT    = '>l'
    3.57 -UINT_FMT   = '>L'
    3.58 -
    3.59 -NONE_CODE   = 0
    3.60 -NULL_CODE   = 1
    3.61 -INT_CODE    = 2
    3.62 -STRING_CODE = 3
    3.63 -ATOM_CODE   = 4
    3.64 -BOOL_CODE   = 5
    3.65 -LIST_CODE   = 10
    3.66 -
    3.67 -class Packer:
    3.68 -    
    3.69 -    def __init__(self, io=None):
    3.70 -        self.reset(io=io)
    3.71 -
    3.72 -    def reset(self, io=None):
    3.73 -        if io is None:
    3.74 -            io = _StringIO()
    3.75 -        self.io = io
    3.76 -
    3.77 -    def get_buffer(self):
    3.78 -        return self.io.getvalue()
    3.79 -
    3.80 -    def get_io(self):
    3.81 -        return self.io
    3.82 -
    3.83 -    def struct_pack(self, fmt, x):
    3.84 -        try:
    3.85 -            self.io.write(struct.pack(fmt, x))
    3.86 -        except struct.error, msg:
    3.87 -            raise ConversionError, msg
    3.88 -
    3.89 -    def pack_none(self):
    3.90 -        pass
    3.91 -    
    3.92 -    def pack_bool(self, x):
    3.93 -        # { '1' | '0' }
    3.94 -        print 'bool>', x
    3.95 -        if x:
    3.96 -            self.io.write('\1')
    3.97 -        else:
    3.98 -            self.io.write('\0')
    3.99 -
   3.100 -    def pack_byte(self, x):
   3.101 -        self.struct_pack(BYTE_FMT, x & 0xff)
   3.102 -
   3.103 -    def pack_char(self, x):
   3.104 -        print 'char>', x
   3.105 -        self.io.write(x)
   3.106 -        
   3.107 -    def pack_ubyte(self, x):
   3.108 -        print 'ubyte>', x
   3.109 -        self.struct_pack(UBYTE_FMT, x & 0xff)
   3.110 -
   3.111 -    def pack_ushort(self, x):
   3.112 -        print 'ushort>', x
   3.113 -        self.struct_pack(USHORT_FMT, x & 0xffff)
   3.114 -        
   3.115 -    def pack_short(self, x):
   3.116 -        print 'short>', x
   3.117 -        self.struct_pack(SHORT_FMT, x & 0xffff)
   3.118 -
   3.119 -    def pack_uint(self, x):
   3.120 -        print 'uint>', x
   3.121 -        self.struct_pack(UINT_FMT, x)
   3.122 -        
   3.123 -    def pack_int(self, x):
   3.124 -        print 'int>', x
   3.125 -        self.struct_pack(INT_FMT, x)
   3.126 -
   3.127 -    def pack_uhyper(self, x):
   3.128 -        print 'uhyper>', x
   3.129 -        self.pack_uint(x>>32 & 0xffffffffL)
   3.130 -        self.pack_uint(x & 0xffffffffL)
   3.131 -
   3.132 -    pack_hyper = pack_uhyper
   3.133 -
   3.134 -    def pack_fstring(self, n, x):
   3.135 -        print 'fstring>', x
   3.136 -        self.io.write(x)
   3.137 -
   3.138 -    pack_fopaque = pack_fstring
   3.139 -
   3.140 -    def pack_string(self, x):
   3.141 -        print 'string>', x
   3.142 -        n = len(x)
   3.143 -        self.pack_ushort(n)
   3.144 -        self.pack_fstring(n, x)
   3.145 -
   3.146 -    pack_opaque = pack_string
   3.147 -    pack_bytes = pack_string
   3.148 -
   3.149 -    def pack_list(self, x, pack_item):
   3.150 -        print 'list>', x
   3.151 -        # { '1' <item> }* '0'
   3.152 -        for item in x:
   3.153 -            self.pack_bool(1)
   3.154 -            pack_item(item)
   3.155 -        self.pack_bool(0)
   3.156 -
   3.157 -    def pack_farray(self, x, pack_item):
   3.158 -        # <item>*
   3.159 -        # Can pass n and check length - but is it worth it?
   3.160 -        print 'farray>', list
   3.161 -        for item in x:
   3.162 -            pack_item(item)
   3.163 -
   3.164 -    def pack_array(self, x, pack_item):
   3.165 -        # n <item>*n
   3.166 -        print 'array>', x
   3.167 -        self.pack_uint(len(x))
   3.168 -        self.pack_farray(x, pack_item)
   3.169 -
   3.170 -class Unpacker:
   3.171 -
   3.172 -    def __init__(self, data):
   3.173 -        self.reset(data)
   3.174 -
   3.175 -    def reset(self, data):
   3.176 -        if isinstance(data, types.StringType):
   3.177 -            data = _StringIO(data)
   3.178 -        self.io = data
   3.179 -
   3.180 -    def get_bytes(self, n):
   3.181 -        if n < 0:
   3.182 -            raise ConversionError('negative byte count')
   3.183 -        data = self.io.read(n)
   3.184 -        return data
   3.185 -
   3.186 -    def struct_unpack(self, fmt, n):
   3.187 -        data = self.get_bytes(n)
   3.188 -        try:
   3.189 -            return struct.unpack(fmt, data)[0]
   3.190 -        except struct.error, msg:
   3.191 -            raise ConversionError, msg
   3.192 -       
   3.193 -    def unpack_none(self):
   3.194 -        return None
   3.195 -
   3.196 -    def unpack_bool(self):
   3.197 -        return self.struct_unpack(BOOL_FMT, BOOL_SIZE)
   3.198 -
   3.199 -    def unpack_char(self):
   3.200 -        return self.get_bytes(1)[0]
   3.201 -
   3.202 -    def unpack_byte(self):
   3.203 -        return self.struct_unpack(BYTE_FMT, BYTE_SIZE)
   3.204 -    
   3.205 -    def unpack_ubyte(self):
   3.206 -        return self.struct_unpack(UBYTE_FMT, BYTE_SIZE)
   3.207 -    
   3.208 -    def unpack_ushort(self):
   3.209 -        return self.struct_unpack(USHORT_FMT, SHORT_SIZE)
   3.210 -
   3.211 -    def unpack_short(self):
   3.212 -        return self.struct_unpack(SHORT_FMT, SHORT_SIZE)
   3.213 -        
   3.214 -    def unpack_uint(self):
   3.215 -        x = self.struct_unpack(UINT_FMT, UINT_SIZE)
   3.216 -        try:
   3.217 -            return int(x)
   3.218 -        except OverflowError:
   3.219 -            return x
   3.220 -
   3.221 -    def unpack_int(self):
   3.222 -        return self.struct_unpack(INT_FMT, INT_SIZE)
   3.223 -
   3.224 -    def unpack_uhyper(self):
   3.225 -        hi = self.unpack_uint()
   3.226 -        lo = self.unpack_uint()
   3.227 -        return long(hi)<<32 | lo
   3.228 -
   3.229 -    def unpack_hyper(self):
   3.230 -        x = self.unpack_uhyper()
   3.231 -        if x >= 0x8000000000000000L:
   3.232 -            x = x - 0x10000000000000000L
   3.233 -        return x
   3.234 -
   3.235 -    def unpack_fstring(self, n):
   3.236 -        return self.get_bytes(n)
   3.237 -
   3.238 -    unpack_fopaque = unpack_fstring
   3.239 -
   3.240 -    def unpack_string(self):
   3.241 -        n = self.unpack_ushort()
   3.242 -        return self.unpack_fstring(n)
   3.243 -
   3.244 -    unpack_opaque = unpack_string
   3.245 -    unpack_bytes = unpack_string
   3.246 -
   3.247 -    def unpack_list(self, unpack_item):
   3.248 -        list = []
   3.249 -        while self.unpack_bool():
   3.250 -            list.append(unpack_item())
   3.251 -        return list
   3.252 -
   3.253 -    def unpack_farray(self, n, unpack_item):
   3.254 -        list = []
   3.255 -        for i in range(n):
   3.256 -            list.append(unpack_item())
   3.257 -        return list
   3.258 -
   3.259 -    def unpack_array(self, unpack_item):
   3.260 -        n = self.unpack_ushort()
   3.261 -        return self.unpack_farray(n, unpack_item)
   3.262 -
   3.263 -class SxpPacker(Packer):
   3.264 -
   3.265 -    pack_code = Packer.pack_ushort
   3.266 -
   3.267 -    def pack(self, x):
   3.268 -        if isinstance(x, types.NoneType):
   3.269 -            self.pack_code(NONE_CODE)
   3.270 -            self.pack_none()
   3.271 -        elif isinstance(x, types.IntType):
   3.272 -            self.pack_code(INT_CODE)
   3.273 -            self.pack_int(x)
   3.274 -        elif isinstance(x, types.StringType):
   3.275 -            self.pack_code(STRING_CODE)
   3.276 -            self.pack_string(x)
   3.277 -        elif isinstance(x, types.ListType):
   3.278 -            self.pack_code(LIST_CODE)
   3.279 -            self.pack_list(x, self.pack)
   3.280 -        else:
   3.281 -           raise Error('invalid type ' + str(type(x)))
   3.282 -
   3.283 -class SxpUnpacker(Unpacker):
   3.284 -
   3.285 -    unpack_code = Unpacker.unpack_ushort
   3.286 -
   3.287 -    def unpack(self):
   3.288 -        code = self.unpack_code()
   3.289 -        if code == NONE_CODE:
   3.290 -            val = self.unpack_none()
   3.291 -        elif code == INT_CODE:
   3.292 -            val = self.unpack_int()
   3.293 -        elif code == BOOL_CODE:
   3.294 -            val = self.unpack_bool()
   3.295 -        elif code == STRING_CODE:
   3.296 -            val = self.unpack_string()
   3.297 -        elif code == ATOM_CODE:
   3.298 -            val = self.unpack_string()
   3.299 -        elif code == LIST_CODE:
   3.300 -            val = self.unpack_list(self.unpack)
   3.301 -        else:
   3.302 -            raise Error('invalid code ' + str(code))
   3.303 -        return val
   3.304 -
   3.305 -def main():
   3.306 -    d = "['vfarm', ['@', ['name', 'vfarm1']], ['memory', 1024], ['image', 'splinux'], ['args', 'root=/dev/nfs ip=dhcp'], [ 1, -1, 1000000]]"
   3.307 -    print"> len=", len(d), "d=", d
   3.308 -    obj = ['vfarm', ['@', ['name', 'vfarm1']],
   3.309 -           ['memory', 1024],
   3.310 -           ['image', 'splinux'],
   3.311 -           ['args', 'root=/dev/nfs ip=dhcp'],
   3.312 -           [ 1, -1, 1000000] ]
   3.313 -    print "> obj=", obj
   3.314 -    pack = SxpPacker()
   3.315 -    pack.pack(obj)
   3.316 -    data = pack.get_buffer()
   3.317 -    print "> len=", len(data), "data=", data
   3.318 -    unpack = SxpUnpacker(data)
   3.319 -    obj_unpack = unpack.unpack()
   3.320 -    print "> obj=", obj_unpack
   3.321 -    #obj = [100,101,102, 999.00234, { 'a': 1, 'b': 2 } ]
   3.322 -    #pack.reset()
   3.323 -    #pack.pack_item(obj)
   3.324 -    #data = pack.get_buffer()
   3.325 -    #print "> obj=", obj
   3.326 -    #print "> len=", len(data), "data=", data
   3.327 -    #unpack.reset(data)
   3.328 -    #obj_unpack = unpack.unpack_item()
   3.329 -    #print "> obj=", obj_unpack
   3.330 -    
   3.331 -if __name__ == "__main__":
   3.332 -    main()
     4.1 --- a/tools/xfrd/xfrdClient.py	Thu Jul 08 12:00:59 2004 +0000
     4.2 +++ b/tools/xfrd/xfrdClient.py	Thu Jul 08 12:05:58 2004 +0000
     4.3 @@ -14,7 +14,6 @@ import StringIO
     4.4  sys.path.append("/home/mjw/repos-bk/xeno-unstable.bk/tools/python")
     4.5  
     4.6  import xen.xend.sxp as sxp
     4.7 -from xen.xend.packing import SxpPacker, SxpUnpacker
     4.8  
     4.9  XFRD_PORT = 8002
    4.10