ia64/xen-unstable

changeset 7442:4ba11726df73

Added diagnosis tool for broken domains.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Wed Oct 19 13:59:22 2005 +0100 (2005-10-19)
parents 857b79d27993
children b0f61c2c0746
files tools/python/xen/util/diagnose.py
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/python/xen/util/diagnose.py	Wed Oct 19 13:59:22 2005 +0100
     1.3 @@ -0,0 +1,148 @@
     1.4 +# This library is free software; you can redistribute it and/or
     1.5 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
     1.6 +# License as published by the Free Software Foundation.
     1.7 +#
     1.8 +# This library is distributed in the hope that it will be useful,
     1.9 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.10 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.11 +# Lesser General Public License for more details.
    1.12 +#
    1.13 +# You should have received a copy of the GNU Lesser General Public
    1.14 +# License along with this library; if not, write to the Free Software
    1.15 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.16 +#
    1.17 +# Copyright (c) 2005 XenSource Ltd
    1.18 +
    1.19 +
    1.20 +import re
    1.21 +import sys
    1.22 +
    1.23 +from xen.xend import sxp
    1.24 +
    1.25 +from xen.xend.XendClient import server
    1.26 +from xen.xend.XendError import XendError
    1.27 +from xen.xend.xenstore.xstransact import xstransact
    1.28 +
    1.29 +import xen.xend.XendProtocol
    1.30 +
    1.31 +
    1.32 +domain = None
    1.33 +domid = None
    1.34 +deviceClass = None
    1.35 +device = None
    1.36 +frontendPath = None
    1.37 +backendPath = None
    1.38 +
    1.39 +
    1.40 +def diagnose(dom):
    1.41 +    global domain
    1.42 +    global domid
    1.43 +    global dompath
    1.44 +    
    1.45 +    try:
    1.46 +        domain = server.xend_domain(dom)
    1.47 +        state = sxp.child_value(domain, 'state')
    1.48 +        domid = int(sxp.child_value(domain, 'domid'))
    1.49 +        name = sxp.child_value(domain, 'name')
    1.50 +        dompath = '/local/domain/%d' % domid
    1.51 +
    1.52 +        print "Domain ID is %d." % domid
    1.53 +        print "Domain name is %s." % name
    1.54 +
    1.55 +        if not state:
    1.56 +            raise XendError("Cannot find state")
    1.57 +
    1.58 +        if state.find('c') != -1:
    1.59 +            print "Domain has crashed."
    1.60 +
    1.61 +        diagnose_console()
    1.62 +
    1.63 +        diagnose_devices()
    1.64 +    except xen.xend.XendProtocol.XendError, exn:
    1.65 +        print exn
    1.66 +
    1.67 +
    1.68 +def diagnose_console():
    1.69 +    port    = xstransact.Read(dompath + '/console/port')
    1.70 +    ringref = xstransact.Read(dompath + '/console/ring-ref')
    1.71 +    tty     = xstransact.Read(dompath + '/console/tty')
    1.72 +
    1.73 +    if not port:
    1.74 +        print "Console port is missing; Xend has failed."
    1.75 +    if not ringref:
    1.76 +        print "Console ring-ref is missing; Xend has failed."
    1.77 +    if not tty:
    1.78 +        print "Console tty is missing; Xenconsoled has failed."
    1.79 +
    1.80 +
    1.81 +def diagnose_devices():
    1.82 +    global deviceClass
    1.83 +    global device
    1.84 +    global frontendPath
    1.85 +    global backendPath
    1.86 +    
    1.87 +    device_path = dompath + '/device'
    1.88 +
    1.89 +    device_classes = xstransact.List(device_path)
    1.90 +
    1.91 +    print "Found %d device classes in use." % len(device_classes)
    1.92 +
    1.93 +    for dc in device_classes:
    1.94 +        deviceClass = dc
    1.95 +        device_class_path = device_path + '/' + deviceClass
    1.96 +
    1.97 +        devices = xstransact.List(device_class_path)
    1.98 +
    1.99 +        print "Found %d %s devices." % (len(devices), deviceClass)
   1.100 +
   1.101 +        for d in devices:
   1.102 +            device = d
   1.103 +            
   1.104 +            print "Found device %s, %s." % (deviceClass, device)
   1.105 +
   1.106 +            frontendPath = device_class_path + '/' + device
   1.107 +            backendPath = xstransact.Read(frontendPath, 'backend')
   1.108 +
   1.109 +            if not backendPath:
   1.110 +                print ("Cannot find backend path for device %s, %s." %
   1.111 +                       (deviceClass, device))
   1.112 +            else:
   1.113 +                backend_error = xstransact.Read(backendPath, 'error')
   1.114 +
   1.115 +                if backend_error:
   1.116 +                    diagnose_device_error(backend_error)
   1.117 +
   1.118 +
   1.119 +def diagnose_device_error(err):
   1.120 +    if re.search("2 reading .*/ring-ref and event-channel", err):
   1.121 +        print ("Backend is stuck waiting for frontend for device %s, %s." %
   1.122 +               (deviceClass, device))
   1.123 +        diagnose_stuck_frontend()
   1.124 +    else:
   1.125 +        print ("Device %s, %s shows error %s." %
   1.126 +               (deviceClass, device, err))
   1.127 +
   1.128 +
   1.129 +def diagnose_stuck_frontend():
   1.130 +    if deviceClass == "vbd":
   1.131 +        phy = xstransact.Read(backendPath, 'physical-device')
   1.132 +
   1.133 +        if phy:
   1.134 +            print ("Device %s, %s hotplugging has completed successfully." %
   1.135 +                   (deviceClass, device))
   1.136 +        else:
   1.137 +            print ("Device %s, %s hotplugging failed." %
   1.138 +                   (deviceClass, device))
   1.139 +
   1.140 +
   1.141 +def main(argv = None):
   1.142 +    if argv is None:
   1.143 +        argv = sys.argv
   1.144 +
   1.145 +    diagnose(argv[1])
   1.146 +
   1.147 +    return 0
   1.148 +
   1.149 +
   1.150 +if __name__ == "__main__":
   1.151 +    sys.exit(main())