[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Merge



# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Node ID e843c1fde3c2df049f9123b9998ca5cab1efad0f
# Parent  a89599a12d4bf27e224135f0fe7c670526803a42
# Parent  a330509abb20982fc75fb5fa66155d9bb09225f9
Merge
---
 tools/examples/init.d/xendomains             |    9 ++++-
 tools/ioemu/hw/usb-hid.c                     |   19 +++++++++--
 tools/ioemu/hw/usb-uhci.c                    |   42 ++++++++++++++++---------
 tools/python/xen/web/httpserver.py           |   44 +++++++++++++++++----------
 tools/python/xen/xend/XendConfig.py          |   37 +++++++++++++++++++++-
 tools/python/xen/xend/XendDomainInfo.py      |   19 ++++++-----
 tools/python/xen/xend/server/SrvDomain.py    |   13 +++++++
 tools/python/xen/xend/server/SrvDomainDir.py |   37 ++++++++++++++++++++++
 tools/python/xen/xm/create.py                |    4 +-
 tools/python/xen/xm/main.py                  |   17 +++++++---
 10 files changed, 187 insertions(+), 54 deletions(-)

diff -r a89599a12d4b -r e843c1fde3c2 tools/examples/init.d/xendomains
--- a/tools/examples/init.d/xendomains  Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/examples/init.d/xendomains  Thu Dec 07 13:18:08 2006 +0000
@@ -204,12 +204,14 @@ start()
        return; 
     fi
 
+    saved_domains=" "
     if [ "$XENDOMAINS_RESTORE" = "true" ] &&
        contains_something "$XENDOMAINS_SAVE"
     then
         mkdir -p $(dirname "$LOCKFILE")
        touch $LOCKFILE
        echo -n "Restoring Xen domains:"
+       saved_domains=`ls $XENDOMAINS_SAVE`
        for dom in $XENDOMAINS_SAVE/*; do
            echo -n " ${dom##*/}"
            xm restore $dom
@@ -234,9 +236,14 @@ start()
        # Create all domains with config files in XENDOMAINS_AUTO.
        # TODO: We should record which domain name belongs 
        # so we have the option to selectively shut down / migrate later
+       # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
+       # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't 
+       # restore correctly it requires administrative attention.
        for dom in $XENDOMAINS_AUTO/*; do
            echo -n " ${dom##*/}"
-           if is_running $dom; then
+           shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
+           echo $saved_domains | grep -w $shortdom > /dev/null
+           if [ $? -eq 0 ] || is_running $dom; then
                echo -n "(skip)"
            else
                xm create --quiet --defconfig $dom
diff -r a89599a12d4b -r e843c1fde3c2 tools/ioemu/hw/usb-hid.c
--- a/tools/ioemu/hw/usb-hid.c  Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/ioemu/hw/usb-hid.c  Thu Dec 07 13:18:08 2006 +0000
@@ -39,6 +39,7 @@ typedef struct USBMouseState {
     int x, y;
     int kind;
     int mouse_grabbed;
+    int status_changed;
 } USBMouseState;
 
 /* mostly the same values as the Bochs USB Mouse device */
@@ -231,6 +232,7 @@ static void usb_mouse_event(void *opaque
     s->dy += dy1;
     s->dz += dz1;
     s->buttons_state = buttons_state;
+    s->status_changed = 1;
 }
 
 static void usb_tablet_event(void *opaque,
@@ -242,6 +244,7 @@ static void usb_tablet_event(void *opaqu
     s->y = y;
     s->dz += dz;
     s->buttons_state = buttons_state;
+    s->status_changed = 1;
 }
 
 static inline int int_clamp(int val, int vmin, int vmax)
@@ -483,10 +486,16 @@ static int usb_mouse_handle_data(USBDevi
     switch(pid) {
     case USB_TOKEN_IN:
         if (devep == 1) {
-           if (s->kind == USB_MOUSE)
-               ret = usb_mouse_poll(s, data, len);
-           else if (s->kind == USB_TABLET)
-               ret = usb_tablet_poll(s, data, len);
+            if (s->kind == USB_MOUSE)
+                ret = usb_mouse_poll(s, data, len);
+            else if (s->kind == USB_TABLET)
+                ret = usb_tablet_poll(s, data, len);
+
+            if (!s->status_changed)
+                ret = USB_RET_NAK;
+            else
+                s->status_changed = 0;
+
         } else {
             goto fail;
         }
@@ -523,6 +532,7 @@ USBDevice *usb_tablet_init(void)
     s->dev.handle_data = usb_mouse_handle_data;
     s->dev.handle_destroy = usb_mouse_handle_destroy;
     s->kind = USB_TABLET;
+    s->status_changed = 0;
 
     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
 
@@ -544,6 +554,7 @@ USBDevice *usb_mouse_init(void)
     s->dev.handle_data = usb_mouse_handle_data;
     s->dev.handle_destroy = usb_mouse_handle_destroy;
     s->kind = USB_MOUSE;
+    s->status_changed = 0;
 
     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
 
diff -r a89599a12d4b -r e843c1fde3c2 tools/ioemu/hw/usb-uhci.c
--- a/tools/ioemu/hw/usb-uhci.c Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/ioemu/hw/usb-uhci.c Thu Dec 07 13:18:08 2006 +0000
@@ -424,12 +424,10 @@ static int uhci_handle_td(UHCIState *s, 
     uint8_t buf[2048];
     int len, max_len, err, ret;
 
-    if (td->ctrl & TD_CTRL_IOC) {
-        *int_mask |= 0x01;
-    }
-    
-    if (!(td->ctrl & TD_CTRL_ACTIVE))
-        return 1;
+    if (!(td->ctrl & TD_CTRL_ACTIVE)){
+        ret = 1;
+        goto out;
+    }
 
     /* TD is active */
     max_len = ((td->token >> 21) + 1) & 0x7ff;
@@ -467,7 +465,8 @@ static int uhci_handle_td(UHCIState *s, 
         /* invalid pid : frame interrupted */
         s->status |= UHCI_STS_HCPERR;
         uhci_update_irq(s);
-        return -1;
+        ret = -1;
+        goto out;
     }
     if (td->ctrl & TD_CTRL_IOS)
         td->ctrl &= ~TD_CTRL_ACTIVE;
@@ -479,10 +478,12 @@ static int uhci_handle_td(UHCIState *s, 
             len < max_len) {
             *int_mask |= 0x02;
             /* short packet: do not update QH */
-            return 1;
+            ret = 1;
+            goto out;
         } else {
             /* success */
-            return 0;
+            ret = 0;
+            goto out;
         }
     } else {
         switch(ret) {
@@ -501,23 +502,34 @@ static int uhci_handle_td(UHCIState *s, 
             }
             td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) | 
                 (err << TD_CTRL_ERROR_SHIFT);
-            return 1;
+            ret = 1;
+            goto out;
         case USB_RET_NAK:
             td->ctrl |= TD_CTRL_NAK;
             if (pid == USB_TOKEN_SETUP)
                 goto do_timeout;
-            return 1;
+            ret = 1;
+            goto out;
         case USB_RET_STALL:
             td->ctrl |= TD_CTRL_STALL;
             td->ctrl &= ~TD_CTRL_ACTIVE;
-            return 1;
+            ret = 1;
+            goto out;
         case USB_RET_BABBLE:
             td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
             td->ctrl &= ~TD_CTRL_ACTIVE;
             /* frame interrupted */
-            return -1;
-        }
-    }
+            ret = -1;
+            goto out;
+        }
+    }
+   
+out:
+    /* If TD is inactive and IOC bit set to 1 then update int_mask */ 
+    if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
+        *int_mask |= 0x01;
+    }
+    return ret;
 }
 
 static void uhci_frame_timer(void *opaque)
diff -r a89599a12d4b -r e843c1fde3c2 tools/python/xen/web/httpserver.py
--- a/tools/python/xen/web/httpserver.py        Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/python/xen/web/httpserver.py        Thu Dec 07 13:18:08 2006 +0000
@@ -264,7 +264,32 @@ class HttpServerRequest(http.HttpRequest
             s += x + "/"
             self.write(' <a href="%s">%s</a>/' % (s, x))
         self.write("</h1>")
-        
+
+class HttpServerClient:
+
+    def __init__(self, server, sock, addr):
+        self.server = server
+        self.sock = sock
+        self.addr = addr
+
+    def process(self):
+        thread = threading.Thread(target=self.doProcess)
+        thread.setDaemon(True)
+        thread.start()
+
+    def doProcess(self):
+        try:
+            rp = RequestProcessor(self.server, self.sock, self.addr)
+            rp.process()
+        except SystemExit:
+            raise
+        except Exception, ex:
+            print 'HttpServer>processRequest> exception: ', ex
+            try:
+                self.sock.close()
+            except:
+                pass
+
 class HttpServer:
 
     backlog = 5
@@ -286,8 +311,8 @@ class HttpServer:
 
         while not self.closed:
             (sock, addr) = self.accept()
-            self.processRequest(sock, addr)
-
+            cl = HttpServerClient(self, sock, addr)
+            cl.process()
 
     def stop(self):
         self.close()
@@ -313,19 +338,6 @@ class HttpServer:
             self.socket.close()
         except:
             pass
-
-    def processRequest(self, sock, addr):
-        try:
-            rp = RequestProcessor(self, sock, addr)
-            rp.process()
-        except SystemExit:
-            raise
-        except Exception, ex:
-            print 'HttpServer>processRequest> exception: ', ex
-            try:
-                sock.close()
-            except:
-                pass
 
     def getServerAddr(self):
         return (socket.gethostname(), self.port)
diff -r a89599a12d4b -r e843c1fde3c2 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Thu Dec 07 13:18:08 2006 +0000
@@ -41,6 +41,39 @@ def reverse_dict(adict):
 
 def bool0(v):
     return v != '0' and bool(v)
+
+# Recursively copy a data struct, scrubbing out VNC passwords.
+# Will scrub any dict entry with a key of 'vncpasswd' or any
+# 2-element list whose first member is 'vncpasswd'. It will
+# also scrub a string matching '(vncpasswd XYZ)'. Everything
+# else is no-op passthrough
+def scrub_password(data):
+    if type(data) == dict or type(data) == XendConfig:
+        scrubbed = {}
+        for key in data.keys():
+            if key == "vncpasswd":
+                scrubbed[key] = "XXXXXXXX"
+            else:
+                scrubbed[key] = scrub_password(data[key])
+        return scrubbed
+    elif type(data) == list:
+        if len(data) == 2 and type(data[0]) == str and data[0] == 'vncpasswd':
+            return ['vncpasswd', 'XXXXXXXX']
+        else:
+            scrubbed = []
+            for entry in data:
+                scrubbed.append(scrub_password(entry))
+            return scrubbed
+    elif type(data) == tuple:
+        scrubbed = []
+        for entry in data:
+            scrubbed.append(scrub_password(entry))
+        return tuple(scrubbed)
+    elif type(data) == str:
+        return re.sub(r'\(vncpasswd\s+[^\)]+\)','(vncpasswd XXXXXX)', data)
+    else:
+        return data
+
 
 # Mapping from XendConfig configuration keys to the old
 # legacy configuration keys that map directly.
@@ -269,7 +302,7 @@ class XendConfig(dict):
             # output from xc.domain_getinfo
             self._dominfo_to_xapi(dominfo)
 
-        log.debug('XendConfig.init: %s' % self)
+        log.debug('XendConfig.init: %s' % scrub_password(self))
 
         # validators go here
         self.validate()
@@ -478,7 +511,7 @@ class XendConfig(dict):
             else:
                 for opt, val in config[1:]:
                     dev_info[opt] = val
-                log.debug("XendConfig: reading device: %s" % dev_info)
+                log.debug("XendConfig: reading device: %s" % 
scrub_password(dev_info))
                 # create uuid if it doesn't
                 dev_uuid = dev_info.get('uuid', uuid.createString())
                 dev_info['uuid'] = dev_uuid
diff -r a89599a12d4b -r e843c1fde3c2 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Dec 07 13:18:08 2006 +0000
@@ -40,6 +40,7 @@ from xen.xend import balloon, sxp, uuid,
 from xen.xend import balloon, sxp, uuid, image, arch
 from xen.xend import XendRoot, XendNode, XendConfig
 
+from xen.xend.XendConfig import scrub_password
 from xen.xend.XendBootloader import bootloader
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendDevices import XendDevices
@@ -148,7 +149,7 @@ def create(config):
     @raise VmError: Invalid configuration or failure to start.
     """
 
-    log.debug("XendDomainInfo.create(%s)", config)
+    log.debug("XendDomainInfo.create(%s)", scrub_password(config))
     vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
     try:
         vm.start()
@@ -175,7 +176,7 @@ def recreate(info, priv):
     @raise XendError: Errors with configuration.
     """
 
-    log.debug("XendDomainInfo.recreate(%s)", info)
+    log.debug("XendDomainInfo.recreate(%s)", scrub_password(info))
 
     assert not info['dying']
 
@@ -257,7 +258,7 @@ def restore(config):
     @raise XendError: Errors with configuration.
     """
 
-    log.debug("XendDomainInfo.restore(%s)", config)
+    log.debug("XendDomainInfo.restore(%s)", scrub_password(config))
     vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
                         resume = True)
     try:
@@ -280,7 +281,7 @@ def createDormant(domconfig):
     @raise XendError: Errors with configuration.    
     """
     
-    log.debug("XendDomainInfo.createDormant(%s)", domconfig)
+    log.debug("XendDomainInfo.createDormant(%s)", scrub_password(domconfig))
     
     # domid does not make sense for non-running domains.
     domconfig.pop('domid', None)
@@ -520,11 +521,11 @@ class XendDomainInfo:
         @param dev_config: device configuration
         @type  dev_config: SXP object (parsed config)
         """
-        log.debug("XendDomainInfo.device_create: %s" % dev_config)
+        log.debug("XendDomainInfo.device_create: %s" % 
scrub_password(dev_config))
         dev_type = sxp.name(dev_config)
         dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
         dev_config_dict = self.info['devices'][dev_uuid][1]
-        log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
+        log.debug("XendDomainInfo.device_create: %s" % 
scrub_password(dev_config_dict))
         devid = self._createDevice(dev_type, dev_config_dict)
         self._waitForDevice(dev_type, devid)
         return self.getDeviceController(dev_type).sxpr(devid)
@@ -746,7 +747,7 @@ class XendDomainInfo:
 
         to_store.update(self._vcpuDomDetails())
 
-        log.debug("Storing domain details: %s", to_store)
+        log.debug("Storing domain details: %s", scrub_password(to_store))
 
         self._writeDom(to_store)
 
@@ -1188,7 +1189,7 @@ class XendDomainInfo:
         """
         for (devclass, config) in self.info.get('devices', {}).values():
             if devclass in XendDevices.valid_devices():            
-                log.info("createDevice: %s : %s" % (devclass, config))
+                log.info("createDevice: %s : %s" % (devclass, 
scrub_password(config)))
                 self._createDevice(devclass, config)
 
         if self.image:
@@ -1667,7 +1668,7 @@ class XendDomainInfo:
         if not self._readVm('xend/restart_count'):
             to_store['xend/restart_count'] = str(0)
 
-        log.debug("Storing VM details: %s", to_store)
+        log.debug("Storing VM details: %s", scrub_password(to_store))
 
         self._writeVm(to_store)
         self._setVmPermissions()
diff -r a89599a12d4b -r e843c1fde3c2 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/python/xen/xend/server/SrvDomain.py Thu Dec 07 13:18:08 2006 +0000
@@ -21,6 +21,7 @@ from xen.xend import sxp
 from xen.xend import sxp
 from xen.xend import XendDomain
 from xen.xend.Args import FormFn
+from xen.xend.XendLogging import log
 
 from xen.web.SrvDir import SrvDir
 
@@ -62,6 +63,18 @@ class SrvDomain(SrvDir):
     def op_shutdown(self, _, req):
         self.acceptCommand(req)
         return self.dom.shutdown(req.args['reason'][0])
+
+    def op_delete(self, _, req):
+        self.acceptCommand(req)
+        return self.xd.domain_delete(self.dom.getName())
+
+    def op_start(self, _, req):
+        self.acceptCommand(req)
+        paused = False
+        if 'paused' in req.args and req.args['paused'] == [1]:
+            paused = True
+        log.debug("Starting domain " + self.dom.getName() + " " + str(paused))
+        return self.xd.domain_start(self.dom.getName(), paused)
 
     def op_sysrq(self, _, req):
         self.acceptCommand(req)
diff -r a89599a12d4b -r e843c1fde3c2 
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py      Thu Dec 07 13:14:44 
2006 +0000
+++ b/tools/python/xen/xend/server/SrvDomainDir.py      Thu Dec 07 13:18:08 
2006 +0000
@@ -25,6 +25,8 @@ from xen.xend.XendDomainInfo import Xend
 from xen.xend.XendDomainInfo import XendDomainInfo
 from xen.xend.Args import FormFn
 from xen.xend.XendError import XendError
+from xen.xend.XendLogging import log
+from xen.xend.XendConstants import DOM_STATE_RUNNING
 
 from xen.web.SrvDir import SrvDir
 from SrvDomain import SrvDomain
@@ -101,6 +103,35 @@ class SrvDomainDir(SrvDir):
             out.close()
             return val
 
+    def op_new(self, _, req):
+        """Define a new domain.
+        Expects the domain config in request parameter 'config' in SXP format.
+        """
+        ok = 0
+        errmsg = ''
+        try:
+            configstring = req.args.get('config')[0]
+            #print 'op_create>', 'config:', configstring
+            pin = sxp.Parser()
+            pin.input(configstring)
+            pin.input_eof()
+            config = pin.get_val()
+            ok = 1
+        except sxp.ParseError, ex:
+            errmsg = 'Invalid configuration ' + str(ex)
+        except Exception, ex:
+            print 'op_create> Exception in config', ex
+            traceback.print_exc()
+            errmsg = 'Configuration error ' + str(ex)
+        if not ok:
+            raise XendError(errmsg)
+        try:
+            self.xd.domain_new(config)
+        except Exception, ex:
+            print 'op_create> Exception creating domain:'
+            traceback.print_exc()
+            raise XendError("Error creating domain: " + str(ex))
+
     def op_restore(self, op, req):
         """Restore a domain from file.
 
@@ -159,7 +190,11 @@ class SrvDomainDir(SrvDir):
             if detail:
                 sxp.show(map(XendDomainInfo.sxpr, self.xd.list()), out=req)
             else:
-                sxp.show(self.xd.list_names(), out=req)
+                state = DOM_STATE_RUNNING
+                if 'state' in req.args and len(req.args['state']) > 0:
+                    state = req.args['state'][0]
+                log.debug("Listing domains in state " + str(state))
+                sxp.show(self.xd.list_names(state), out=req)
         else:
             domains = self.xd.list_sorted()
             req.write('<ul>')
diff -r a89599a12d4b -r e843c1fde3c2 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/python/xen/xm/create.py     Thu Dec 07 13:18:08 2006 +0000
@@ -704,8 +704,10 @@ def configure_hvm(config_image, vals):
     config_image.append(['vncpasswd', vals.vncpasswd])
 
 def run_bootloader(vals, config_image):
+    if not os.access(vals.bootloader, os.F_OK):
+        err("Bootloader '%s' does not exist" % vals.bootloader)
     if not os.access(vals.bootloader, os.X_OK):
-        err("Bootloader isn't executable")
+        err("Bootloader '%s' isn't executable" % vals.bootloader)
     if len(vals.disk) < 1:
         err("No disks configured and boot loader requested")
     (uname, dev, mode, backend) = vals.disk[0]
diff -r a89599a12d4b -r e843c1fde3c2 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Dec 07 13:14:44 2006 +0000
+++ b/tools/python/xen/xm/main.py       Thu Dec 07 13:18:08 2006 +0000
@@ -30,6 +30,7 @@ import traceback
 import traceback
 import xmlrpclib
 import traceback
+import time
 import datetime
 from select import select
 import xml.dom.minidom
@@ -626,7 +627,13 @@ def parse_doms_info(info):
 
     def get_status(n, t, d):
         return DOM_STATES[t(sxp.child_value(info, n, d))]
-    
+
+    start_time = get_info('start_time', float, -1)
+    if start_time == -1:
+        up_time = float(-1)
+    else:
+        up_time = time.time() - start_time
+
     return {
         'domid'    : get_info('domid',        str,   ''),
         'name'     : get_info('name',         str,   '??'),
@@ -634,7 +641,7 @@ def parse_doms_info(info):
         'vcpus'    : get_info('vcpus',        int,   0),
         'state'    : get_info('state',        str,    ''),
         'cpu_time' : get_info('cpu_time',     float, 0),
-        'up_time'  : get_info('up_time',      float, -1),
+        'up_time'  : up_time,
         'seclabel' : security.get_security_printlabel(info),
         }
 
@@ -1209,7 +1216,7 @@ def xm_uptime(args):
 
     for dom in doms:
         d = parse_doms_info(dom)
-        if d['domid'] > 0:
+        if int(d['domid']) > 0:
             uptime = int(round(d['up_time']))
         else:
             f=open('/proc/uptime', 'r')
@@ -1236,10 +1243,10 @@ def xm_uptime(args):
         if short_mode:
             now = datetime.datetime.now()
             upstring = now.strftime(" %H:%M:%S") + " up " + upstring
-            upstring += ", " + d['name'] + " (" + str(d['domid']) + ")"
+            upstring += ", " + d['name'] + " (" + d['domid'] + ")"
         else:
             upstring += ':%(seconds)02d' % vars()
-            upstring = ("%(name)-32s %(domid)3d " % d) + upstring
+            upstring = ("%(name)-32s %(domid)3s " % d) + upstring
 
         print upstring
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.