ia64/xen-unstable

changeset 1646:19a9925664d8

bitkeeper revision 1.1041.2.2 (40e2ec02psfxj9RKCAgBaiEIUJeF7A)

Add explicit synchronous connect/disconnect methods to port objects
in xend.
author kaf24@scramble.cl.cam.ac.uk
date Wed Jun 30 16:36:18 2004 +0000 (2004-06-30)
parents 9836ac52e77a
children 7ee821f4caea 14fb6b05a585 bb0cd2c046b0
files tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/channel.py
line diff
     1.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Wed Jun 30 15:31:23 2004 +0000
     1.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Wed Jun 30 16:36:18 2004 +0000
     1.3 @@ -38,9 +38,6 @@
     1.4  #define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
     1.5  #define EVTCHN_DEV_MAJOR 10
     1.6  #define EVTCHN_DEV_MINOR 200
     1.7 -#define PORT_NORMAL     0x0000   /* A standard event notification.      */ 
     1.8 -#define PORT_EXCEPTION  0x8000   /* An exceptional notification.        */
     1.9 -#define PORTIDX_MASK    0x7fff   /* Strip subtype to obtain port index. */
    1.10  /* /dev/xen/evtchn ioctls: */
    1.11  /* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
    1.12  #define EVTCHN_RESET  _IO('E', 1)
    1.13 @@ -81,7 +78,7 @@ static PyObject *xu_notifier_read(PyObje
    1.14      }
    1.15      
    1.16      if ( bytes == sizeof(v) )
    1.17 -        return Py_BuildValue("(i,i)", v&PORTIDX_MASK, v&~PORTIDX_MASK);
    1.18 +        return PyInt_FromLong(v);
    1.19  
    1.20   none:
    1.21      Py_INCREF(Py_None);
    1.22 @@ -145,7 +142,7 @@ static PyMethodDef xu_notifier_methods[]
    1.23      { "read",
    1.24        (PyCFunction)xu_notifier_read,
    1.25        METH_VARARGS,
    1.26 -      "Read a (@port, @type) pair.\n" },
    1.27 +      "Read a @port with pending notifications.\n" },
    1.28  
    1.29      { "unmask", 
    1.30        (PyCFunction)xu_notifier_unmask,
    1.31 @@ -199,10 +196,6 @@ static PyObject *xu_notifier_new(PyObjec
    1.32  
    1.33  static PyObject *xu_notifier_getattr(PyObject *obj, char *name)
    1.34  {
    1.35 -    if ( strcmp(name, "EXCEPTION") == 0 )
    1.36 -        return PyInt_FromLong(PORT_EXCEPTION);
    1.37 -    if ( strcmp(name, "NORMAL") == 0 )
    1.38 -        return PyInt_FromLong(PORT_NORMAL);
    1.39      return Py_FindMethod(xu_notifier_methods, obj, name);
    1.40  }
    1.41  
    1.42 @@ -686,43 +679,6 @@ typedef struct xu_port_object {
    1.43  
    1.44  static PyObject *port_error;
    1.45  
    1.46 -static int xup_connect(xu_port_object *xup, domid_t dom,
    1.47 -                       int local_port, int remote_port){
    1.48 -    // From our prespective rx = producer, tx = consumer.
    1.49 -    int err = 0;
    1.50 -    printf("%s> dom=%u %d:%d\n", __FUNCTION__, (unsigned int)dom, 
    1.51 -           local_port, remote_port);
    1.52 -
    1.53 -    // Consumer = tx.
    1.54 -    //xup->interface->tx_resp_prod = 0;
    1.55 -    //xup->interface->tx_req_prod = 0;
    1.56 -    xup->tx_resp_prod = xup->interface->tx_resp_prod;
    1.57 -    xup->tx_req_cons = xup->interface->tx_resp_prod;
    1.58 -    printf("%s> tx: %u %u : %u %u\n", __FUNCTION__,
    1.59 -           (unsigned int)xup->interface->tx_resp_prod,
    1.60 -           (unsigned int)xup->tx_resp_prod,
    1.61 -           (unsigned int)xup->tx_req_cons,
    1.62 -           (unsigned int)xup->interface->tx_req_prod);
    1.63 -
    1.64 -    // Producer = rx.
    1.65 -    //xup->interface->rx_req_prod  = 0;
    1.66 -    //xup->interface->rx_resp_prod = 0;
    1.67 -    xup->rx_req_prod  = xup->interface->rx_req_prod;
    1.68 -    xup->rx_resp_cons = xup->interface->rx_resp_prod;
    1.69 -    printf("%s> rx: %u %u : %u %u\n", __FUNCTION__,
    1.70 -           (unsigned int)xup->rx_resp_cons,
    1.71 -           (unsigned int)xup->interface->rx_resp_prod,
    1.72 -           (unsigned int)xup->interface->rx_req_prod,
    1.73 -           (unsigned int)xup->rx_req_prod);
    1.74 -
    1.75 -    xup->remote_dom   = dom;
    1.76 -    xup->local_port   = local_port;
    1.77 -    xup->remote_port  = remote_port;
    1.78 -
    1.79 -    printf("%s< err=%d\n", __FUNCTION__, err);
    1.80 -    return err;
    1.81 -}
    1.82 -
    1.83  static PyObject *xu_port_notify(PyObject *self, PyObject *args)
    1.84  {
    1.85      xu_port_object *xup = (xu_port_object *)self;
    1.86 @@ -913,6 +869,86 @@ static PyObject *xu_port_space_to_write_
    1.87      return PyInt_FromLong(1);
    1.88  }
    1.89  
    1.90 +static int __xu_port_connect(xu_port_object *xup)
    1.91 +{
    1.92 +    xc_dominfo_t info;
    1.93 +
    1.94 +    if ( xup->mem_fd != -1 )
    1.95 +        return 0;
    1.96 +
    1.97 +    if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
    1.98 +    {
    1.99 +        PyErr_SetString(port_error, "Could not open '/dev/mem'");
   1.100 +        return -1;
   1.101 +    }
   1.102 +
   1.103 +    /* Set the General-Purpose Subject whose page frame will be mapped. */
   1.104 +    (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)xup->remote_dom);
   1.105 +
   1.106 +    if ( (xc_domain_getinfo(xup->xc_handle, xup->remote_dom, 1, &info) != 1) ||
   1.107 +         (info.domid != xup->remote_dom) )
   1.108 +    {
   1.109 +        PyErr_SetString(port_error, "Failed to obtain domain status");
   1.110 +        (void)close(xup->mem_fd);
   1.111 +        xup->mem_fd = -1;
   1.112 +        return -1;
   1.113 +    }
   1.114 +
   1.115 +    xup->interface = 
   1.116 +        map_control_interface(xup->mem_fd, info.shared_info_frame);
   1.117 +    if ( xup->interface == NULL )
   1.118 +    {
   1.119 +        PyErr_SetString(port_error, "Failed to map domain control interface");
   1.120 +        (void)close(xup->mem_fd);
   1.121 +        xup->mem_fd = -1;
   1.122 +        return -1;
   1.123 +    }
   1.124 +
   1.125 +    /* Synchronise ring indexes. */
   1.126 +    xup->tx_resp_prod = xup->interface->tx_resp_prod;
   1.127 +    xup->tx_req_cons  = xup->interface->tx_resp_prod;
   1.128 +    xup->rx_req_prod  = xup->interface->rx_req_prod;
   1.129 +    xup->rx_resp_cons = xup->interface->rx_resp_prod;
   1.130 +
   1.131 +    return 0;
   1.132 +}
   1.133 +
   1.134 +static void __xu_port_disconnect(xu_port_object *xup)
   1.135 +{
   1.136 +    if ( xup->mem_fd == -1 )
   1.137 +        return;
   1.138 +    unmap_control_interface(xup->mem_fd, xup->interface);
   1.139 +    (void)close(xup->mem_fd);
   1.140 +    xup->mem_fd = -1;
   1.141 +}
   1.142 +
   1.143 +static PyObject *xu_port_connect(PyObject *self, PyObject *args)
   1.144 +{
   1.145 +    xu_port_object *xup = (xu_port_object *)self;
   1.146 +
   1.147 +    if ( !PyArg_ParseTuple(args, "") )
   1.148 +        return NULL;
   1.149 +
   1.150 +    if ( __xu_port_connect(xup) != 0 )
   1.151 +        return NULL;
   1.152 +
   1.153 +    Py_INCREF(Py_None);
   1.154 +    return Py_None;
   1.155 +}
   1.156 +
   1.157 +static PyObject *xu_port_disconnect(PyObject *self, PyObject *args)
   1.158 +{
   1.159 +    xu_port_object *xup = (xu_port_object *)self;
   1.160 +
   1.161 +    if ( !PyArg_ParseTuple(args, "") )
   1.162 +        return NULL;
   1.163 +
   1.164 +    __xu_port_disconnect(xup);
   1.165 +
   1.166 +    Py_INCREF(Py_None);
   1.167 +    return Py_None;
   1.168 +}
   1.169 +
   1.170  static PyMethodDef xu_port_methods[] = {
   1.171      { "notify",
   1.172        (PyCFunction)xu_port_notify,
   1.173 @@ -959,6 +995,16 @@ static PyMethodDef xu_port_methods[] = {
   1.174        METH_VARARGS,
   1.175        "Returns TRUE if there is space to write a response message.\n" },
   1.176  
   1.177 +    { "connect",
   1.178 +      (PyCFunction)xu_port_connect,
   1.179 +      METH_VARARGS,
   1.180 +      "Synchronously connect to remote domain.\n" },
   1.181 +
   1.182 +    { "disconnect",
   1.183 +      (PyCFunction)xu_port_disconnect,
   1.184 +      METH_VARARGS,
   1.185 +      "Synchronously disconnect from remote domain.\n" },
   1.186 +
   1.187      { NULL, NULL, 0, NULL }
   1.188  };
   1.189  
   1.190 @@ -969,26 +1015,19 @@ static PyObject *xu_port_new(PyObject *s
   1.191      xu_port_object *xup;
   1.192      u32 dom;
   1.193      int port1, port2;
   1.194 -    xc_dominfo_t info;
   1.195  
   1.196      if ( !PyArg_ParseTuple(args, "i", &dom) )
   1.197          return NULL;
   1.198  
   1.199      xup = PyObject_New(xu_port_object, &xu_port_type);
   1.200  
   1.201 -    if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
   1.202 -    {
   1.203 -        PyErr_SetString(port_error, "Could not open '/dev/mem'");
   1.204 -        goto fail1;
   1.205 -    }
   1.206 -
   1.207 -    /* Set the General-Purpose Subject whose page frame will be mapped. */
   1.208 -    (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)dom);
   1.209 +    xup->remote_dom = dom;
   1.210 +    xup->mem_fd     = -1; /* currently disconnected */
   1.211  
   1.212      if ( (xup->xc_handle = xc_interface_open()) == -1 )
   1.213      {
   1.214          PyErr_SetString(port_error, "Could not open Xen control interface");
   1.215 -        goto fail2;
   1.216 +        goto fail1;
   1.217      }
   1.218  
   1.219      if ( dom == 0 )
   1.220 @@ -1002,7 +1041,7 @@ static PyObject *xu_port_new(PyObject *s
   1.221          if ( port1 < 0 )
   1.222          {
   1.223              PyErr_SetString(port_error, "Could not open channel to DOM0");
   1.224 -            goto fail3;
   1.225 +            goto fail2;
   1.226          }
   1.227      }
   1.228      else if ( xc_evtchn_bind_interdomain(xup->xc_handle, 
   1.229 @@ -1010,34 +1049,22 @@ static PyObject *xu_port_new(PyObject *s
   1.230                                           &port1, &port2) != 0 )
   1.231      {
   1.232          PyErr_SetString(port_error, "Could not open channel to domain");
   1.233 -        goto fail3;
   1.234 -    }
   1.235 -
   1.236 -    if ( (xc_domain_getinfo(xup->xc_handle, dom, 1, &info) != 1) ||
   1.237 -         (info.domid != dom) )
   1.238 -    {
   1.239 -        PyErr_SetString(port_error, "Failed to obtain domain status");
   1.240 -        goto fail4;
   1.241 +        goto fail2;
   1.242      }
   1.243  
   1.244 -    xup->interface = 
   1.245 -        map_control_interface(xup->mem_fd, info.shared_info_frame);
   1.246 -    if ( xup->interface == NULL )
   1.247 -    {
   1.248 -        PyErr_SetString(port_error, "Failed to map domain control interface");
   1.249 -        goto fail4;
   1.250 -    }
   1.251 +    xup->local_port  = port1;
   1.252 +    xup->remote_port = port2;
   1.253 +
   1.254 +    if ( __xu_port_connect(xup) != 0 )
   1.255 +        goto fail3;
   1.256  
   1.257 -    xup_connect(xup, dom, port1, port2);
   1.258      return (PyObject *)xup;
   1.259 -
   1.260      
   1.261 - fail4:
   1.262 -    (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
   1.263   fail3:
   1.264 -    (void)xc_interface_close(xup->xc_handle);
   1.265 +    if ( dom != 0 )
   1.266 +        (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
   1.267   fail2:
   1.268 -    (void)close(xup->mem_fd);
   1.269 +    (void)xc_interface_close(xup->xc_handle);
   1.270   fail1:
   1.271      PyObject_Del((PyObject *)xup);
   1.272      return NULL;        
   1.273 @@ -1058,11 +1085,10 @@ static PyObject *xu_port_getattr(PyObjec
   1.274  static void xu_port_dealloc(PyObject *self)
   1.275  {
   1.276      xu_port_object *xup = (xu_port_object *)self;
   1.277 -    unmap_control_interface(xup->mem_fd, xup->interface);
   1.278 +    __xu_port_disconnect(xup);
   1.279      if ( xup->remote_dom != 0 )
   1.280          (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
   1.281      (void)xc_interface_close(xup->xc_handle);
   1.282 -    (void)close(xup->mem_fd);
   1.283      PyObject_Del(self);
   1.284  }
   1.285  
     2.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Wed Jun 30 15:31:23 2004 +0000
     2.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Jun 30 16:36:18 2004 +0000
     2.3 @@ -169,13 +169,10 @@ class NotifierProtocol(protocol.Protocol
     2.4      def __init__(self, channelFactory):
     2.5          self.channelFactory = channelFactory
     2.6  
     2.7 -    def notificationReceived(self, idx, type):
     2.8 -        #print 'NotifierProtocol>notificationReceived>', idx, type
     2.9 +    def notificationReceived(self, idx):
    2.10          channel = self.channelFactory.getChannel(idx)
    2.11 -        if not channel:
    2.12 -            return
    2.13 -        #print 'NotifierProtocol>notificationReceived> channel', channel
    2.14 -        channel.notificationReceived(type)
    2.15 +        if channel:
    2.16 +            channel.notificationReceived()
    2.17  
    2.18      def connectionLost(self, reason=None):
    2.19          pass
    2.20 @@ -251,9 +248,8 @@ class NotifierPort(abstract.FileDescript
    2.21              notification = self.notifier.read()
    2.22              if not notification:
    2.23                  break
    2.24 -            (idx, type) = notification
    2.25 -            self.protocol.notificationReceived(idx, type)
    2.26 -            self.notifier.unmask(idx)
    2.27 +            self.protocol.notificationReceived(notification)
    2.28 +            self.notifier.unmask(notification)
    2.29              count += 1
    2.30          #print 'NotifierPort>doRead<'
    2.31  
     3.1 --- a/tools/python/xen/xend/server/channel.py	Wed Jun 30 15:31:23 2004 +0000
     3.2 +++ b/tools/python/xen/xend/server/channel.py	Wed Jun 30 16:36:18 2004 +0000
     3.3 @@ -107,22 +107,14 @@ class BaseChannel:
     3.4          """
     3.5          return self.idx
     3.6  
     3.7 -    def notificationReceived(self, type):
     3.8 +    def notificationReceived(self):
     3.9          """Called when a notification is received.
    3.10          Closes the channel on error, otherwise calls
    3.11          handleNotification(type), which should be defined
    3.12          in a subclass.
    3.13          """
    3.14 -        #print 'notificationReceived> type=', type, self
    3.15 -        if self.closed: return
    3.16 -        if type == self.factory.notifier.EXCEPTION:
    3.17 -            print 'notificationReceived> EXCEPTION'
    3.18 -            info = xc.evtchn_status(self.idx)
    3.19 -            if info['status'] == 'unbound':
    3.20 -                print 'notificationReceived> EXCEPTION closing...'
    3.21 -                self.close()
    3.22 -                return
    3.23 -        self.handleNotification(type)
    3.24 +        if not self.closed:
    3.25 +            self.handleNotification(type)
    3.26  
    3.27      def close(self):
    3.28          """Close the channel. Calls channelClosed() on the factory.