diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/misc/Makefile | 2 | ||||
-rw-r--r-- | tools/misc/netfix (renamed from tools/xen/netfix) | 0 | ||||
-rw-r--r-- | tools/xen/Makefile | 1 | ||||
-rw-r--r-- | tools/xend-old/Makefile | 17 | ||||
-rw-r--r-- | tools/xend-old/lib/__init__.py | 0 | ||||
-rw-r--r-- | tools/xend-old/lib/blkif.py | 214 | ||||
-rw-r--r-- | tools/xend-old/lib/console.py | 180 | ||||
-rw-r--r-- | tools/xend-old/lib/domain_controller.h | 532 | ||||
-rwxr-xr-x | tools/xend-old/lib/main.py | 317 | ||||
-rw-r--r-- | tools/xend-old/lib/manager.py | 174 | ||||
-rw-r--r-- | tools/xend-old/lib/netif.py | 187 | ||||
-rw-r--r-- | tools/xend-old/lib/utils.c | 1384 | ||||
-rw-r--r-- | tools/xend-old/setup.py | 19 | ||||
-rwxr-xr-x | tools/xend-old/xend | 22 | ||||
-rw-r--r-- | tools/xentrace/formats | 28 | ||||
-rw-r--r-- | tools/xentrace/xentrace.c | 2 |
16 files changed, 17 insertions, 3062 deletions
diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 9891676d5a..9df04d8ea2 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -19,7 +19,9 @@ all: $(TARGETS) install: all mkdir -p $(prefix)/usr/bin + mkdir -p $(prefix)/usr/sbin install -m0755 $(INSTALL) $(prefix)/usr/bin + install -m0755 netfix $(prefix)/usr/sbin $(MAKE) -C miniterm install clean: diff --git a/tools/xen/netfix b/tools/misc/netfix index def4e28a6c..def4e28a6c 100644 --- a/tools/xen/netfix +++ b/tools/misc/netfix diff --git a/tools/xen/Makefile b/tools/xen/Makefile index 8732a30932..343a596e90 100644 --- a/tools/xen/Makefile +++ b/tools/xen/Makefile @@ -12,7 +12,6 @@ install: all fi mkdir -p $(prefix)/usr/sbin install -m0755 xend $(prefix)/usr/sbin - install -m0755 netfix $(prefix)/usr/sbin install -m0755 xm $(prefix)/usr/sbin mkdir -p $(prefix)/etc/xen/xend install -m0755 vifctl $(prefix)/etc/xen/xend diff --git a/tools/xend-old/Makefile b/tools/xend-old/Makefile deleted file mode 100644 index 8e28c0386a..0000000000 --- a/tools/xend-old/Makefile +++ /dev/null @@ -1,17 +0,0 @@ - -all: - python setup.py build - -install: all - if [ "$(prefix)" = "" ]; then \ - python setup.py install; \ - elif [ "$(dist)" = "yes" ]; then \ - python setup.py install --home="$(prefix)"; \ - else \ - python setup.py install --root="$(prefix)"; \ - fi - mkdir -p $(prefix)/usr/sbin - install -m0755 xend $(prefix)/usr/sbin - -clean: - rm -rf build *.pyc *.pyo *.a *.so *.o *~ *.rpm diff --git a/tools/xend-old/lib/__init__.py b/tools/xend-old/lib/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/tools/xend-old/lib/__init__.py +++ /dev/null diff --git a/tools/xend-old/lib/blkif.py b/tools/xend-old/lib/blkif.py deleted file mode 100644 index 51431b694a..0000000000 --- a/tools/xend-old/lib/blkif.py +++ /dev/null @@ -1,214 +0,0 @@ - -################################################################# -## xend/blkif.py -- Block-interface management functions for Xend -## Copyright (c) 2004, K A Fraser (University of Cambridge) -################################################################# - -import errno, re, os, select, signal, socket, sys -import xend.main, xend.console, xend.manager, xend.utils, Xc - -CMSG_BLKIF_BE = 1 -CMSG_BLKIF_FE = 2 -CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED = 0 -CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED = 32 -CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED = 32 -CMSG_BLKIF_FE_INTERFACE_CONNECT = 33 -CMSG_BLKIF_FE_INTERFACE_DISCONNECT = 34 -CMSG_BLKIF_BE_CREATE = 0 -CMSG_BLKIF_BE_DESTROY = 1 -CMSG_BLKIF_BE_CONNECT = 2 -CMSG_BLKIF_BE_DISCONNECT = 3 -CMSG_BLKIF_BE_VBD_CREATE = 4 -CMSG_BLKIF_BE_VBD_DESTROY = 5 -CMSG_BLKIF_BE_VBD_GROW = 6 -CMSG_BLKIF_BE_VBD_SHRINK = 7 - -BLKIF_DRIVER_STATUS_DOWN = 0 -BLKIF_DRIVER_STATUS_UP = 1 - -pendmsg = None -pendaddr = None - -recovery = False # Is a recovery in progress? (if so we'll need to notify guests) -be_port = None # Port object for backend domain - -def backend_tx_req(msg): - port = xend.blkif.be_port - if not port: - print "BUG: attempt to transmit request to non-existant blkif driver" - if port.space_to_write_request(): - port.write_request(msg) - port.notify() - else: - xend.blkif.pendmsg = msg - -def backend_rx_req(port, msg): - port.write_response(msg) - subtype = (msg.get_header())['subtype'] - print "Received blkif-be request, subtype %d" % subtype - if subtype == CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED: - status = (msg.get_payload())['status'] - if status == BLKIF_DRIVER_STATUS_UP: - if xend.blkif.recovery: - # Nasty hack: we count the number of VBDs we reattach so that - # we'll know when to notify the guests. Must make this better! - interface.rebuilt_so_far = 0 - interface.nr_to_rebuild = 0 - print "New blkif backend now UP, rebuilding VBDs:" - for blkif_key in interface.list.keys(): - blkif = interface.list[blkif_key] - blkif.create() - for vdev in blkif.devices.keys(): - blkif.reattach_device(vdev) - interface.nr_to_rebuild += 1 - else: - print "Unexpected block backend driver status: %d" % status - - -def backend_rx_rsp(port, msg): - subtype = (msg.get_header())['subtype'] - print "Received blkif-be response, subtype %d" % subtype - if subtype == CMSG_BLKIF_BE_CREATE: - rsp = { 'success': True } - xend.main.send_management_response(rsp, xend.blkif.pendaddr) - elif subtype == CMSG_BLKIF_BE_CONNECT: - pl = msg.get_payload() - (dom, hnd, frame, evtchn, st) = (pl['domid'], pl['blkif_handle'], - pl['shmem_frame'], pl['evtchn'], - pl['status']) - blkif = interface.list[xend.main.port_from_dom(dom).local_port] - msg = xend.utils.message(CMSG_BLKIF_FE, - CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED, 0, - { 'handle' : 0, 'status' : 2, - 'evtchn' : blkif.evtchn['port2'] }) - blkif.ctrlif_tx_req(xend.main.port_list[blkif.key], msg) - elif subtype == CMSG_BLKIF_BE_VBD_CREATE: - pl = msg.get_payload() - (dom, hnd, vdev, ro, st) = (pl['domid'], pl['blkif_handle'], - pl['vdevice'], pl['readonly'], - pl['status']) - blkif = interface.list[xend.main.port_from_dom(dom).local_port] - (pdev, start_sect, nr_sect, readonly) = blkif.devices[vdev] - msg = xend.utils.message(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW, 0, - { 'domid' : dom, 'blkif_handle' : 0, - 'vdevice' : vdev, - 'extent.sector_start' : start_sect, - 'extent.sector_length' : nr_sect, - 'extent.device' : pdev }) - backend_tx_req(msg) - elif subtype == CMSG_BLKIF_BE_VBD_GROW: - if not xend.blkif.recovery: - rsp = { 'success': True } - xend.main.send_management_response(rsp, xend.blkif.pendaddr) - else: - interface.rebuilt_so_far += 1 - if interface.rebuilt_so_far == interface.nr_to_rebuild: - print "Rebuilt VBDs, notifying guests:" - for blkif_key in interface.list.keys(): - blkif = interface.list[blkif_key] - print " Notifying %d" % blkif.dom - msg = xend.utils.message(CMSG_BLKIF_FE, - CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED, - 0, { 'handle' : 0, 'status' : 1 }) - blkif.ctrlif_tx_req(xend.main.port_from_dom(blkif.dom),msg) - xend.blkif.recovery = False - print "Done notifying guests" - - -def backend_do_work(port): - global pendmsg - if pendmsg and port.space_to_write_request(): - port.write_request(pendmsg) - pendmsg = None - return True - return False - - -class interface: - - # Dictionary of all block-device interfaces. - list = {} - - # NB. 'key' is an opaque value that has no meaning in this class. - def __init__(self, dom, key): - self.dom = dom - self.key = key - self.devices = {} - self.pendmsg = None - interface.list[key] = self - self.create() - - def create(self): - msg = xend.utils.message(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE, 0, - { 'domid' : self.dom, 'blkif_handle' : 0 }) - xend.blkif.pendaddr = xend.main.mgmt_req_addr - backend_tx_req(msg) - - # Attach a device to the specified interface - def attach_device(self, vdev, pdev, start_sect, nr_sect, readonly): - if self.devices.has_key(vdev): - return False - self.devices[vdev] = (pdev, start_sect, nr_sect, readonly) - msg = xend.utils.message(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE, 0, - { 'domid' : self.dom, 'blkif_handle' : 0, - 'vdevice' : vdev, 'readonly' : readonly }) - xend.blkif.pendaddr = xend.main.mgmt_req_addr - backend_tx_req(msg) - return True - - def reattach_device(self, vdev): - (pdev, start_sect, nr_sect, readonly) = self.devices[vdev] - msg = xend.utils.message(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE, - 0, { 'domid' : self.dom, - 'blkif_handle' : 0, - 'vdevice' : vdev, - 'readonly' : readonly }) - xend.blkif.pendaddr = xend.main.mgmt_req_addr - backend_tx_req(msg) - - # Completely destroy this interface. - def destroy(self): - del interface.list[self.key] - msg = xend.utils.message(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY, 0, - { 'domid' : self.dom, 'blkif_handle' : 0 }) - backend_tx_req(msg) - - - # The parameter @port is the control-interface event channel. This method - # returns True if messages were written to the control interface. - def ctrlif_transmit_work(self, port): - if self.pendmsg and port.space_to_write_request(): - port.write_request(self.pendmsg) - self.pendmsg = None - return True - return False - - def ctrlif_tx_req(self, port, msg): - if port.space_to_write_request(): - port.write_request(msg) - port.notify() - else: - self.pendmsg = msg - - def ctrlif_rx_req(self, port, msg): - port.write_response(msg) - subtype = (msg.get_header())['subtype'] - if subtype == CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED: - msg = xend.utils.message(CMSG_BLKIF_FE, - CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED, - 0, - { 'handle' : 0, 'status' : 1 }) - self.ctrlif_tx_req(port, msg) - elif subtype == CMSG_BLKIF_FE_INTERFACE_CONNECT: - pl = msg.get_payload() - (hnd, frame) = (pl['handle'], pl['shmem_frame']) - xc = Xc.new() - self.evtchn = xc.evtchn_bind_interdomain( - dom1=xend.blkif.be_port.remote_dom, - dom2=self.dom) - msg = xend.utils.message(CMSG_BLKIF_BE, - CMSG_BLKIF_BE_CONNECT, 0, - { 'domid' : self.dom, 'blkif_handle' : 0, - 'shmem_frame' : frame, - 'evtchn' : self.evtchn['port1'] }) - backend_tx_req(msg) diff --git a/tools/xend-old/lib/console.py b/tools/xend-old/lib/console.py deleted file mode 100644 index 57898817f5..0000000000 --- a/tools/xend-old/lib/console.py +++ /dev/null @@ -1,180 +0,0 @@ - -############################################################# -## xend/console.py -- Console-management functions for Xend -## Copyright (c) 2004, K A Fraser (University of Cambridge) -############################################################# - -import errno, re, os, select, signal, socket, struct, sys -import xend.blkif, xend.main, xend.manager, xend.utils, Xc - -## -## interface: -## Each control interface owns an instance of this class, which manages -## the current state of the console interface. Normally a console interface -## will be one of two state: -## LISTENING: listening for a connection on TCP port 'self.port' -## CONNECTED: sending/receiving console data on TCP port 'self.port' -## -## A dictionary of all active interfaces, indexed by TCP socket descriptor, -## is accessible as 'interface.list_by_fd'. -## -## NB. When a class instance is to be destroyed you *must* call the 'close' -## method. Otherwise a stale reference will eb left in the interface list. -## -class interface: - - # The various states that a console interface may be in. - CLOSED = 0 # No console activity - LISTENING = 1 # Listening on port 'self.port'. Socket object 'self.sock'. - CONNECTED = 2 # Active connection on 'self.port'. Socket obj 'self.sock'. - - - # Dictionary of all active (non-closed) console interfaces. - list_by_fd = {} - - - # Dictionary of all console interfaces, closed and open. - list = {} - - - # NB. 'key' is an opaque value that has no meaning in this class. - def __init__(self, port, key): - self.status = interface.CLOSED - self.port = port - self.key = key - self.rbuf = xend.utils.buffer() - self.wbuf = xend.utils.buffer() - interface.list[key] = self - - - # Is this interface closed (inactive)? - def closed(self): - return self.status == interface.CLOSED - - - # Is this interface listening? - def listening(self): - return self.status == interface.LISTENING - - - # Is this interface active and connected? - def connected(self): - return self.status == interface.CONNECTED - - - # Close the interface, if it is not closed already. - def close(self): - if not self.closed(): - del interface.list_by_fd[self.sock.fileno()] - self.sock.close() - del self.sock - self.status = interface.CLOSED - - - # Move the interface into the 'listening' state. Opens a new listening - # socket and updates 'list_by_fd'. - def listen(self): - # Close old socket (if any), and create a fresh one. - self.close() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) - - try: - # Turn the new socket into a non-blocking listener. - self.sock.setblocking(False) - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.sock.bind(('', self.port)) - self.sock.listen(1) - - # Announce the new status of thsi interface. - self.status = interface.LISTENING - interface.list_by_fd[self.sock.fileno()] = self - - except: - # In case of trouble ensure we get rid of dangling socket reference - self.sock.close() - del self.sock - raise - - - # Move a listening interface into the 'connected' state. - def connect(self): - # Pick up a new connection, if one is available. - try: - (sock, addr) = self.sock.accept() - except: - return 0 - sock.setblocking(False) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Close the listening socket. - self.sock.close() - - # Publish the new socket and the new interface state. - self.sock = sock - self.status = interface.CONNECTED - interface.list_by_fd[self.sock.fileno()] = self - return 1 - - - # Completely sestroy a console interface. - def destroy(self): - self.close() - del interface.list[self.key] - - - # Do work triggered by resource availability on a console-interface socket. - def socket_work(self): - # If the interface is listening, check for pending connections. - if self.listening(): - self.connect() - - # All done if the interface is not connected. - if not self.connected(): - return - - # Send as much pending data as possible via the socket. - while not self.rbuf.empty(): - try: - bytes = self.sock.send(self.rbuf.peek()) - if bytes > 0: - self.rbuf.discard(bytes) - except socket.error, error: - pass - - # Read as much data as is available. Don't worry about - # overflowing our buffer: it's more important to read the - # incoming data stream and detect errors or closure of the - # remote end in a timely manner. - try: - while 1: - data = self.sock.recv(2048) - # Return of zero means the remote end has disconnected. - # We therefore return the console interface to listening. - if not data: - self.listen() - break - self.wbuf.write(data) - except socket.error, error: - # Assume that most errors mean that the connection is dead. - # In such cases we return the interface to 'listening' state. - if error[0] != errno.EAGAIN: - print "Better return to listening" - self.listen() - print "New status: " + str(self.status) - - - # The parameter @port is the control-interface event channel. This method - # returns True if messages were written to the control interface. - def ctrlif_transmit_work(self, port): - work_done = False - while not self.wbuf.empty() and port.space_to_write_request(): - msg = xend.utils.message(0, 0, 0) - msg.append_payload(self.wbuf.read(msg.MAX_PAYLOAD)) - port.write_request(msg) - work_done = True - return work_done - - - def ctrlif_rx_req(self, port, msg): - self.rbuf.write(msg.get_payload()) - port.write_response(msg) diff --git a/tools/xend-old/lib/domain_controller.h b/tools/xend-old/lib/domain_controller.h deleted file mode 100644 index 76dd164fcb..0000000000 --- a/tools/xend-old/lib/domain_controller.h +++ /dev/null @@ -1,532 +0,0 @@ -/****************************************************************************** - * domain_controller.h - * - * Interface to server controller (e.g., 'xend'). This header file defines the - * interface that is shared with guest OSes. - * - * Copyright (c) 2004, K A Fraser - */ - -#ifndef __DOMAIN_CONTROLLER_H__ -#define __DOMAIN_CONTROLLER_H__ - - -#ifndef BASIC_START_INFO -#error "Xen header file hypervisor-if.h must already be included here." -#endif - - -/* - * EXTENDED BOOTSTRAP STRUCTURE FOR NEW DOMAINS. - */ - -typedef struct { - BASIC_START_INFO; - u16 domain_controller_evtchn; /* 320 */ -} PACKED extended_start_info_t; /* 322 bytes */ -#define SIF_BLK_BE_DOMAIN (1<<4) /* Is this a block backend domain? */ -#define SIF_NET_BE_DOMAIN (1<<5) /* Is this a net backend domain? */ - - -/* - * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be - * interpreted by control software to determine the appropriate action. These - * are only really advisories: the controller can actually do as it likes. - */ -#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ -#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */ -#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ - - -/* - * CONTROLLER MESSAGING INTERFACE. - */ - -typedef struct { - u8 type; /* 0: echoed in response */ - u8 subtype; /* 1: echoed in response */ - u8 id; /* 2: echoed in response */ - u8 length; /* 3: number of bytes in 'msg' */ - u8 msg[60]; /* 4: type-specific message data */ -} PACKED control_msg_t; /* 64 bytes */ - -#define CONTROL_RING_SIZE 8 -typedef u32 CONTROL_RING_IDX; -#define MASK_CONTROL_IDX(_i) ((_i)&(CONTROL_RING_SIZE-1)) - -typedef struct { - control_msg_t tx_ring[CONTROL_RING_SIZE]; /* 0: guest -> controller */ - control_msg_t rx_ring[CONTROL_RING_SIZE]; /* 512: controller -> guest */ - CONTROL_RING_IDX tx_req_prod, tx_resp_prod; /* 1024, 1028 */ - CONTROL_RING_IDX rx_req_prod, rx_resp_prod; /* 1032, 1036 */ -} PACKED control_if_t; /* 1040 bytes */ - -/* - * Top-level command types. - */ -#define CMSG_CONSOLE 0 /* Console */ -#define CMSG_BLKIF_BE 1 /* Block-device backend */ -#define CMSG_BLKIF_FE 2 /* Block-device frontend */ -#define CMSG_NETIF_BE 3 /* Network-device backend */ -#define CMSG_NETIF_FE 4 /* Network-device frontend */ -#define CMSG_SHUTDOWN 6 /* Shutdown messages */ - - -/****************************************************************************** - * CONSOLE DEFINITIONS - */ - -/* - * Subtypes for console messages. - */ -#define CMSG_CONSOLE_DATA 0 - - -/****************************************************************************** - * BLOCK-INTERFACE FRONTEND DEFINITIONS - */ - -/* Messages from domain controller to guest. */ -#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED 0 - -/* Messages from guest to domain controller. */ -#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED 32 -#define CMSG_BLKIF_FE_INTERFACE_CONNECT 33 -#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT 34 - -/* These are used by both front-end and back-end drivers. */ -#define blkif_vdev_t u16 -#define blkif_pdev_t u16 -#define blkif_sector_t u64 - -/* - * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED: - * Notify a guest about a status change on one of its block interfaces. - * If the interface is DESTROYED or DOWN then the interface is disconnected: - * 1. The shared-memory frame is available for reuse. - * 2. Any unacknowledged messgaes pending on the interface were dropped. - */ -#define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */ -#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */ -#define BLKIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */ -typedef struct { - u32 handle; /* 0 */ - u32 status; /* 4 */ - u16 evtchn; /* 8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */ -} PACKED blkif_fe_interface_status_changed_t; /* 10 bytes */ - -/* - * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED: - * Notify the domain controller that the front-end driver is DOWN or UP. - * When the driver goes DOWN then the controller will send no more - * status-change notifications. When the driver comes UP then the controller - * will send a notification for each interface that currently exists. - * If the driver goes DOWN while interfaces are still UP, the domain - * will automatically take the interfaces DOWN. - */ -#define BLKIF_DRIVER_STATUS_DOWN 0 -#define BLKIF_DRIVER_STATUS_UP 1 -typedef struct { - /* IN */ - u32 status; /* 0: BLKIF_DRIVER_STATUS_??? */ - /* OUT */ - /* - * Tells driver how many interfaces it should expect to immediately - * receive notifications about. - */ - u32 nr_interfaces; /* 4 */ -} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */ - -/* - * CMSG_BLKIF_FE_INTERFACE_CONNECT: - * If successful, the domain controller will acknowledge with a - * STATUS_CONNECTED message. - */ -typedef struct { - u32 handle; /* 0 */ - u32 __pad; - memory_t shmem_frame; /* 8 */ - MEMORY_PADDING; -} PACKED blkif_fe_interface_connect_t; /* 16 bytes */ - -/* - * CMSG_BLKIF_FE_INTERFACE_DISCONNECT: - * If successful, the domain controller will acknowledge with a - * STATUS_DISCONNECTED message. - */ -typedef struct { - u32 handle; /* 0 */ -} PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */ - - -/****************************************************************************** - * BLOCK-INTERFACE BACKEND DEFINITIONS - */ - -/* Messages from domain controller. */ -#define CMSG_BLKIF_BE_CREATE 0 /* Create a new block-device interface. */ -#define CMSG_BLKIF_BE_DESTROY 1 /* Destroy a block-device interface. */ -#define CMSG_BLKIF_BE_CONNECT 2 /* Connect i/f to remote driver. */ -#define CMSG_BLKIF_BE_DISCONNECT 3 /* Disconnect i/f from remote driver. */ -#define CMSG_BLKIF_BE_VBD_CREATE 4 /* Create a new VBD for an interface. */ -#define CMSG_BLKIF_BE_VBD_DESTROY 5 /* Delete a VBD from an interface. */ -#define CMSG_BLKIF_BE_VBD_GROW 6 /* Append an extent to a given VBD. */ -#define CMSG_BLKIF_BE_VBD_SHRINK 7 /* Remove last extent from a given VBD. */ - -/* Messages to domain controller. */ -#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32 - -/* - * Message request/response definitions for block-device messages. - */ - -typedef struct { - blkif_sector_t sector_start; /* 0 */ - blkif_sector_t sector_length; /* 8 */ - blkif_pdev_t device; /* 16 */ - u16 __pad; /* 18 */ -} PACKED blkif_extent_t; /* 20 bytes */ - -/* Non-specific 'okay' return. */ -#define BLKIF_BE_STATUS_OKAY 0 -/* Non-specific 'error' return. */ -#define BLKIF_BE_STATUS_ERROR 1 -/* The following are specific error returns. */ -#define BLKIF_BE_STATUS_INTERFACE_EXISTS 2 -#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3 -#define BLKIF_BE_STATUS_INTERFACE_CONNECTED 4 -#define BLKIF_BE_STATUS_VBD_EXISTS 5 -#define BLKIF_BE_STATUS_VBD_NOT_FOUND 6 -#define BLKIF_BE_STATUS_OUT_OF_MEMORY 7 -#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND 8 -#define BLKIF_BE_STATUS_MAPPING_ERROR 9 - -/* This macro can be used to create an array of descriptive error strings. */ -#define BLKIF_BE_STATUS_ERRORS { \ - "Okay", \ - "Non-specific error", \ - "Interface already exists", \ - "Interface not found", \ - "Interface is still connected", \ - "VBD already exists", \ - "VBD not found", \ - "Out of memory", \ - "Extent not found for VBD", \ - "Could not map domain memory" } - -/* - * CMSG_BLKIF_BE_CREATE: - * When the driver sends a successful response then the interface is fully - * created. The controller will send a DOWN notification to the front-end - * driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Domain attached to new interface. */ - u32 blkif_handle; /* 4: Domain-specific interface handle. */ - /* OUT */ - u32 status; /* 8 */ -} PACKED blkif_be_create_t; /* 12 bytes */ - -/* - * CMSG_BLKIF_BE_DESTROY: - * When the driver sends a successful response then the interface is fully - * torn down. The controller will send a DESTROYED notification to the - * front-end driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Identify interface to be destroyed. */ - u32 blkif_handle; /* 4: ...ditto... */ - /* OUT */ - u32 status; /* 8 */ -} PACKED blkif_be_destroy_t; /* 12 bytes */ - -/* - * CMSG_BLKIF_BE_CONNECT: - * When the driver sends a successful response then the interface is fully - * connected. The controller will send a CONNECTED notification to the - * front-end driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Domain attached to new interface. */ - u32 blkif_handle; /* 4: Domain-specific interface handle. */ - memory_t shmem_frame; /* 8: Page cont. shared comms window. */ - MEMORY_PADDING; - u32 evtchn; /* 16: Event channel for notifications. */ - /* OUT */ - u32 status; /* 20 */ -} PACKED blkif_be_connect_t; /* 24 bytes */ - -/* - * CMSG_BLKIF_BE_DISCONNECT: - * When the driver sends a successful response then the interface is fully - * disconnected. The controller will send a DOWN notification to the front-end - * driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Domain attached to new interface. */ - u32 blkif_handle; /* 4: Domain-specific interface handle. */ - /* OUT */ - u32 status; /* 8 */ -} PACKED blkif_be_disconnect_t; /* 12 bytes */ - -/* CMSG_BLKIF_BE_VBD_CREATE */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Identify blkdev interface. */ - u32 blkif_handle; /* 4: ...ditto... */ - blkif_vdev_t vdevice; /* 8: Interface-specific id for this VBD. */ - u16 readonly; /* 10: Non-zero -> VBD isn't writeable. */ - /* OUT */ - u32 status; /* 12 */ -} PACKED blkif_be_vbd_create_t; /* 16 bytes */ - -/* CMSG_BLKIF_BE_VBD_DESTROY */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Identify blkdev interface. */ - u32 blkif_handle; /* 4: ...ditto... */ - blkif_vdev_t vdevice; /* 8: Interface-specific id of the VBD. */ - u16 __pad; /* 10 */ - /* OUT */ - u32 status; /* 12 */ -} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */ - -/* CMSG_BLKIF_BE_VBD_GROW */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Identify blkdev interface. */ - u32 blkif_handle; /* 4: ...ditto... */ - blkif_extent_t extent; /* 8: Physical extent to append to VBD. */ - blkif_vdev_t vdevice; /* 28: Interface-specific id of the VBD. */ - u16 __pad; /* 30 */ - /* OUT */ - u32 status; /* 32 */ -} PACKED blkif_be_vbd_grow_t; /* 36 bytes */ - -/* CMSG_BLKIF_BE_VBD_SHRINK */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Identify blkdev interface. */ - u32 blkif_handle; /* 4: ...ditto... */ - blkif_vdev_t vdevice; /* 8: Interface-specific id of the VBD. */ - u16 __pad; /* 10 */ - /* OUT */ - u32 status; /* 12 */ -} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */ - -/* - * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED: - * Notify the domain controller that the back-end driver is DOWN or UP. - * If the driver goes DOWN while interfaces are still UP, the controller - * will automatically send DOWN notifications. - */ -typedef struct { - u32 status; /* 0: BLKIF_DRIVER_STATUS_??? */ -} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */ - - -/****************************************************************************** - * NETWORK-INTERFACE FRONTEND DEFINITIONS - */ - -/* Messages from domain controller to guest. */ -#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED 0 - -/* Messages from guest to domain controller. */ -#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED 32 -#define CMSG_NETIF_FE_INTERFACE_CONNECT 33 -#define CMSG_NETIF_FE_INTERFACE_DISCONNECT 34 - -/* - * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED: - * Notify a guest about a status change on one of its network interfaces. - * If the interface is DESTROYED or DOWN then the interface is disconnected: - * 1. The shared-memory frame is available for reuse. - * 2. Any unacknowledged messgaes pending on the interface were dropped. - */ -#define NETIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */ -#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */ -#define NETIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */ -typedef struct { - u32 handle; /* 0 */ - u32 status; /* 4 */ - u16 evtchn; /* 8: status == NETIF_INTERFACE_STATUS_CONNECTED */ - u8 mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */ -} PACKED netif_fe_interface_status_changed_t; /* 16 bytes */ - -/* - * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED: - * Notify the domain controller that the front-end driver is DOWN or UP. - * When the driver goes DOWN then the controller will send no more - * status-change notifications. When the driver comes UP then the controller - * will send a notification for each interface that currently exists. - * If the driver goes DOWN while interfaces are still UP, the domain - * will automatically take the interfaces DOWN. - */ -#define NETIF_DRIVER_STATUS_DOWN 0 -#define NETIF_DRIVER_STATUS_UP 1 -typedef struct { - /* IN */ - u32 status; /* 0: NETIF_DRIVER_STATUS_??? */ - /* OUT */ - /* - * Tells driver how many interfaces it should expect to immediately - * receive notifications about. - */ - u32 nr_interfaces; /* 4 */ -} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */ - -/* - * CMSG_NETIF_FE_INTERFACE_CONNECT: - * If successful, the domain controller will acknowledge with a - * STATUS_CONNECTED message. - */ -typedef struct { - u32 handle; /* 0 */ - u32 __pad; /* 4 */ - memory_t tx_shmem_frame; /* 8 */ - MEMORY_PADDING; - memory_t rx_shmem_frame; /* 16 */ - MEMORY_PADDING; -} PACKED netif_fe_interface_connect_t; /* 24 bytes */ - -/* - * CMSG_NETIF_FE_INTERFACE_DISCONNECT: - * If successful, the domain controller will acknowledge with a - * STATUS_DISCONNECTED message. - */ -typedef struct { - u32 handle; /* 0 */ -} PACKED netif_fe_interface_disconnect_t; /* 4 bytes */ - - -/****************************************************************************** - * NETWORK-INTERFACE BACKEND DEFINITIONS - */ - -/* Messages from domain controller. */ -#define CMSG_NETIF_BE_CREATE 0 /* Create a new net-device interface. */ -#define CMSG_NETIF_BE_DESTROY 1 /* Destroy a net-device interface. */ -#define CMSG_NETIF_BE_CONNECT 2 /* Connect i/f to remote driver. */ -#define CMSG_NETIF_BE_DISCONNECT 3 /* Disconnect i/f from remote driver. */ - -/* Messages to domain controller. */ -#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32 - -/* - * Message request/response definitions for net-device messages. - */ - -/* Non-specific 'okay' return. */ -#define NETIF_BE_STATUS_OKAY 0 -/* Non-specific 'error' return. */ -#define NETIF_BE_STATUS_ERROR 1 -/* The following are specific error returns. */ -#define NETIF_BE_STATUS_INTERFACE_EXISTS 2 -#define NETIF_BE_STATUS_INTERFACE_NOT_FOUND 3 -#define NETIF_BE_STATUS_INTERFACE_CONNECTED 4 -#define NETIF_BE_STATUS_OUT_OF_MEMORY 5 -#define NETIF_BE_STATUS_MAPPING_ERROR 6 - -/* This macro can be used to create an array of descriptive error strings. */ -#define NETIF_BE_STATUS_ERRORS { \ - "Okay", \ - "Non-specific error", \ - "Interface already exists", \ - "Interface not found", \ - "Interface is still connected", \ - "Out of memory", \ - "Could not map domain memory" } - -/* - * CMSG_NETIF_BE_CREATE: - * When the driver sends a successful response then the interface is fully - * created. The controller will send a DOWN notification to the front-end - * driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Domain attached to new interface. */ - u32 netif_handle; /* 4: Domain-specific interface handle. */ - u8 mac[6]; /* 8 */ - u16 __pad; /* 14 */ - /* OUT */ - u32 status; /* 16 */ -} PACKED netif_be_create_t; /* 20 bytes */ - -/* - * CMSG_NETIF_BE_DESTROY: - * When the driver sends a successful response then the interface is fully - * torn down. The controller will send a DESTROYED notification to the - * front-end driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Identify interface to be destroyed. */ - u32 netif_handle; /* 4: ...ditto... */ - /* OUT */ - u32 status; /* 8 */ -} PACKED netif_be_destroy_t; /* 12 bytes */ - -/* - * CMSG_NETIF_BE_CONNECT: - * When the driver sends a successful response then the interface is fully - * connected. The controller will send a CONNECTED notification to the - * front-end driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Domain attached to new interface. */ - u32 netif_handle; /* 4: Domain-specific interface handle. */ - memory_t tx_shmem_frame; /* 8: Page cont. tx shared comms window. */ - MEMORY_PADDING; - memory_t rx_shmem_frame; /* 16: Page cont. rx shared comms window. */ - MEMORY_PADDING; - u16 evtchn; /* 24: Event channel for notifications. */ - u16 __pad; /* 26 */ - /* OUT */ - u32 status; /* 28 */ -} PACKED netif_be_connect_t; /* 32 bytes */ - -/* - * CMSG_NETIF_BE_DISCONNECT: - * When the driver sends a successful response then the interface is fully - * disconnected. The controller will send a DOWN notification to the front-end - * driver. - */ -typedef struct { - /* IN */ - domid_t domid; /* 0: Domain attached to new interface. */ - u32 netif_handle; /* 4: Domain-specific interface handle. */ - /* OUT */ - u32 status; /* 8 */ -} PACKED netif_be_disconnect_t; /* 12 bytes */ - -/* - * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED: - * Notify the domain controller that the back-end driver is DOWN or UP. - * If the driver goes DOWN while interfaces are still UP, the domain - * will automatically send DOWN notifications. - */ -typedef struct { - u32 status; /* 0: NETIF_DRIVER_STATUS_??? */ -} PACKED netif_be_driver_status_changed_t; /* 4 bytes */ - - -/****************************************************************************** - * SHUTDOWN DEFINITIONS - */ - -/* - * Subtypes for shutdown messages. - */ -#define CMSG_SHUTDOWN_POWEROFF 0 /* Clean shutdown (SHUTDOWN_poweroff). */ -#define CMSG_SHUTDOWN_REBOOT 1 /* Clean shutdown (SHUTDOWN_reboot). */ -#define CMSG_SHUTDOWN_SUSPEND 2 /* Create suspend info, then */ - /* SHUTDOWN_suspend. */ - -#endif /* __DOMAIN_CONTROLLER_H__ */ diff --git a/tools/xend-old/lib/main.py b/tools/xend-old/lib/main.py deleted file mode 100755 index 0eecd17a05..0000000000 --- a/tools/xend-old/lib/main.py +++ /dev/null @@ -1,317 +0,0 @@ - -########################################################### -## xend.py -- Xen controller daemon -## Copyright (c) 2004, K A Fraser (University of Cambridge) -########################################################### - -import errno, re, os, pwd, select, signal, socket, struct, sys, time -import xend.blkif, xend.netif, xend.console, xend.manager, xend.utils, Xc - - -# The following parameters could be placed in a configuration file. -PID = '/var/run/xend.pid' -LOG = '/var/log/xend.log' -USER = 'root' -CONTROL_DIR = '/var/run/xend' -UNIX_SOCK = 'management_sock' # relative to CONTROL_DIR - - -CMSG_CONSOLE = 0 -CMSG_BLKIF_BE = 1 -CMSG_BLKIF_FE = 2 -CMSG_NETIF_BE = 3 -CMSG_NETIF_FE = 4 - - -def port_from_dom(dom): - global port_list - for idx, port in port_list.items(): - if port.remote_dom == dom: - return port - return None - - -def send_management_response(response, addr): - try: - response = str(response) - print "Mgmt_rsp[%s]: %s" % (addr, response) - management_interface.sendto(response, addr) - except socket.error, error: - pass - - -def daemon_loop(): - # Could we do this more nicely? The xend.manager functions need access - # to this global state to do their work. - global port_list, notifier, management_interface, mgmt_req_addr, dom0_port - - # Lists of all interfaces, indexed by local event-channel port. - port_list = {} - - xc = Xc.new() - - # Ignore writes to disconnected sockets. We clean up differently. - signal.signal(signal.SIGPIPE, signal.SIG_IGN) - - # Construct the management interface. This is a UNIX domain socket via - # which we receive 'request' datagrams. Each request is a string that - # can be eval'ed as a Python statement. Responses can be remotely eval'ed - # by the requester to create a Python dictionary of result values. - management_interface = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM, 0) - if os.path.exists(CONTROL_DIR+'/'+UNIX_SOCK): - os.unlink(CONTROL_DIR+'/'+UNIX_SOCK) - management_interface.setblocking(False) - management_interface.bind(CONTROL_DIR+'/'+UNIX_SOCK) - - # Interface via which we receive event notifications from other guest - # OSes. This interface also allows us to clear/acknowledge outstanding - # notifications. - notifier = xend.utils.notifier() - - # The DOM0 control interface is not set up via the management interface. - # Note that console messages don't come our way (actually, only driver - # back-ends should use the DOM0 control interface). - dom0_port = xend.utils.port(0) - xend.netif.be_port = dom0_port - xend.blkif.be_port = dom0_port - notifier.bind(dom0_port.local_port) - port_list[dom0_port.local_port] = dom0_port - - ## - ## MAIN LOOP - ## - while 1: - - # Construct a poll set. We wait on: - # 1. Requests on the management interface. - # 2. Incoming event-channel notifications. - # Furthermore, for each active control interface: - # 3. Incoming console data. - # 4. Space for outgoing console data (if there is data to send). - waitset = select.poll() - waitset.register(management_interface, select.POLLIN) - waitset.register(notifier, select.POLLIN) - for idx, con_if in xend.console.interface.list_by_fd.items(): - if not con_if.closed(): - pflags = select.POLLIN - if not con_if.rbuf.empty() and con_if.connected(): - pflags = select.POLLIN | select.POLLOUT - waitset.register(con_if.sock.fileno(), pflags) - - # Wait for something to do... - fdset = waitset.poll() - - # Look for messages on the management interface. - # These should consist of executable Python statements that call - # well-known management functions (e.g., new_control_interface(dom=9)). - try: - data, mgmt_req_addr = management_interface.recvfrom(2048) - except socket.error, error: - if error[0] != errno.EAGAIN: - raise - else: - if mgmt_req_addr: - # Evaluate the request in an exception-trapping sandbox. - try: - print "Mgmt_req[%s]: %s" % (mgmt_req_addr, data) - response = eval('xend.manager.'+data) - - except: - # Catch all exceptions and turn into an error response: - # status: False - # error_type: 'exception' - # exception_type: name of exception type. - # exception value: textual exception value. - exc_type, exc_val = sys.exc_info()[:2] - response = { 'success': False } - response['error_type'] = 'exception' - response['exception_type'] = str(exc_type) - response['exception_value'] = str(exc_val) - response = str(response) - - # Try to send a response to the requester. - if response: - send_management_response(response, mgmt_req_addr) - - # Do work for every console interface that hit in the poll set. - for (fd, events) in fdset: - if xend.console.interface.list_by_fd.has_key(fd): - con_if = xend.console.interface.list_by_fd[fd] - con_if.socket_work() - # We may now have pending data to send via the control - # interface. If so then send all we can and notify the remote. - port = port_list[con_if.key] - if con_if.ctrlif_transmit_work(port): - port.notify() - - # Process control-interface notifications from other guest OSes. - while 1: - # Grab a notification, if there is one. - notification = notifier.read() - if not notification: - break - (idx, type) = notification - - if not port_list.has_key(idx): - continue - - port = port_list[idx] - work_done = False - - con_if = False - if xend.console.interface.list.has_key(idx): - con_if = xend.console.interface.list[idx] - - blk_if = False - if xend.blkif.interface.list.has_key(idx): - blk_if = xend.blkif.interface.list[idx] - - net_if = False - if xend.netif.interface.list.has_key(idx): - net_if = xend.netif.interface.list[idx] - - # If we pick up a disconnect notification then we do any necessary - # cleanup. - if type == notifier.EXCEPTION: - ret = xc.evtchn_status(idx) - if ret['status'] == 'unbound': - notifier.unbind(idx) - del port_list[idx], port - if con_if: - con_if.destroy() - del con_if - if blk_if: - blk_if.destroy() - del blk_if - if net_if: - net_if.destroy() - del net_if - continue - - # Process incoming requests. - while port.request_to_read(): - msg = port.read_request() - work_done = True - type = (msg.get_header())['type'] - if type == CMSG_CONSOLE and con_if: - con_if.ctrlif_rx_req(port, msg) - elif type == CMSG_BLKIF_FE and blk_if: - blk_if.ctrlif_rx_req(port, msg) - elif type == CMSG_BLKIF_BE and port == xend.blkif.be_port: - xend.blkif.backend_rx_req(port, msg) - elif type == CMSG_NETIF_FE and net_if: - net_if.ctrlif_rx_req(port, msg) - elif type == CMSG_NETIF_BE and port == xend.netif.be_port: - xend.netif.backend_rx_req(port, msg) - else: - port.write_response(msg) - - # Process incoming responses. - while port.response_to_read(): - msg = port.read_response() - work_done = True - type = (msg.get_header())['type'] - if type == CMSG_BLKIF_BE and port == xend.blkif.be_port: - xend.blkif.backend_rx_rsp(port, msg) - elif type == CMSG_NETIF_BE and port == xend.netif.be_port: - xend.netif.backend_rx_rsp(port, msg) - - # Send console data. - if con_if and con_if.ctrlif_transmit_work(port): - work_done = True - - # Send blkif messages. - if blk_if and blk_if.ctrlif_transmit_work(port): - work_done = True - - # Send netif messages. - if net_if and net_if.ctrlif_transmit_work(port): - work_done = True - - # Back-end block-device work. - if port == dom0_port and xend.blkif.backend_do_work(port): - work_done = True - - # Back-end network-device work. - if port == xend.netif.be_port and xend.netif.backend_do_work(port): - work_done = True - - # Finally, notify the remote end of any work that we did. - if work_done: - port.notify() - - # Unmask notifications for this port. - notifier.unmask(idx) - - - -def cleanup_daemon(kill=False): - # No cleanup to do if the PID file is empty. - if not os.path.isfile(PID) or not os.path.getsize(PID): - return 0 - # Read the PID of the previous invocation and search active process list. - pid = open(PID, 'r').read() - lines = os.popen('ps ' + pid + ' 2>/dev/null').readlines() - for line in lines: - if re.search('^ *' + pid + '.+xend', line): - if not kill: - print "Daemon is already running (PID %d)" % int(pid) - return 1 - # Old daemon is still active: terminate it. - os.kill(int(pid), 1) - # Delete the, now stale, PID file. - os.remove(PID) - return 0 - - - -def start_daemon(): - if cleanup_daemon(kill=False): - return 1 - - if not os.path.exists(CONTROL_DIR): - os.mkdir(CONTROL_DIR) - - # Open log file. Truncate it if non-empty, and request line buffering. - if os.path.isfile(LOG): - os.rename(LOG, LOG+'.old') - logfile = open(LOG, 'w+', 1) - - # Detach from TTY. - os.setsid() - - # Set the UID. - try: - os.setuid(pwd.getpwnam(USER)[2]) - except KeyError, error: - print "Error: no such user '%s'" % USER - return 1 - - # Ensure that zombie children are automatically reaped. - xend.utils.autoreap() - - # Fork -- parent writes the PID file and exits. - pid = os.fork() - if pid: - pidfile = open(PID, 'w') - pidfile.write(str(pid)) - pidfile.close() - return 0 - - # Close down standard file handles - try: - os.close(0) # stdin - os.close(1) # stdout - os.close(2) # stderr - except: - pass - - # Redirect output to log file, then enter the main loop. - sys.stdout = sys.stderr = logfile - daemon_loop() - return 0 - - - -def stop_daemon(): - return cleanup_daemon(kill=True) diff --git a/tools/xend-old/lib/manager.py b/tools/xend-old/lib/manager.py deleted file mode 100644 index 49517583b5..0000000000 --- a/tools/xend-old/lib/manager.py +++ /dev/null @@ -1,174 +0,0 @@ - -############################################################# -## xend/manager.py -- Management-interface functions for Xend -## Copyright (c) 2004, K A Fraser (University of Cambridge) -############################################################# - -import xend.blkif, xend.netif, xend.console, xend.main, xend.utils - - -## -## new_control_interface: -## Create a new control interface with the specified domain @dom. -## The console port may also be specified; otherwise a suitable port is -## automatically allocated. -## -def new_control_interface(dom, console_port=-1): - # Allocate an event channel and binbd to it. - port = xend.utils.port(dom) - xend.main.notifier.bind(port.local_port) - - # If necessary, compute a suitable TCP port for console I/O. - if console_port < 0: - console_port = 9600 + port.local_port - - # Create a listening console interface. - con_if = xend.console.interface(console_port, port.local_port) - con_if.listen() - - # Update the master port list. - xend.main.port_list[port.local_port] = port - - # Construct the successful response to be returned to the requester. - response = { 'success': True } - response['local_port'] = port.local_port - response['remote_port'] = port.remote_port - response['console_port'] = console_port - return response - - -## -## new_block_interface: -## Create a new block interface for the specified domain @dom. -## -def new_block_interface(dom, handle=-1): - # By default we create an interface with handle zero. - if handle < 0: - handle = 0 - - # We only support one interface per domain, which must have handle zero. - if handle != 0: - response = { 'success': False } - response['error_type'] = 'Bad handle %d (only handle 0 ' + \ - 'is supported)' % handle - return response - - # Find local event-channel port associated with the specified domain. - port = xend.main.port_from_dom(dom) - if not port: - response = { 'success': False } - response['error_type'] = 'Unknown domain %d' % dom - return response - - # The interface must not already exist. - if xend.blkif.interface.list.has_key(port.local_port): - response = { 'success': False } - response['error_type'] = 'Interface (dom=%d,handle=%d) already ' + \ - 'exists' % (dom, handle) - return response - - # Create the new interface. Initially no virtual devices are attached. - xend.blkif.interface(dom, port.local_port) - - # Response is deferred until back-end driver sends acknowledgement. - return None - - -## -## new_block_device: -## Attach a new virtual block device to the specified block interface -## (@dom, @handle). The new device is identified by @vdev, and maps to -## the real block extent (@pdev, @start_sect, @nr_sect). If @readonly then -## write requests to @vdev will be rejected. -## -def new_block_device(dom, handle, vdev, pdev, start_sect, nr_sect, readonly): - # We only support one interface per domain, which must have handle zero. - if handle != 0: - response = { 'success': False } - response['error_type'] = 'Bad handle %d (only handle 0 ' + \ - 'is supported)' % handle - return response - - # Find local event-channel port associated with the specified domain. - port = xend.main.port_from_dom(dom) - if not port: - response = { 'success': False } - response['error_type'] = 'Unknown domain %d' % dom - return response - - # The interface must exist. - if not xend.blkif.interface.list.has_key(port.local_port): - response = { 'success': False } - response['error_type'] = 'Interface (dom=%d,handle=%d) does not ' + \ - 'exists' % (dom, handle) - return response - - # The virtual device must not yet exist. - blkif = xend.blkif.interface.list[port.local_port] - if not blkif.attach_device(vdev, pdev, start_sect, nr_sect, readonly): - response = { 'success': False } - response['error_type'] = 'Vdevice (dom=%d,handle=%d,vdevice=%d) ' + \ - 'already exists' % (dom, handle, vdev) - return response - - # Response is deferred until back-end driver sends acknowledgement. - return None - - -## -## new_network_interface: -## Create a new network interface for the specified domain @dom. -## -def new_network_interface(dom, handle=-1): - # By default we create an interface with handle zero. - if handle < 0: - handle = 0 - - # We only support one interface per domain, which must have handle zero. - if handle != 0: - response = { 'success': False } - response['error_type'] = 'Bad handle %d (only handle 0 ' + \ - 'is supported)' % handle - return response - - # Find local event-channel port associated with the specified domain. - port = xend.main.port_from_dom(dom) - if not port: - response = { 'success': False } - response['error_type'] = 'Unknown domain %d' % dom - return response - - # The interface must not already exist. - if xend.netif.interface.list.has_key(port.local_port): - response = { 'success': False } - response['error_type'] = 'Interface (dom=%d,handle=%d) already ' + \ - 'exists' % (dom, handle) - return response - - # Create the new interface. Initially no virtual devices are attached. - xend.netif.interface(dom, port.local_port) - - # Response is deferred until back-end driver sends acknowledgement. - return None - -## -## set_network_backend -## Authorise a domain to act as the net backend (assumes we only have one -## backend driver for now). After this call, back end "up" notifications -## for the network will only be accepted from this domain. -## -def set_network_backend(dom): - if xend.netif.be_port.remote_dom != 0: - xend.netif.recovery = True - xend.netif.be_port = xend.main.port_from_dom(dom) - return { 'success' : True } - -## -## set_block_backend -## Authorise a domain to act as the block backend (assumes we only have one -## backend driver for now). After this call, back end "up" notifications -## for the network will only be accepted from this domain. -def set_block_backend(dom): - if xend.blkif.be_port: xend.blkif.recovery = True - xend.blkif.be_port = xend.main.port_from_dom(dom) - return { 'success' : True } diff --git a/tools/xend-old/lib/netif.py b/tools/xend-old/lib/netif.py deleted file mode 100644 index eaa10086a2..0000000000 --- a/tools/xend-old/lib/netif.py +++ /dev/null @@ -1,187 +0,0 @@ - -################################################################### -## xend/netif.py -- Network-interface management functions for Xend -## Copyright (c) 2004, K A Fraser (University of Cambridge) -################################################################### - -import errno, random, re, os, select, signal, socket, struct, sys -import xend.main, xend.console, xend.manager, xend.utils, Xc - -CMSG_NETIF_BE = 3 -CMSG_NETIF_FE = 4 -CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED = 0 -CMSG_NETIF_FE_DRIVER_STATUS_CHANGED = 32 -CMSG_NETIF_BE_DRIVER_STATUS_CHANGED = 32 -CMSG_NETIF_FE_INTERFACE_CONNECT = 33 -CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34 -CMSG_NETIF_BE_CREATE = 0 -CMSG_NETIF_BE_DESTROY = 1 -CMSG_NETIF_BE_CONNECT = 2 -CMSG_NETIF_BE_DISCONNECT = 3 - -NETIF_DRIVER_STATUS_DOWN = 0 -NETIF_DRIVER_STATUS_UP = 1 - -pendmsg = None -pendaddr = None - -recovery = False # Is a recovery in progress? -be_port = None # Port object for backend domain - -def backend_tx_req(msg): - if xend.netif.be_port.space_to_write_request(): - xend.netif.be_port.write_request(msg) - xend.netif.be_port.notify() - else: - xend.netif.pendmsg = msg - -def backend_rx_req(port, msg): - port.write_response(msg) - subtype = (msg.get_header())['subtype'] - print "Received netif-be request, subtype %d" % subtype - if subtype == CMSG_NETIF_BE_DRIVER_STATUS_CHANGED: - pl = msg.get_payload() - status = pl['status'] - if status == NETIF_DRIVER_STATUS_UP: - if xend.netif.recovery: - print "New netif backend now UP, notifying guests:" - for netif_key in interface.list.keys(): - netif = interface.list[netif_key] - netif.create() - print " Notifying %d" % netif.dom - msg = xend.utils.message( - CMSG_NETIF_FE, - CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0, - { 'handle' : 0, 'status' : 1 }) - netif.ctrlif_tx_req(xend.main.port_from_dom(netif.dom),msg) - print "Done notifying guests" - recovery = False - else: - print "Unexpected net backend driver status: %d" % status - -def backend_rx_rsp(port, msg): - subtype = (msg.get_header())['subtype'] - print "Received netif-be response, subtype %d" % subtype - if subtype == CMSG_NETIF_BE_CREATE: - rsp = { 'success': True } - xend.main.send_management_response(rsp, xend.netif.pendaddr) - elif subtype == CMSG_NETIF_BE_CONNECT: - pl = msg.get_payload() - (dom, hnd, evtchn, tx_frame, rx_frame, st) = ( - pl['domid'], pl['netif_handle'], pl['evtchn'], - pl['tx_shmem_frame'], pl['rx_shmem_frame'], pl['status']) - netif = interface.list[xend.main.port_from_dom(dom).local_port] - msg = xend.utils.message(CMSG_NETIF_FE, - CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0, - { 'handle' : 0, 'status' : 2, - 'evtchn' : netif.evtchn['port2'], - 'mac[0]' : netif.mac[0], - 'mac[1]' : netif.mac[1], - 'mac[2]' : netif.mac[2], - 'mac[3]' : netif.mac[3], - 'mac[4]' : netif.mac[4], - 'mac[5]' : netif.mac[5] }) - netif.ctrlif_tx_req(xend.main.port_list[netif.key], msg) - -def backend_do_work(port): - global pendmsg - if pendmsg and port.space_to_write_request(): - port.write_request(pendmsg) - pendmsg = None - return True - return False - - -class interface: - - # Dictionary of all network-device interfaces. - list = {} - - drvdom = None - - # NB. 'key' is an opaque value that has no meaning in this class. - def __init__(self, dom, key): - self.dom = dom - self.key = key - self.pendmsg = None - - # VIFs get a random MAC address with a "special" vendor id. - # - # NB. The vendor is currently an "obsolete" one that used to belong - # to DEC (AA-00-00). Using it is probably a bit rude :-) - # - # NB2. The first bit of the first random octet is set to zero for - # all dynamic MAC addresses. This may allow us to manually specify - # MAC addresses for some VIFs with no fear of clashes. - self.mac = [ 0xaa, 0x00, 0x00 ] - self.mac.append(int(random.random()*128)) - self.mac.append(int(random.random()*256)) - self.mac.append(int(random.random()*256)) - - interface.list[key] = self - self.create() - - def create(self): - """Notify the current network back end to create the virtual interface - represented by this object.""" - msg = xend.utils.message(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE, 0, - { 'domid' : self.dom, 'netif_handle' : 0, - 'mac[0]' : self.mac[0], - 'mac[1]' : self.mac[1], - 'mac[2]' : self.mac[2], - 'mac[3]' : self.mac[3], - 'mac[4]' : self.mac[4], - 'mac[5]' : self.mac[5] }) - xend.netif.pendaddr = xend.main.mgmt_req_addr - backend_tx_req(msg) - - - # Completely destroy this interface. - def destroy(self): - del interface.list[self.key] - msg = xend.utils.message(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY, 0, - { 'domid' : self.dom, 'netif_handle' : 0 }) - backend_tx_req(msg) - - - # The parameter @port is the control-interface event channel. This method - # returns True if messages were written to the control interface. - def ctrlif_transmit_work(self, port): - if self.pendmsg and port.space_to_write_request(): - port.write_request(self.pendmsg) - self.pendmsg = None - return True - return False - - def ctrlif_tx_req(self, port, msg): - if port.space_to_write_request(): - port.write_request(msg) - port.notify() - else: - self.pendmsg = msg - - def ctrlif_rx_req(self, port, msg): - port.write_response(msg) - subtype = (msg.get_header())['subtype'] - if subtype == CMSG_NETIF_FE_DRIVER_STATUS_CHANGED: - print "netif driver up message from %d" % port.remote_dom - msg = xend.utils.message(CMSG_NETIF_FE, - CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0, - { 'handle' : 0, 'status' : 1 }) - self.ctrlif_tx_req(port, msg) - elif subtype == CMSG_NETIF_FE_INTERFACE_CONNECT: - print "netif connect request from %d" % port.remote_dom - pl = msg.get_payload() - (hnd, tx_frame, rx_frame) = (pl['handle'], pl['tx_shmem_frame'], - pl['rx_shmem_frame']) - xc = Xc.new() - self.evtchn = xc.evtchn_bind_interdomain( - dom1=xend.netif.be_port.remote_dom, - dom2=self.dom) - msg = xend.utils.message(CMSG_NETIF_BE, - CMSG_NETIF_BE_CONNECT, 0, - { 'domid' : self.dom, 'netif_handle' : 0, - 'tx_shmem_frame' : tx_frame, - 'rx_shmem_frame' : rx_frame, - 'evtchn' : self.evtchn['port1'] }) - backend_tx_req(msg) diff --git a/tools/xend-old/lib/utils.c b/tools/xend-old/lib/utils.c deleted file mode 100644 index 2d96577203..0000000000 --- a/tools/xend-old/lib/utils.c +++ /dev/null @@ -1,1384 +0,0 @@ -/****************************************************************************** - * utils.c - * - * Copyright (c) 2004, K A Fraser - */ - -#include <Python.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/mman.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <xc.h> - -#include <hypervisor-if.h> -#include "domain_controller.h" - -#include <asm-xen/proc_cmd.h> - -/* Needed for Python versions earlier than 2.3. */ -#ifndef PyMODINIT_FUNC -#define PyMODINIT_FUNC DL_EXPORT(void) -#endif - -/* NB. The following should be kept in sync with the kernel's evtchn driver. */ -#define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 200 -#define PORT_NORMAL 0x0000 /* A standard event notification. */ -#define PORT_EXCEPTION 0x8000 /* An exceptional notification. */ -#define PORTIDX_MASK 0x7fff /* Strip subtype to obtain port index. */ -/* /dev/xen/evtchn ioctls: */ -/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */ -#define EVTCHN_RESET _IO('E', 1) -/* EVTCHN_BIND: Bind to teh specified event-channel port. */ -#define EVTCHN_BIND _IO('E', 2) -/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */ -#define EVTCHN_UNBIND _IO('E', 3) - -/* Size of a machine page frame. */ -#define PAGE_SIZE 4096 - - -/* - * *********************** NOTIFIER *********************** - */ - -typedef struct { - PyObject_HEAD; - int evtchn_fd; -} xu_notifier_object; - -static PyObject *xu_notifier_read(PyObject *self, PyObject *args) -{ - xu_notifier_object *xun = (xu_notifier_object *)self; - u16 v; - int bytes; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - while ( (bytes = read(xun->evtchn_fd, &v, sizeof(v))) == -1 ) - { - if ( errno == EINTR ) - continue; - if ( errno == EAGAIN ) - goto none; - return PyErr_SetFromErrno(PyExc_IOError); - } - - if ( bytes == sizeof(v) ) - return Py_BuildValue("(i,i)", v&PORTIDX_MASK, v&~PORTIDX_MASK); - - none: - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_notifier_unmask(PyObject *self, PyObject *args) -{ - xu_notifier_object *xun = (xu_notifier_object *)self; - u16 v; - int idx; - - if ( !PyArg_ParseTuple(args, "i", &idx) ) - return NULL; - - v = (u16)idx; - - (void)write(xun->evtchn_fd, &v, sizeof(v)); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_notifier_bind(PyObject *self, PyObject *args) -{ - xu_notifier_object *xun = (xu_notifier_object *)self; - int idx; - - if ( !PyArg_ParseTuple(args, "i", &idx) ) - return NULL; - - if ( ioctl(xun->evtchn_fd, EVTCHN_BIND, idx) != 0 ) - return PyErr_SetFromErrno(PyExc_IOError); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_notifier_unbind(PyObject *self, PyObject *args) -{ - xu_notifier_object *xun = (xu_notifier_object *)self; - int idx; - - if ( !PyArg_ParseTuple(args, "i", &idx) ) - return NULL; - - if ( ioctl(xun->evtchn_fd, EVTCHN_UNBIND, idx) != 0 ) - return PyErr_SetFromErrno(PyExc_IOError); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_notifier_fileno(PyObject *self, PyObject *args) -{ - xu_notifier_object *xun = (xu_notifier_object *)self; - return PyInt_FromLong(xun->evtchn_fd); -} - -static PyMethodDef xu_notifier_methods[] = { - { "read", - (PyCFunction)xu_notifier_read, - METH_VARARGS, - "Read a (@port, @type) pair.\n" }, - - { "unmask", - (PyCFunction)xu_notifier_unmask, - METH_VARARGS, - "Unmask notifications for a @port.\n" }, - - { "bind", - (PyCFunction)xu_notifier_bind, - METH_VARARGS, - "Get notifications for a @port.\n" }, - - { "unbind", - (PyCFunction)xu_notifier_unbind, - METH_VARARGS, - "No longer get notifications for a @port.\n" }, - - { "fileno", - (PyCFunction)xu_notifier_fileno, - METH_VARARGS, - "Return the file descriptor for the notification channel.\n" }, - - { NULL, NULL, 0, NULL } -}; - -staticforward PyTypeObject xu_notifier_type; - -static PyObject *xu_notifier_new(PyObject *self, PyObject *args) -{ - xu_notifier_object *xun; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - xun = PyObject_New(xu_notifier_object, &xu_notifier_type); - - reopen: - xun->evtchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); - if ( xun->evtchn_fd == -1 ) - { - if ( (errno == ENOENT) && - ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - (EVTCHN_DEV_MAJOR << 8) | EVTCHN_DEV_MINOR) == 0) ) - goto reopen; - PyObject_Del((PyObject *)xun); - return PyErr_SetFromErrno(PyExc_IOError); - } - - return (PyObject *)xun; -} - -static PyObject *xu_notifier_getattr(PyObject *obj, char *name) -{ - if ( strcmp(name, "EXCEPTION") == 0 ) - return PyInt_FromLong(PORT_EXCEPTION); - if ( strcmp(name, "NORMAL") == 0 ) - return PyInt_FromLong(PORT_NORMAL); - return Py_FindMethod(xu_notifier_methods, obj, name); -} - -static void xu_notifier_dealloc(PyObject *self) -{ - xu_notifier_object *xun = (xu_notifier_object *)self; - (void)close(xun->evtchn_fd); - PyObject_Del(self); -} - -static PyTypeObject xu_notifier_type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "notifier", - sizeof(xu_notifier_object), - 0, - xu_notifier_dealloc, /* tp_dealloc */ - NULL, /* tp_print */ - xu_notifier_getattr, /* tp_getattr */ - NULL, /* tp_setattr */ - NULL, /* tp_compare */ - NULL, /* tp_repr */ - NULL, /* tp_as_number */ - NULL, /* tp_as_sequence */ - NULL, /* tp_as_mapping */ - NULL /* tp_hash */ -}; - - - -/* - * *********************** MESSAGE *********************** - */ - -#define TYPE(_x,_y) (((_x)<<8)|(_y)) -#define P2C(_struct, _field, _ctype) \ - do { \ - PyObject *obj; \ - if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL ) \ - { \ - if ( PyInt_Check(obj) ) \ - { \ - ((_struct *)&xum->msg.msg[0])->_field = \ - (_ctype)PyInt_AsLong(obj); \ - dict_items_parsed++; \ - } \ - else if ( PyLong_Check(obj) ) \ - { \ - ((_struct *)&xum->msg.msg[0])->_field = \ - (_ctype)PyLong_AsUnsignedLongLong(obj); \ - dict_items_parsed++; \ - } \ - } \ - xum->msg.length = sizeof(_struct); \ - } while ( 0 ) -#define C2P(_struct, _field, _pytype, _ctype) \ - do { \ - PyObject *obj = Py ## _pytype ## _From ## _ctype \ - (((_struct *)&xum->msg.msg[0])->_field); \ - if ( dict == NULL ) dict = PyDict_New(); \ - PyDict_SetItemString(dict, #_field, obj); \ - } while ( 0 ) - -typedef struct { - PyObject_HEAD; - control_msg_t msg; -} xu_message_object; - -static PyObject *xu_message_append_payload(PyObject *self, PyObject *args) -{ - xu_message_object *xum = (xu_message_object *)self; - char *str; - int len; - - if ( !PyArg_ParseTuple(args, "s#", &str, &len) ) - return NULL; - - if ( (len + xum->msg.length) > sizeof(xum->msg.msg) ) - { - PyErr_SetString(PyExc_RuntimeError, "out of space in control message"); - return NULL; - } - - memcpy(&xum->msg.msg[xum->msg.length], str, len); - xum->msg.length += len; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_message_set_response_fields(PyObject *self, PyObject *args) -{ - xu_message_object *xum = (xu_message_object *)self; - PyObject *payload; - int dict_items_parsed = 0; - - if ( !PyArg_ParseTuple(args, "O", &payload) ) - return NULL; - - if ( !PyDict_Check(payload) ) - { - PyErr_SetString(PyExc_TypeError, "payload is not a dictionary"); - return NULL; - } - - switch ( TYPE(xum->msg.type, xum->msg.subtype) ) - { - case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED): - P2C(blkif_fe_driver_status_changed_t, nr_interfaces, u32); - break; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): - P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32); - break; - } - - if ( dict_items_parsed != PyDict_Size(payload) ) - { - PyErr_SetString(PyExc_TypeError, "payload contains bad items"); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_message_get_payload(PyObject *self, PyObject *args) -{ - xu_message_object *xum = (xu_message_object *)self; - PyObject *dict = NULL; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - switch ( TYPE(xum->msg.type, xum->msg.subtype) ) - { - case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED): - C2P(blkif_fe_interface_status_changed_t, handle, Int, Long); - C2P(blkif_fe_interface_status_changed_t, status, Int, Long); - C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED): - C2P(blkif_fe_driver_status_changed_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT): - C2P(blkif_fe_interface_connect_t, handle, Int, Long); - C2P(blkif_fe_interface_connect_t, shmem_frame, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_DISCONNECT): - C2P(blkif_fe_interface_disconnect_t, handle, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE): - C2P(blkif_be_create_t, domid, Int, Long); - C2P(blkif_be_create_t, blkif_handle, Int, Long); - C2P(blkif_be_create_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY): - C2P(blkif_be_destroy_t, domid, Int, Long); - C2P(blkif_be_destroy_t, blkif_handle, Int, Long); - C2P(blkif_be_destroy_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT): - C2P(blkif_be_connect_t, domid, Int, Long); - C2P(blkif_be_connect_t, blkif_handle, Int, Long); - C2P(blkif_be_connect_t, shmem_frame, Int, Long); - C2P(blkif_be_connect_t, evtchn, Int, Long); - C2P(blkif_be_connect_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT): - C2P(blkif_be_disconnect_t, domid, Int, Long); - C2P(blkif_be_disconnect_t, blkif_handle, Int, Long); - C2P(blkif_be_disconnect_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE): - C2P(blkif_be_vbd_create_t, domid, Int, Long); - C2P(blkif_be_vbd_create_t, blkif_handle, Int, Long); - C2P(blkif_be_vbd_create_t, vdevice, Int, Long); - C2P(blkif_be_vbd_create_t, readonly, Int, Long); - C2P(blkif_be_vbd_create_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY): - C2P(blkif_be_vbd_destroy_t, domid, Int, Long); - C2P(blkif_be_vbd_destroy_t, blkif_handle, Int, Long); - C2P(blkif_be_vbd_destroy_t, vdevice, Int, Long); - C2P(blkif_be_vbd_destroy_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW): - C2P(blkif_be_vbd_grow_t, domid, Int, Long); - C2P(blkif_be_vbd_grow_t, blkif_handle, Int, Long); - C2P(blkif_be_vbd_grow_t, vdevice, Int, Long); - C2P(blkif_be_vbd_grow_t, extent.sector_start, - Long, UnsignedLongLong); - C2P(blkif_be_vbd_grow_t, extent.sector_length, - Long, UnsignedLongLong); - C2P(blkif_be_vbd_grow_t, extent.device, Int, Long); - C2P(blkif_be_vbd_grow_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK): - C2P(blkif_be_vbd_shrink_t, domid, Int, Long); - C2P(blkif_be_vbd_shrink_t, blkif_handle, Int, Long); - C2P(blkif_be_vbd_shrink_t, vdevice, Int, Long); - C2P(blkif_be_vbd_shrink_t, status, Int, Long); - return dict; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED): - C2P(blkif_be_driver_status_changed_t, status, Int, Long); - return dict; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED): - C2P(netif_fe_interface_status_changed_t, handle, Int, Long); - C2P(netif_fe_interface_status_changed_t, status, Int, Long); - C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long); - return dict; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): - C2P(netif_fe_driver_status_changed_t, status, Int, Long); - C2P(netif_fe_driver_status_changed_t, nr_interfaces, Int, Long); - return dict; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT): - C2P(netif_fe_interface_connect_t, handle, Int, Long); - C2P(netif_fe_interface_connect_t, tx_shmem_frame, Int, Long); - C2P(netif_fe_interface_connect_t, rx_shmem_frame, Int, Long); - return dict; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_DISCONNECT): - C2P(netif_fe_interface_disconnect_t, handle, Int, Long); - return dict; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE): - C2P(netif_be_create_t, domid, Int, Long); - C2P(netif_be_create_t, netif_handle, Int, Long); - C2P(netif_be_create_t, status, Int, Long); - return dict; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY): - C2P(netif_be_destroy_t, domid, Int, Long); - C2P(netif_be_destroy_t, netif_handle, Int, Long); - C2P(netif_be_destroy_t, status, Int, Long); - return dict; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT): - C2P(netif_be_connect_t, domid, Int, Long); - C2P(netif_be_connect_t, netif_handle, Int, Long); - C2P(netif_be_connect_t, tx_shmem_frame, Int, Long); - C2P(netif_be_connect_t, rx_shmem_frame, Int, Long); - C2P(netif_be_connect_t, evtchn, Int, Long); - C2P(netif_be_connect_t, status, Int, Long); - return dict; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT): - C2P(netif_be_disconnect_t, domid, Int, Long); - C2P(netif_be_disconnect_t, netif_handle, Int, Long); - C2P(netif_be_disconnect_t, status, Int, Long); - return dict; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED): - C2P(netif_be_driver_status_changed_t, status, Int, Long); - return dict; - } - - return PyString_FromStringAndSize(xum->msg.msg, xum->msg.length); -} - -static PyObject *xu_message_get_header(PyObject *self, PyObject *args) -{ - xu_message_object *xum = (xu_message_object *)self; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - return Py_BuildValue("{s:i,s:i,s:i}", - "type", xum->msg.type, - "subtype", xum->msg.subtype, - "id", xum->msg.id); -} - -static PyMethodDef xu_message_methods[] = { - { "append_payload", - (PyCFunction)xu_message_append_payload, - METH_VARARGS, - "Append @str to the message payload.\n" }, - - { "set_response_fields", - (PyCFunction)xu_message_set_response_fields, - METH_VARARGS, - "Fill in the response fields in a message that was passed to us.\n" }, - - { "get_payload", - (PyCFunction)xu_message_get_payload, - METH_VARARGS, - "Return the message payload in string form.\n" }, - - { "get_header", - (PyCFunction)xu_message_get_header, - METH_VARARGS, - "Returns a dictionary of values for @type, @subtype, and @id.\n" }, - - { NULL, NULL, 0, NULL } -}; - -staticforward PyTypeObject xu_message_type; - -static PyObject *xu_message_new(PyObject *self, PyObject *args) -{ - xu_message_object *xum; - int type, subtype, id, dict_items_parsed = 0; - PyObject *payload = NULL; - - if ( !PyArg_ParseTuple(args, "iii|O", &type, &subtype, &id, &payload) ) - return NULL; - - xum = PyObject_New(xu_message_object, &xu_message_type); - - xum->msg.type = type; - xum->msg.subtype = subtype; - xum->msg.id = id; - xum->msg.length = 0; - - if ( payload == NULL ) - return (PyObject *)xum; - - if ( !PyDict_Check(payload) ) - { - PyErr_SetString(PyExc_TypeError, "payload is not a dictionary"); - PyObject_Del((PyObject *)xum); - return NULL; - } - - switch ( TYPE(type, subtype) ) - { - case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED): - P2C(blkif_fe_interface_status_changed_t, handle, u32); - P2C(blkif_fe_interface_status_changed_t, status, u32); - P2C(blkif_fe_interface_status_changed_t, evtchn, u16); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE): - P2C(blkif_be_create_t, domid, u32); - P2C(blkif_be_create_t, blkif_handle, u32); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY): - P2C(blkif_be_destroy_t, domid, u32); - P2C(blkif_be_destroy_t, blkif_handle, u32); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT): - P2C(blkif_be_connect_t, domid, u32); - P2C(blkif_be_connect_t, blkif_handle, u32); - P2C(blkif_be_connect_t, shmem_frame, memory_t); - P2C(blkif_be_connect_t, evtchn, u16); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT): - P2C(blkif_be_disconnect_t, domid, u32); - P2C(blkif_be_disconnect_t, blkif_handle, u32); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE): - P2C(blkif_be_vbd_create_t, domid, u32); - P2C(blkif_be_vbd_create_t, blkif_handle, u32); - P2C(blkif_be_vbd_create_t, vdevice, blkif_vdev_t); - P2C(blkif_be_vbd_create_t, readonly, u16); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY): - P2C(blkif_be_vbd_destroy_t, domid, u32); - P2C(blkif_be_vbd_destroy_t, blkif_handle, u32); - P2C(blkif_be_vbd_destroy_t, vdevice, blkif_vdev_t); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW): - P2C(blkif_be_vbd_grow_t, domid, u32); - P2C(blkif_be_vbd_grow_t, blkif_handle, u32); - P2C(blkif_be_vbd_grow_t, vdevice, blkif_vdev_t); - P2C(blkif_be_vbd_grow_t, extent.sector_start, blkif_sector_t); - P2C(blkif_be_vbd_grow_t, extent.sector_length, blkif_sector_t); - P2C(blkif_be_vbd_grow_t, extent.device, blkif_pdev_t); - break; - case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK): - P2C(blkif_be_vbd_shrink_t, domid, u32); - P2C(blkif_be_vbd_shrink_t, blkif_handle, u32); - P2C(blkif_be_vbd_shrink_t, vdevice, blkif_vdev_t); - break; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED): - P2C(netif_fe_interface_status_changed_t, handle, u32); - P2C(netif_fe_interface_status_changed_t, status, u32); - P2C(netif_fe_interface_status_changed_t, evtchn, u16); - P2C(netif_fe_interface_status_changed_t, mac[0], u8); - P2C(netif_fe_interface_status_changed_t, mac[1], u8); - P2C(netif_fe_interface_status_changed_t, mac[2], u8); - P2C(netif_fe_interface_status_changed_t, mac[3], u8); - P2C(netif_fe_interface_status_changed_t, mac[4], u8); - P2C(netif_fe_interface_status_changed_t, mac[5], u8); - break; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE): - P2C(netif_be_create_t, domid, u32); - P2C(netif_be_create_t, netif_handle, u32); - P2C(netif_be_create_t, mac[0], u8); - P2C(netif_be_create_t, mac[1], u8); - P2C(netif_be_create_t, mac[2], u8); - P2C(netif_be_create_t, mac[3], u8); - P2C(netif_be_create_t, mac[4], u8); - P2C(netif_be_create_t, mac[5], u8); - break; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY): - P2C(netif_be_destroy_t, domid, u32); - P2C(netif_be_destroy_t, netif_handle, u32); - break; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT): - P2C(netif_be_connect_t, domid, u32); - P2C(netif_be_connect_t, netif_handle, u32); - P2C(netif_be_connect_t, tx_shmem_frame, memory_t); - P2C(netif_be_connect_t, rx_shmem_frame, memory_t); - P2C(netif_be_connect_t, evtchn, u16); - break; - case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT): - P2C(netif_be_disconnect_t, domid, u32); - P2C(netif_be_disconnect_t, netif_handle, u32); - break; - case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): - P2C(netif_fe_driver_status_changed_t, status, u32); - P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32); - break; - } - - if ( dict_items_parsed != PyDict_Size(payload) ) - { - PyErr_SetString(PyExc_TypeError, "payload contains bad items"); - PyObject_Del((PyObject *)xum); - return NULL; - } - - return (PyObject *)xum; -} - -static PyObject *xu_message_getattr(PyObject *obj, char *name) -{ - xu_message_object *xum; - if ( strcmp(name, "MAX_PAYLOAD") == 0 ) - return PyInt_FromLong(sizeof(xum->msg.msg)); - return Py_FindMethod(xu_message_methods, obj, name); -} - -static void xu_message_dealloc(PyObject *self) -{ - PyObject_Del(self); -} - -static PyTypeObject xu_message_type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "message", - sizeof(xu_message_object), - 0, - xu_message_dealloc, /* tp_dealloc */ - NULL, /* tp_print */ - xu_message_getattr, /* tp_getattr */ - NULL, /* tp_setattr */ - NULL, /* tp_compare */ - NULL, /* tp_repr */ - NULL, /* tp_as_number */ - NULL, /* tp_as_sequence */ - NULL, /* tp_as_mapping */ - NULL /* tp_hash */ -}; - - - -/* - * *********************** PORT *********************** - */ - -static control_if_t *map_control_interface(int fd, unsigned long pfn) -{ - char *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, - MAP_SHARED, fd, pfn * PAGE_SIZE); - if ( vaddr == MAP_FAILED ) - return NULL; - return (control_if_t *)(vaddr + 2048); -} -static void unmap_control_interface(int fd, control_if_t *c) -{ - char *vaddr = (char *)c - 2048; - (void)munmap(vaddr, PAGE_SIZE); -} - -typedef struct xu_port_object { - PyObject_HEAD; - int mem_fd; - int xc_handle; - u32 remote_dom; - int local_port, remote_port; - control_if_t *interface; - CONTROL_RING_IDX tx_req_cons, tx_resp_prod; - CONTROL_RING_IDX rx_req_prod, rx_resp_cons; -} xu_port_object; - -static PyObject *port_error; - -static int xup_connect(xu_port_object *xup, domid_t dom, - int local_port, int remote_port){ - // From our prespective rx = producer, tx = consumer. - int err = 0; - printf("%s> dom=%u %d:%d\n", __FUNCTION__, (unsigned int)dom, - local_port, remote_port); - - // Consumer = tx. - //xup->interface->tx_resp_prod = 0; - //xup->interface->tx_req_prod = 0; - xup->tx_resp_prod = xup->interface->tx_resp_prod; - xup->tx_req_cons = xup->interface->tx_resp_prod; - printf("%s> tx: %u %u : %u %u\n", __FUNCTION__, - (unsigned int)xup->interface->tx_resp_prod, - (unsigned int)xup->tx_resp_prod, - (unsigned int)xup->tx_req_cons, - (unsigned int)xup->interface->tx_req_prod); - - // Producer = rx. - //xup->interface->rx_req_prod = 0; - //xup->interface->rx_resp_prod = 0; - xup->rx_req_prod = xup->interface->rx_req_prod; - xup->rx_resp_cons = xup->interface->rx_resp_prod; - printf("%s> rx: %u %u : %u %u\n", __FUNCTION__, - (unsigned int)xup->rx_resp_cons, - (unsigned int)xup->interface->rx_resp_prod, - (unsigned int)xup->interface->rx_req_prod, - (unsigned int)xup->rx_req_prod); - - xup->remote_dom = dom; - xup->local_port = local_port; - xup->remote_port = remote_port; - - printf("%s< err=%d\n", __FUNCTION__, err); - return err; -} - -static PyObject *xu_port_notify(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - (void)xc_evtchn_send(xup->xc_handle, xup->local_port); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_port_read_request(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - xu_message_object *xum; - CONTROL_RING_IDX c = xup->tx_req_cons; - control_if_t *cif = xup->interface; - control_msg_t *cmsg; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( (c == cif->tx_req_prod) || - ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) ) - { - PyErr_SetString(port_error, "no request to read"); - return NULL; - } - - cmsg = &cif->tx_ring[MASK_CONTROL_IDX(c)]; - xum = PyObject_New(xu_message_object, &xu_message_type); - memcpy(&xum->msg, cmsg, sizeof(*cmsg)); - if ( xum->msg.length > sizeof(xum->msg.msg) ) - xum->msg.length = sizeof(xum->msg.msg); - xup->tx_req_cons++; - return (PyObject *)xum; -} - -static PyObject *xu_port_write_request(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - xu_message_object *xum; - CONTROL_RING_IDX p = xup->rx_req_prod; - control_if_t *cif = xup->interface; - control_msg_t *cmsg; - - if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) ) - return NULL; - - if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) ) - { - PyErr_SetString(PyExc_TypeError, "expected a xend.utils.message"); - return NULL; - } - - if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) ) - { - PyErr_SetString(port_error, "no space to write request"); - return NULL; - } - - cmsg = &cif->rx_ring[MASK_CONTROL_IDX(p)]; - memcpy(cmsg, &xum->msg, sizeof(*cmsg)); - - xup->rx_req_prod = cif->rx_req_prod = p + 1; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_port_read_response(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - xu_message_object *xum; - CONTROL_RING_IDX c = xup->rx_resp_cons; - control_if_t *cif = xup->interface; - control_msg_t *cmsg; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) ) - { - PyErr_SetString(port_error, "no response to read"); - return NULL; - } - - cmsg = &cif->rx_ring[MASK_CONTROL_IDX(c)]; - xum = PyObject_New(xu_message_object, &xu_message_type); - memcpy(&xum->msg, cmsg, sizeof(*cmsg)); - if ( xum->msg.length > sizeof(xum->msg.msg) ) - xum->msg.length = sizeof(xum->msg.msg); - xup->rx_resp_cons++; - return (PyObject *)xum; -} - -static PyObject *xu_port_write_response(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - xu_message_object *xum; - CONTROL_RING_IDX p = xup->tx_resp_prod; - control_if_t *cif = xup->interface; - control_msg_t *cmsg; - - if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) ) - return NULL; - - if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) ) - { - PyErr_SetString(PyExc_TypeError, "expected a xend.utils.message"); - return NULL; - } - - if ( p == xup->tx_req_cons ) - { - PyErr_SetString(port_error, "no space to write response"); - return NULL; - } - - cmsg = &cif->tx_ring[MASK_CONTROL_IDX(p)]; - memcpy(cmsg, &xum->msg, sizeof(*cmsg)); - - xup->tx_resp_prod = cif->tx_resp_prod = p + 1; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *xu_port_request_to_read(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - CONTROL_RING_IDX c = xup->tx_req_cons; - control_if_t *cif = xup->interface; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( (c == cif->tx_req_prod) || - ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) ) - return PyInt_FromLong(0); - - return PyInt_FromLong(1); -} - -static PyObject *xu_port_space_to_write_request(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - CONTROL_RING_IDX p = xup->rx_req_prod; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) ) - return PyInt_FromLong(0); - - return PyInt_FromLong(1); -} - -static PyObject *xu_port_response_to_read(PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - CONTROL_RING_IDX c = xup->rx_resp_cons; - control_if_t *cif = xup->interface; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) ) - return PyInt_FromLong(0); - - return PyInt_FromLong(1); -} - -static PyObject *xu_port_space_to_write_response( - PyObject *self, PyObject *args) -{ - xu_port_object *xup = (xu_port_object *)self; - CONTROL_RING_IDX p = xup->tx_resp_prod; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( p == xup->tx_req_cons ) - return PyInt_FromLong(0); - - return PyInt_FromLong(1); -} - -static PyMethodDef xu_port_methods[] = { - { "notify", - (PyCFunction)xu_port_notify, - METH_VARARGS, - "Send a notification to the remote end.\n" }, - - { "read_request", - (PyCFunction)xu_port_read_request, - METH_VARARGS, - "Read a request message from the control interface.\n" }, - - { "write_request", - (PyCFunction)xu_port_write_request, - METH_VARARGS, - "Write a request message to the control interface.\n" }, - - { "read_response", - (PyCFunction)xu_port_read_response, - METH_VARARGS, - "Read a response message from the control interface.\n" }, - - { "write_response", - (PyCFunction)xu_port_write_response, - METH_VARARGS, - "Write a response message to the control interface.\n" }, - - { "request_to_read", - (PyCFunction)xu_port_request_to_read, - METH_VARARGS, - "Returns TRUE if there is a request message to read.\n" }, - - { "space_to_write_request", - (PyCFunction)xu_port_space_to_write_request, - METH_VARARGS, - "Returns TRUE if there is space to write a request message.\n" }, - - { "response_to_read", - (PyCFunction)xu_port_response_to_read, - METH_VARARGS, - "Returns TRUE if there is a response message to read.\n" }, - - { "space_to_write_response", - (PyCFunction)xu_port_space_to_write_response, - METH_VARARGS, - "Returns TRUE if there is space to write a response message.\n" }, - - { NULL, NULL, 0, NULL } -}; - -staticforward PyTypeObject xu_port_type; - -static PyObject *xu_port_new(PyObject *self, PyObject *args) -{ - xu_port_object *xup; - u32 dom; - int port1, port2; - xc_dominfo_t info; - - if ( !PyArg_ParseTuple(args, "i", &dom) ) - return NULL; - - xup = PyObject_New(xu_port_object, &xu_port_type); - - if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 ) - { - PyErr_SetString(port_error, "Could not open '/dev/mem'"); - goto fail1; - } - - /* Set the General-Purpose Subject whose page frame will be mapped. */ - (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)dom); - - if ( (xup->xc_handle = xc_interface_open()) == -1 ) - { - PyErr_SetString(port_error, "Could not open Xen control interface"); - goto fail2; - } - - if ( dom == 0 ) - { - /* - * The control-interface event channel for DOM0 is already set up. - * We use an ioctl to discover the port at our end of the channel. - */ - port1 = ioctl(xup->xc_handle, IOCTL_PRIVCMD_INITDOMAIN_EVTCHN, NULL); - port2 = -1; /* We don't need the remote end of the DOM0 link. */ - if ( port1 < 0 ) - { - PyErr_SetString(port_error, "Could not open channel to DOM0"); - goto fail3; - } - } - else if ( xc_evtchn_bind_interdomain(xup->xc_handle, - DOMID_SELF, dom, - &port1, &port2) != 0 ) - { - PyErr_SetString(port_error, "Could not open channel to domain"); - goto fail3; - } - - if ( (xc_domain_getinfo(xup->xc_handle, dom, 1, &info) != 1) || - (info.domid != dom) ) - { - PyErr_SetString(port_error, "Failed to obtain domain status"); - goto fail4; - } - - xup->interface = - map_control_interface(xup->mem_fd, info.shared_info_frame); - if ( xup->interface == NULL ) - { - PyErr_SetString(port_error, "Failed to map domain control interface"); - goto fail4; - } - - xup_connect(xup, dom, port1, port2); - return (PyObject *)xup; - - - fail4: - (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1); - fail3: - (void)xc_interface_close(xup->xc_handle); - fail2: - (void)close(xup->mem_fd); - fail1: - PyObject_Del((PyObject *)xup); - return NULL; -} - -static PyObject *xu_port_getattr(PyObject *obj, char *name) -{ - xu_port_object *xup = (xu_port_object *)obj; - if ( strcmp(name, "local_port") == 0 ) - return PyInt_FromLong(xup->local_port); - if ( strcmp(name, "remote_port") == 0 ) - return PyInt_FromLong(xup->remote_port); - if ( strcmp(name, "remote_dom") == 0 ) - return PyInt_FromLong(xup->remote_dom); - return Py_FindMethod(xu_port_methods, obj, name); -} - -static void xu_port_dealloc(PyObject *self) -{ - xu_port_object *xup = (xu_port_object *)self; - unmap_control_interface(xup->mem_fd, xup->interface); - if ( xup->remote_dom != 0 ) - (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port); - (void)xc_interface_close(xup->xc_handle); - (void)close(xup->mem_fd); - PyObject_Del(self); -} - -static PyTypeObject xu_port_type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "port", - sizeof(xu_port_object), - 0, - xu_port_dealloc, /* tp_dealloc */ - NULL, /* tp_print */ - xu_port_getattr, /* tp_getattr */ - NULL, /* tp_setattr */ - NULL, /* tp_compare */ - NULL, /* tp_repr */ - NULL, /* tp_as_number */ - NULL, /* tp_as_sequence */ - NULL, /* tp_as_mapping */ - NULL /* tp_hash */ -}; - - - -/* - * *********************** BUFFER *********************** - */ - -#define BUFSZ 65536 -#define MASK_BUF_IDX(_i) ((_i)&(BUFSZ-1)) -typedef unsigned int BUF_IDX; - -typedef struct { - PyObject_HEAD; - char *buf; - unsigned int prod, cons; -} xu_buffer_object; - -static PyObject *__xu_buffer_peek(xu_buffer_object *xub, int max) -{ - PyObject *str1, *str2; - int len1, len2, c = MASK_BUF_IDX(xub->cons); - - len1 = xub->prod - xub->cons; - if ( len1 > (BUFSZ - c) ) /* clip to ring wrap */ - len1 = BUFSZ - c; - if ( len1 > max ) /* clip to specified maximum */ - len1 = max; - if ( len1 < 0 ) /* sanity */ - len1 = 0; - - if ( (str1 = PyString_FromStringAndSize(&xub->buf[c], len1)) == NULL ) - return NULL; - - if ( (len1 < (xub->prod - xub->cons)) && (len1 < max) ) - { - len2 = max - len1; - if ( len2 > MASK_BUF_IDX(xub->prod) ) - len2 = MASK_BUF_IDX(xub->prod); - if ( len2 > 0 ) - { - str2 = PyString_FromStringAndSize(&xub->buf[0], len2); - if ( str2 == NULL ) - return NULL; - PyString_ConcatAndDel(&str1, str2); - if ( str1 == NULL ) - return NULL; - } - } - - return str1; -} - -static PyObject *xu_buffer_peek(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - int max = 1024; - - if ( !PyArg_ParseTuple(args, "|i", &max) ) - return NULL; - - return __xu_buffer_peek(xub, max); -} - -static PyObject *xu_buffer_read(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - PyObject *str; - int max = 1024; - - if ( !PyArg_ParseTuple(args, "|i", &max) ) - return NULL; - - if ( (str = __xu_buffer_peek(xub, max)) != NULL ) - xub->cons += PyString_Size(str); - - return str; -} - -static PyObject *xu_buffer_discard(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - int max, len; - - if ( !PyArg_ParseTuple(args, "i", &max) ) - return NULL; - - len = xub->prod - xub->cons; - if ( len > max ) - len = max; - if ( len < 0 ) - len = 0; - - xub->cons += len; - - return PyInt_FromLong(len); -} - -static PyObject *xu_buffer_write(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - char *str; - int len, len1, len2; - - if ( !PyArg_ParseTuple(args, "s#", &str, &len) ) - return NULL; - - len1 = len; - if ( len1 > (BUFSZ - MASK_BUF_IDX(xub->prod)) ) - len1 = BUFSZ - MASK_BUF_IDX(xub->prod); - if ( len1 > (BUFSZ - (xub->prod - xub->cons)) ) - len1 = BUFSZ - (xub->prod - xub->cons); - - if ( len1 == 0 ) - return PyInt_FromLong(0); - - memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[0], len1); - xub->prod += len1; - - if ( len1 < len ) - { - len2 = len - len1; - if ( len2 > (BUFSZ - MASK_BUF_IDX(xub->prod)) ) - len2 = BUFSZ - MASK_BUF_IDX(xub->prod); - if ( len2 > (BUFSZ - (xub->prod - xub->cons)) ) - len2 = BUFSZ - (xub->prod - xub->cons); - if ( len2 != 0 ) - { - memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[len1], len2); - xub->prod += len2; - return PyInt_FromLong(len1 + len2); - } - } - - return PyInt_FromLong(len1); -} - -static PyObject *xu_buffer_empty(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( xub->cons == xub->prod ) - return PyInt_FromLong(1); - - return PyInt_FromLong(0); -} - -static PyObject *xu_buffer_full(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - if ( (xub->prod - xub->cons) == BUFSZ ) - return PyInt_FromLong(1); - - return PyInt_FromLong(0); -} - -static PyMethodDef xu_buffer_methods[] = { - { "peek", - (PyCFunction)xu_buffer_peek, - METH_VARARGS, - "Peek up to @max bytes from the buffer. Returns a string.\n" }, - - { "read", - (PyCFunction)xu_buffer_read, - METH_VARARGS, - "Read up to @max bytes from the buffer. Returns a string.\n" }, - - { "discard", - (PyCFunction)xu_buffer_discard, - METH_VARARGS, - "Discard up to @max bytes from the buffer. Returns number of bytes.\n" }, - - { "write", - (PyCFunction)xu_buffer_write, - METH_VARARGS, - "Write @string into buffer. Return number of bytes written.\n" }, - - { "empty", - (PyCFunction)xu_buffer_empty, - METH_VARARGS, - "Return TRUE if the buffer is empty.\n" }, - - { "full", - (PyCFunction)xu_buffer_full, - METH_VARARGS, - "Return TRUE if the buffer is full.\n" }, - - { NULL, NULL, 0, NULL } -}; - -staticforward PyTypeObject xu_buffer_type; - -static PyObject *xu_buffer_new(PyObject *self, PyObject *args) -{ - xu_buffer_object *xub; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - xub = PyObject_New(xu_buffer_object, &xu_buffer_type); - - if ( (xub->buf = malloc(BUFSZ)) == NULL ) - { - PyObject_Del((PyObject *)xub); - return NULL; - } - - xub->prod = xub->cons = 0; - - return (PyObject *)xub; -} - -static PyObject *xu_buffer_getattr(PyObject *obj, char *name) -{ - return Py_FindMethod(xu_buffer_methods, obj, name); -} - -static void xu_buffer_dealloc(PyObject *self) -{ - xu_buffer_object *xub = (xu_buffer_object *)self; - free(xub->buf); - PyObject_Del(self); -} - -static PyTypeObject xu_buffer_type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "buffer", - sizeof(xu_buffer_object), - 0, - xu_buffer_dealloc, /* tp_dealloc */ - NULL, /* tp_print */ - xu_buffer_getattr, /* tp_getattr */ - NULL, /* tp_setattr */ - NULL, /* tp_compare */ - NULL, /* tp_repr */ - NULL, /* tp_as_number */ - NULL, /* tp_as_sequence */ - NULL, /* tp_as_mapping */ - NULL /* tp_hash */ -}; - - - -/* - * *********************** MODULE WRAPPER *********************** - */ - -static void handle_child_death(int dummy) -{ - while ( waitpid(-1, NULL, WNOHANG) > 0 ) - continue; -} - -static PyObject *xu_autoreap(PyObject *self, PyObject *args) -{ - struct sigaction sa; - - if ( !PyArg_ParseTuple(args, "") ) - return NULL; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = handle_child_death; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; - (void)sigaction(SIGCHLD, &sa, NULL); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef xu_methods[] = { - { "notifier", xu_notifier_new, METH_VARARGS, - "Create a new notifier." }, - { "message", xu_message_new, METH_VARARGS, - "Create a new communications message." }, - { "port", xu_port_new, METH_VARARGS, - "Create a new communications port." }, - { "buffer", xu_buffer_new, METH_VARARGS, - "Create a new ring buffer." }, - { "autoreap", xu_autoreap, METH_VARARGS, - "Ensure that zombie children are automatically reaped by the OS." }, - { NULL, NULL, 0, NULL } -}; - -PyMODINIT_FUNC initutils(void) -{ - PyObject *m, *d; - - m = Py_InitModule("xend.utils", xu_methods); - - d = PyModule_GetDict(m); - port_error = PyErr_NewException("xend.utils.PortError", NULL, NULL); - PyDict_SetItemString(d, "PortError", port_error); -} diff --git a/tools/xend-old/setup.py b/tools/xend-old/setup.py deleted file mode 100644 index 66ed7a937e..0000000000 --- a/tools/xend-old/setup.py +++ /dev/null @@ -1,19 +0,0 @@ - -from distutils.core import setup, Extension - -utils = Extension("utils", - extra_compile_args = ["-fno-strict-aliasing"], - include_dirs = ["../xc/lib", - "../../xen/include/hypervisor-ifs", - "../../linux-xen-sparse/include"], - library_dirs = ["../xc/lib"], - libraries = ["xc"], - sources = ["lib/utils.c"]) - -setup(name = "xend", - version = "1.0", - packages = ["xend"], - package_dir = { "xend" : "lib" }, - ext_package = "xend", - ext_modules = [ utils ] - ) diff --git a/tools/xend-old/xend b/tools/xend-old/xend deleted file mode 100755 index 6e321bbad3..0000000000 --- a/tools/xend-old/xend +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python - -import os, sys, xend.main - -def main(): - if not sys.argv[1:]: - print 'usage: %s {start|stop|restart}' % sys.argv[0] - elif os.fork(): - pid, status = os.wait() - return status >> 8 - elif sys.argv[1] == 'start': - return xend.main.start_daemon() - elif sys.argv[1] == 'stop': - return xend.main.stop_daemon() - elif sys.argv[1] == 'restart': - return xend.main.stop_daemon() or xend.main.start_daemon() - else: - print 'not an option:', sys.argv[1] - return 1 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tools/xentrace/formats b/tools/xentrace/formats index 9a5b157f47..0452385484 100644 --- a/tools/xentrace/formats +++ b/tools/xentrace/formats @@ -1,17 +1,17 @@ -#0x00010000 CPU%(cpu)d %(tsc).6f sched_add_domain(0x%(3)08x) [ dom id = 0x%(1)x%(2)08x ] -#0x00010001 CPU%(cpu)d %(tsc).6f sched_rem_domain(0x%08(3)x) [ dom id = 0x%(1)x%(2)08x ] -#0x00010002 CPU%(cpu)d %(tsc).6f __wake_up(0x%(3)08x) [ dom id = 0x%(1)x%(2)08x ] -#0x00010003 CPU%(cpu)d %(tsc).6f do_block() [ current = 0x%(2)08x ] -#0x00010004 CPU%(cpu)d %(tsc).6f do_yield() [ current = %(2)08x ] -#0x00010005 CPU%(cpu)d %(tsc).6f do_set_timer_op(0x%(4)08x, 0x%(5)08x) [ current = 0x%(3)08x ] -#0x00010006 CPU%(cpu)d %(tsc).6f sched_ctl(0x%(1)08x) -#0x00010007 CPU%(cpu)d %(tsc).6f sched_adjdom(params) [ dom id = 0x%(1)x%(2)08x ] -#0x00010008 CPU%(cpu)d %(tsc).6f __reschedule(0x%(3)08x) [ dom id = 0x%(1)x%(2)08x ] -#0x00010009 CPU%(cpu)d %(tsc).6f switching to task_struct 0x%(1)08x [ dom id = 0x%(1)x ] -#0x0001000A CPU%(cpu)d %(tsc).6f s_timer_fn(unused) -#0x0001000B CPU%(cpu)d %(tsc).6f t_timer_fn(unused) -#0x0001000C CPU%(cpu)d %(tsc).6f dom_timer_fn(data) -#0x0001000D CPU%(cpu)d %(tsc).6f fallback_timer_fn(unused) +0x00010000 CPU%(cpu)d %(tsc).6f sched_add_domain(0x%(3)08x) [ dom id = 0x%(2)08x ] +0x00010001 CPU%(cpu)d %(tsc).6f sched_rem_domain(0x%08(3)x) [ dom id = 0x%(2)08x ] +0x00010002 CPU%(cpu)d %(tsc).6f __wake_up(0x%(3)08x) [ dom id = 0x%(2)08x ] +0x00010003 CPU%(cpu)d %(tsc).6f do_block() [ current = 0x%(2)08x ] +0x00010004 CPU%(cpu)d %(tsc).6f do_yield() [ current = %(2)08x ] +0x00010005 CPU%(cpu)d %(tsc).6f do_set_timer_op(0x%(4)08x, 0x%(5)08x) [ current = 0x%(3)08x ] +0x00010006 CPU%(cpu)d %(tsc).6f sched_ctl(0x%(1)08x) +0x00010007 CPU%(cpu)d %(tsc).6f sched_adjdom(params) [ dom id = 0x%(2)08x ] +0x00010008 CPU%(cpu)d %(tsc).6f __reschedule(0x%(3)08x) [ dom id = 0x(2)08x ] +0x00010009 CPU%(cpu)d %(tsc).6f switching to task_struct 0x%(1)08x [ dom id = 0x%(1)x ] +0x0001000A CPU%(cpu)d %(tsc).6f s_timer_fn(unused) +0x0001000B CPU%(cpu)d %(tsc).6f t_timer_fn(unused) +0x0001000C CPU%(cpu)d %(tsc).6f dom_timer_fn(data) +0x0001000D CPU%(cpu)d %(tsc).6f fallback_timer_fn(unused) 0x00020008 CPU%(cpu)d %(tsc).6f enter: dom0_create_dom ( ) diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c index dae9b67d80..3560745a42 100644 --- a/tools/xentrace/xentrace.c +++ b/tools/xentrace/xentrace.c @@ -311,7 +311,7 @@ int monitor_tbufs(FILE *logfile) /* printf("XX%d: cons=%ld head=%ld %p\n", i, cons[i], meta[i]->head, data[i] + (cons[i] % size_in_recs) ); */ - while( cons[i] < meta[i]->head ) + while( cons[i] != meta[i]->head ) { /* if( (cons[i] % 6 ) == 0 ) |