diff options
-rw-r--r-- | debian/copyright.in | 5 | ||||
-rw-r--r-- | xenserver/README | 16 | ||||
-rw-r--r-- | xenserver/automake.mk | 3 | ||||
-rw-r--r-- | xenserver/etc_xensource_bugtool_network-status_openvswitch.xml | 21 | ||||
-rw-r--r-- | xenserver/openvswitch-xen.spec | 19 | ||||
-rwxr-xr-x | xenserver/usr_sbin_xen-bugtool | 1670 | ||||
-rwxr-xr-x | xenserver/usr_share_openvswitch_scripts_xen-bugtool-tc-class-show | 25 |
7 files changed, 70 insertions, 1689 deletions
diff --git a/debian/copyright.in b/debian/copyright.in index f131ea92d..87cd72b2e 100644 --- a/debian/copyright.in +++ b/debian/copyright.in @@ -25,7 +25,6 @@ License: xenserver/opt_xensource_libexec_InterfaceReconfigureVswitch.py xenserver/opt_xensource_libexec_interface-reconfigure xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py - xenserver/usr_sbin_xen-bugtool * These components are only distributed in the source package. They do not appear in any binary packages. @@ -54,10 +53,6 @@ License: GNU Lesser General Public Licence version 2.1. debian/ovs-bugtool - xenserver/usr_sbin_xen-bugtool [*] - - * This component is only distributed in the source package. - It does not appear in any binary packages. On Debian systems, the complete text of the GNU Lesser General Public Licence version 2.1 can be found in diff --git a/xenserver/README b/xenserver/README index 5023de25b..3e63374c7 100644 --- a/xenserver/README +++ b/xenserver/README @@ -34,6 +34,12 @@ files are: in the ovs-vswitchd configuration that are managed in the xapi database when integrated with Citrix management tools. + etc_xensource_bugtool_network-status_openvswitch.xml + + xen-bugtool extension to collect networking information relevant to + Open vSwitch. Runs + usr_share_openvswitch_scripts_xen-bugtool-tc-class-show. + etc_xensource_scripts_vif Open vSwitch-aware replacement for Citrix script of the same name. @@ -57,16 +63,18 @@ files are: Template for Open vSwitch's /etc/sysconfig/openvswitch configuration file. + usr_share_openvswitch_scripts_xen-bugtool-tc-class-show + + Script to dump tc class configuration for all network + interfaces. Intended to be run by xen-bugtool via + etc_xensource_bugtool_network-status_openvswitch.xml. + usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py xsconsole plugin to configure the pool-wide configuration keys used to control Open vSwitch when integrated with Citrix management tools. - usr_sbin_xen-bugtool - - Open vSwitch-aware replacement for Citrix script of the same name. - uuid.py This is uuid.py from Python 2.5. It is installed into the diff --git a/xenserver/automake.mk b/xenserver/automake.mk index 6c0268d8c..0a44797d7 100644 --- a/xenserver/automake.mk +++ b/xenserver/automake.mk @@ -15,6 +15,7 @@ EXTRA_DIST += \ xenserver/etc_logrotate.d_openvswitch \ xenserver/etc_profile.d_openvswitch.sh \ xenserver/etc_xapi.d_plugins_openvswitch-cfg-update \ + xenserver/etc_xensource_bugtool_network-status_openvswitch.xml \ xenserver/etc_xensource_scripts_vif \ xenserver/openvswitch-xen.spec \ xenserver/opt_xensource_libexec_InterfaceReconfigure.py \ @@ -22,7 +23,7 @@ EXTRA_DIST += \ xenserver/opt_xensource_libexec_InterfaceReconfigureVswitch.py \ xenserver/opt_xensource_libexec_interface-reconfigure \ xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py \ - xenserver/usr_sbin_xen-bugtool \ xenserver/usr_share_openvswitch_scripts_ovs-xapi-sync \ xenserver/usr_share_openvswitch_scripts_sysconfig.template \ + xenserver/usr_share_openvswitch_scripts_xen-bugtool-tc-class-show \ xenserver/uuid.py diff --git a/xenserver/etc_xensource_bugtool_network-status_openvswitch.xml b/xenserver/etc_xensource_bugtool_network-status_openvswitch.xml new file mode 100644 index 000000000..c926d9ef1 --- /dev/null +++ b/xenserver/etc_xensource_bugtool_network-status_openvswitch.xml @@ -0,0 +1,21 @@ +<!-- + This library is free software; you can redistribute it and/or modify + it under the terms of version 2.1 of the GNU Lesser General Public + License as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. + + Copyright (C) 2011 Nicira Networks. +--> + +<collect> + <command label="tc-class-show">/usr/share/openvswitch/scripts/xen-bugtool-tc-class-show</command> +</collect> diff --git a/xenserver/openvswitch-xen.spec b/xenserver/openvswitch-xen.spec index 1b97a53d2..25e8a96c2 100644 --- a/xenserver/openvswitch-xen.spec +++ b/xenserver/openvswitch-xen.spec @@ -60,6 +60,9 @@ install -m 755 xenserver/etc_profile.d_openvswitch.sh \ install -d -m 755 $RPM_BUILD_ROOT/etc/xapi.d/plugins install -m 755 xenserver/etc_xapi.d_plugins_openvswitch-cfg-update \ $RPM_BUILD_ROOT/etc/xapi.d/plugins/openvswitch-cfg-update +install -d -m 755 $RPM_BUILD_ROOT/etc/xensource/bugtool/network-status +install -m 644 xenserver/etc_xensource_bugtool_network-status_openvswitch.xml \ + $RPM_BUILD_ROOT/etc/xensource/bugtool/network-status/openvswitch.xml install -d -m 755 $RPM_BUILD_ROOT/usr/share/openvswitch/scripts install -m 644 vswitchd/vswitch.ovsschema \ $RPM_BUILD_ROOT/usr/share/openvswitch/vswitch.ovsschema @@ -75,10 +78,10 @@ install -m 755 xenserver/etc_xensource_scripts_vif \ $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/vif install -m 755 xenserver/usr_share_openvswitch_scripts_ovs-xapi-sync \ $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/ovs-xapi-sync -install -m 755 xenserver/usr_sbin_xen-bugtool \ - $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/xen-bugtool install -m 755 xenserver/usr_share_openvswitch_scripts_sysconfig.template \ $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/sysconfig.template +install -m 755 xenserver/usr_share_openvswitch_scripts_xen-bugtool-tc-class-show \ + $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/xen-bugtool-tc-class-show install -m 755 utilities/ovs-save \ $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/ovs-save install -d -m 755 $RPM_BUILD_ROOT/usr/lib/xsconsole/plugins-base @@ -186,8 +189,7 @@ for f in \ /opt/xensource/libexec/InterfaceReconfigure.py \ /opt/xensource/libexec/InterfaceReconfigureBridge.py \ /opt/xensource/libexec/InterfaceReconfigureVswitch.py \ - /etc/xensource/scripts/vif \ - /usr/sbin/xen-bugtool + /etc/xensource/scripts/vif do s=$(basename "$f") t=$(readlink "$f") @@ -248,15 +250,13 @@ rm -f /usr/share/openvswitch/scripts/InterfaceReconfigure.pyc \ /usr/share/openvswitch/scripts/InterfaceReconfigureVSwitch.pyc \ /usr/share/openvswitch/scripts/InterfaceReconfigureVSwitch.pyo -# Restore original XenServer scripts. It's important to do this even on upgrade -# since the version to be installed may be missing some of these scripts. +# Restore original XenServer scripts for f in \ /opt/xensource/libexec/interface-reconfigure \ /opt/xensource/libexec/InterfaceReconfigure.py \ /opt/xensource/libexec/InterfaceReconfigureBridge.py \ /opt/xensource/libexec/InterfaceReconfigureVswitch.py \ - /etc/xensource/scripts/vif \ - /usr/sbin/xen-bugtool + /etc/xensource/scripts/vif do s=$(basename "$f") if [ ! -f "/usr/lib/openvswitch/xs-original/$s" ]; then @@ -290,6 +290,7 @@ fi /etc/init.d/openvswitch /etc/init.d/openvswitch-xapi-update /etc/xapi.d/plugins/openvswitch-cfg-update +/etc/xensource/bugtool/network-status/openvswitch.xml /etc/logrotate.d/openvswitch /etc/profile.d/openvswitch.sh /lib/modules/%{xen_version}/kernel/extra/openvswitch/openvswitch_mod.ko @@ -321,8 +322,8 @@ fi /usr/share/openvswitch/scripts/InterfaceReconfigureBridge.py /usr/share/openvswitch/scripts/InterfaceReconfigureVswitch.py /usr/share/openvswitch/scripts/vif -/usr/share/openvswitch/scripts/xen-bugtool /usr/share/openvswitch/scripts/sysconfig.template +/usr/share/openvswitch/scripts/xen-bugtool-tc-class-show /usr/share/openvswitch/scripts/ovs-save /usr/share/openvswitch/vswitch.ovsschema /usr/sbin/ovs-vswitchd diff --git a/xenserver/usr_sbin_xen-bugtool b/xenserver/usr_sbin_xen-bugtool deleted file mode 100755 index 1a4fe6f51..000000000 --- a/xenserver/usr_sbin_xen-bugtool +++ /dev/null @@ -1,1670 +0,0 @@ -#!/usr/bin/env python - -# This library is free software; you can redistribute it and/or -# modify it under the terms of version 2.1 of the GNU Lesser General Public -# License as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# Copyright (c) 2005, 2007 XenSource Ltd. - - -# -# To add new entries to the bugtool, you need to: -# -# Create a new capability. These declare the new entry to the GUI, including -# the expected size, time to collect, privacy implications, and whether the -# capability should be selected by default. One capability may refer to -# multiple files, assuming that they can be reasonably grouped together, and -# have the same privacy implications. You need: -# -# A new CAP_ constant. -# A cap() invocation to declare the capability. -# -# You then need to add calls to main() to collect the files. These will -# typically be calls to the helpers file_output(), tree_output(), cmd_output(), -# or func_output(). -# - -import getopt -import re -import os -import StringIO -import sys -import tarfile -import time -import commands -import pprint -from xml.dom.minidom import parse, getDOMImplementation -import zipfile -from subprocess import Popen, PIPE -from select import select -from signal import SIGTERM, SIGUSR1 -import md5 -import platform -import fcntl -import glob -import urllib -import socket -import base64 - -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') - -import xen.lowlevel.xc -import XenAPI - -OS_RELEASE = platform.release() - -# -# Files & directories -# - -BUG_DIR = "/var/opt/xen/bug-report" -PLUGIN_DIR = "/etc/xensource/bugtool" -XAPI_BLOBS = '/var/xapi/blobs' -EXTLINUX_CONFIG = '/boot/extlinux.conf' -GRUB_CONFIG = '/boot/grub/menu.lst' -BOOT_KERNEL = '/boot/vmlinuz-' + OS_RELEASE -BOOT_INITRD = '/boot/initrd-' + OS_RELEASE + '.img' -PROC_PARTITIONS = '/proc/partitions' -FSTAB = '/etc/fstab' -PROC_MOUNTS = '/proc/mounts' -ISCSI_CONF = '/etc/iscsi/iscsid.conf' -ISCSI_INITIATOR = '/etc/iscsi/initiatorname.iscsi' -LVM_CACHE = '/etc/lvm/cache/.cache' -LVM_CONFIG = '/etc/lvm/lvm.conf' -PROC_CPUINFO = '/proc/cpuinfo' -PROC_MEMINFO = '/proc/meminfo' -PROC_IOPORTS = '/proc/ioports' -PROC_INTERRUPTS = '/proc/interrupts' -PROC_SCSI = '/proc/scsi/scsi' -FIRSTBOOT_DIR = '/etc/firstboot.d' -PROC_VERSION = '/proc/version' -PROC_MODULES = '/proc/modules' -PROC_DEVICES = '/proc/devices' -PROC_FILESYSTEMS = '/proc/filesystems' -PROC_CMDLINE = '/proc/cmdline' -PROC_CONFIG = '/proc/config.gz' -PROC_USB_DEV = '/proc/bus/usb/devices' -PROC_XEN_BALLOON = '/proc/xen/balloon' -PROC_NET_BONDING_DIR = '/proc/net/bonding' -PROC_NET_VLAN_DIR = '/proc/net/vlan' -PROC_NET_SOFTNET_STAT = '/proc/net/softnet_stat' -PROC_DRIVER_CCISS_DIR = '/proc/driver/cciss' -MODPROBE_CONF = '/etc/modprobe.conf' -MODPROBE_DIR = '/etc/modprobe.d' -BOOT_TIME_CPUS = '/etc/xensource/boot_time_cpus' -BOOT_TIME_MEMORY = '/etc/xensource/boot_time_memory' -SYSCONFIG_HWCONF = '/etc/sysconfig/hwconf' -SYSCONFIG_NETWORK = '/etc/sysconfig/network' -SYSCONFIG_NETWORK_SCRIPTS = '/etc/sysconfig/network-scripts' -IFCFG_RE = re.compile(r'^.*/ifcfg-.*') -ROUTE_RE = re.compile(r'^.*/route-.*') -NETWORK_DBCACHE = '/var/xapi/network.dbcache' -RESOLV_CONF = '/etc/resolv.conf' -MPP_CONF = '/etc/mpp.conf' -MULTIPATH_CONF = '/etc/multipath.conf' -NSSWITCH_CONF = '/etc/nsswitch.conf' -NTP_CONF = '/etc/ntp.conf' -IPTABLES_CONFIG = '/etc/sysconfig/iptables-config' -HOSTS = '/etc/hosts' -HOSTS_ALLOW = '/etc/hosts.allow' -HOSTS_DENY = '/etc/hosts.deny' -DHCP_LEASE_DIR = '/var/lib/dhclient' -OPENVSWITCH_CORE_DIR = '/var/xen/openvswitch' -OPENVSWITCH_CONF = '/etc/ovs-vswitchd.conf' -OPENVSWITCH_CONF_DB = '/etc/openvswitch/conf.db' -OPENVSWITCH_VSWITCHD_PID = '/var/run/openvswitch/ovs-vswitchd.pid' -VAR_LOG_DIR = '/var/log/' -VNCTERM_CORE_DIR = '/var/xen/vncterm' -XENSOURCE_INVENTORY = '/etc/xensource-inventory' -OEM_CONFIG_DIR = '/var/xsconfig' -OEM_CONFIG_FILES_RE = re.compile(r'^.*xensource-inventory$') -OEM_DB_FILES_RE = re.compile(r'^.*state\.db') -INITIAL_INVENTORY = '/opt/xensource/etc/initial-inventory' -VENDORKERNEL_INVENTORY = '/etc/vendorkernel-inventory' -STATIC_VDIS = '/etc/xensource/static-vdis' -POOL_CONF = '/etc/xensource/pool.conf' -NETWORK_CONF = '/etc/xensource/network.conf' -PTOKEN = '/etc/xensource/ptoken' -XAPI_CONF = '/etc/xensource/xapi.conf' -XAPI_SSL_CONF = '/etc/xensource/xapi-ssl.conf' -DB_CONF = '/etc/xensource/db.conf' -DB_CONF_RIO = '/etc/xensource/db.conf.rio' -DB_DEFAULT_FIELDS = '/etc/xensource/db-default-fields' -DB_SCHEMA_SQL = '/etc/xensource/db_schema.sql' -XENSTORED_DB = '/var/lib/xenstored/tdb' -HOST_CRASHDUMPS_DIR = '/var/crash' -HOST_CRASHDUMP_LOGS_RE = re.compile(r'^.*\.log$') -X11_LOGS_DIR = VAR_LOG_DIR -X11_LOGS_RE = re.compile(r'.*/Xorg\..*$') -X11_AUTH_DIR = '/root/' -X11_AUTH_RE = re.compile(r'.*/\.((Xauthority)|(serverauth\.[0-9]*))$') -XAPI_DEBUG_DIR = '/var/xapi/debug' -LOG_CONF = '/etc/xensource/log.conf' -INSTALLED_REPOS_DIR = '/etc/xensource/installed-repos' -PATCH_APPLIED_DIR = '/var/patch/applied' -XENSERVER_LOGS = \ - [ VAR_LOG_DIR + x for x in - ['xensource.log', 'audit.log', 'xenstored-access.log', 'SMlog', 'VMPRlog', 'xen/xenstored-trace.log', - 'xen/xen-hotplug.log', 'xen/domain-builder-ng.log', 'squeezed.log', - 'openvswitch/ovs-vswitchd.log', 'openvswitch/ovsdb-server.log' ] + - [ f % n for n in range(1, 20) \ - for f in ['xensource.log.%d', 'xensource.log.%d.gz','SMlog.%d', 'SMlog.%d.gz', 'VMPRlog.%d', 'VMPRlog.%d.gz', - 'audit.log.%d', 'audit.log.%d.gz', 'xenstored-access.log.%d', 'xenstored-access.log.%d.gz', \ - 'xen/xenstored-access.log.%d', 'xen/xenstored-access.log.%d.gz', 'squeezed.log.%d', \ - 'openvswitch/ovs-vswitchd.log.%d', 'openvswitch/ovs-vswitchd.log.%d.gz', \ - 'openvswitch/ovsdb-server.log.%d', 'openvswitch/ovsdb-server.log.%d.gz']]] \ - + glob.glob('/tmp/qemu.[0-9]*') -OEM_XENSERVER_LOGS_RE = re.compile(r'^.*xensource\.log$') -XHA_LOG = '/var/log/xha.log' -XHAD_CONF = '/etc/xensource/xhad.conf' -YUM_LOG = '/var/log/yum.log' -YUM_REPOS_DIR = '/etc/yum.repos.d' -PAM_DIR = '/etc/pam.d' -FIST_RE = re.compile(r'.*/fist_') -LICENSE_LOGS = \ - [ VAR_LOG_DIR + x for x in - ['v6d.log'] + - [ f % n for n in range(1, 20) \ - for f in ['v6d.log.%d', 'v6d.log.%d.gz' ]]] -LWIDENTITY_JOIN_LOG = '/tmp/lwidentity.join.log' -HOSTS_LWIDENTITY_ORIG = '/etc/hosts.lwidentity.orig' -KRB5_CONF = '/etc/krb5.conf' -LIKEWISE_DIR = '/var/lib/likewise' -XENGUEST_LOG = '/tmp/xenguest.log' - -# -# External programs -# - -ARP = '/sbin/arp' -BIOSDEVNAME = '/sbin/biosdevname' -BRCTL = '/usr/sbin/brctl' -CAT = '/bin/cat' -CHKCONFIG = '/sbin/chkconfig' -CSL = '/opt/Citrix/StorageLink/bin/csl' -DF = '/bin/df' -DMESG = '/bin/dmesg' -DMIDECODE = '/usr/sbin/dmidecode' -DMSETUP = '/sbin/dmsetup' -ETHTOOL = '/sbin/ethtool' -FDISK = '/sbin/fdisk' -FIND = '/usr/bin/find' -HA_QUERY_LIVESET = '/opt/xensource/debug/debug_ha_query_liveset' -HDPARM = '/sbin/hdparm' -IFCONFIG = '/sbin/ifconfig' -IPTABLES = '/sbin/iptables' -ISCSIADM = '/sbin/iscsiadm' -LIST_DOMAINS = '/opt/xensource/bin/list_domains' -LOSETUP = '/sbin/losetup' -LS = '/bin/ls' -LSPCI = '/sbin/lspci' -LVS = '/usr/sbin/lvs' -LVDISPLAY = '/usr/sbin/lvdisplay' -MD5SUM = '/usr/bin/md5sum' -MODINFO = '/sbin/modinfo' -MPPUTIL = '/usr/sbin/mppUtil' -MULTIPATHD = '/sbin/multipathd' -NETSTAT = '/bin/netstat' -OVS_DPCTL = '/usr/bin/ovs-dpctl' -OVS_OFCTL = '/usr/bin/ovs-ofctl' -OVS_VSCTL = '/usr/bin/ovs-vsctl' -OVS_APPCTL = '/usr/bin/ovs-appctl' -PS = '/bin/ps' -PVS = '/usr/sbin/pvs' -ROUTE = '/sbin/route' -RPM = '/bin/rpm' -SG_MAP = '/usr/bin/sg_map' -SQLITE = '/usr/bin/sqlite3' -BIN_STATIC_VDIS = '/opt/xensource/bin/static-vdis' -SYSCTL = '/sbin/sysctl' -TC = '/sbin/tc' -UPTIME = '/usr/bin/uptime' -VGS = '/usr/sbin/vgs' -VGSCAN = '/sbin/vgscan' -XAPI_DB_PROCESS = '/opt/xensource/bin/xapi-db-process' -XE = '/opt/xensource/bin/xe' -XS = '/opt/xensource/debug/xs' -XENSTORE_LS = '/usr/bin/xenstore-ls' -ZCAT = '/bin/zcat' - -# -# PII -- Personally identifiable information. Of particular concern are -# things that would identify customers, or their network topology. -# Passwords are never to be included in any bug report, regardless of any PII -# declaration. -# -# NO -- No PII will be in these entries. -# YES -- PII will likely or certainly be in these entries. -# MAYBE -- The user may wish to audit these entries for PII. -# IF_CUSTOMIZED -- If the files are unmodified, then they will contain no PII, -# but since we encourage customers to edit these files, PII may have been -# introduced by the customer. This is used in particular for the networking -# scripts in dom0. -# - -PII_NO = 'no' -PII_YES = 'yes' -PII_MAYBE = 'maybe' -PII_IF_CUSTOMIZED = 'if_customized' -KEY = 0 -PII = 1 -MIN_SIZE = 2 -MAX_SIZE = 3 -MIN_TIME = 4 -MAX_TIME = 5 -MIME = 6 -CHECKED = 7 -HIDDEN = 8 - -MIME_DATA = 'application/data' -MIME_TEXT = 'text/plain' - -INVENTORY_XML_ROOT = "system-status-inventory" -INVENTORY_XML_SUMMARY = 'system-summary' -INVENTORY_XML_ELEMENT = 'inventory-entry' -CAP_XML_ROOT = "system-status-capabilities" -CAP_XML_ELEMENT = 'capability' - - -CAP_BLOBS = 'blobs' -CAP_BOOT_LOADER = 'boot-loader' -CAP_CVSM = 'CVSM' -CAP_DISK_INFO = 'disk-info' -CAP_FIRSTBOOT = 'firstboot' -CAP_HARDWARE_INFO = 'hardware-info' -CAP_HDPARM_T = 'hdparm-t' -CAP_HIGH_AVAILABILITY = 'high-availability' -CAP_HOST_CRASHDUMP_DUMPS = 'host-crashdump-dumps' -CAP_HOST_CRASHDUMP_LOGS = 'host-crashdump-logs' -CAP_KERNEL_INFO = 'kernel-info' -CAP_LOSETUP_A = 'loopback-devices' -CAP_MULTIPATH = 'multipath' -CAP_NETWORK_CONFIG = 'network-config' -CAP_NETWORK_STATUS = 'network-status' -CAP_OEM = 'oem' -CAP_PAM = 'pam' -CAP_PROCESS_LIST = 'process-list' -CAP_PERSISTENT_STATS = 'persistent-stats' -CAP_SYSTEM_LOGS = 'system-logs' -CAP_SYSTEM_SERVICES = 'system-services' -CAP_TAPDISK_LOGS = 'tapdisk-logs' -CAP_VNCTERM = 'vncterm' -CAP_WLB = 'wlb' -CAP_X11_LOGS = 'X11' -CAP_X11_AUTH = 'X11-auth' -CAP_XAPI_DEBUG = 'xapi-debug' -CAP_XAPI_SUBPROCESS = 'xapi-subprocess' -CAP_XENRT = 'xenrt' -CAP_XENSERVER_CONFIG = 'xenserver-config' -CAP_XENSERVER_DOMAINS = 'xenserver-domains' -CAP_XENSERVER_DATABASES = 'xenserver-databases' -CAP_XENSERVER_INSTALL = 'xenserver-install' -CAP_XENSERVER_LOGS = 'xenserver-logs' -CAP_XEN_INFO = 'xen-info' -CAP_XHA_LIVESET = 'xha-liveset' -CAP_YUM = 'yum' - -KB = 1024 -MB = 1024 * 1024 - -caps = {} -cap_sizes = {} -unlimited_data = False -dbg = False - -def cap(key, pii=PII_MAYBE, min_size=-1, max_size=-1, min_time=-1, - max_time=-1, mime=MIME_TEXT, checked=True, hidden=False): - if os.getenv('XEN_RT') and max_time > 0: - max_time *= 5 - caps[key] = (key, pii, min_size, max_size, min_time, max_time, mime, - checked, hidden) - cap_sizes[key] = 0 - - -cap(CAP_BLOBS, PII_NO, max_size=5*MB) -cap(CAP_BOOT_LOADER, PII_NO, max_size=3*KB, - max_time=5) -cap(CAP_CVSM, PII_NO, max_size=3*MB, - max_time=120) -cap(CAP_DISK_INFO, PII_MAYBE, max_size=50*KB, - max_time=20) -cap(CAP_FIRSTBOOT, PII_YES, min_size=60*KB, max_size=80*KB) -cap(CAP_HARDWARE_INFO, PII_MAYBE, max_size=50*KB, - max_time=20) -cap(CAP_HDPARM_T, PII_NO, min_size=0, max_size=5*KB, - min_time=20, max_time=90, checked=False, hidden=True) -cap(CAP_HIGH_AVAILABILITY, PII_MAYBE, max_size=5*MB) -cap(CAP_HOST_CRASHDUMP_DUMPS,PII_YES, checked = False) -cap(CAP_HOST_CRASHDUMP_LOGS, PII_NO) -cap(CAP_KERNEL_INFO, PII_MAYBE, max_size=120*KB, - max_time=5) -cap(CAP_LOSETUP_A, PII_MAYBE, max_size=KB, max_time=5) -cap(CAP_MULTIPATH, PII_MAYBE, max_size=20*KB, - max_time=10) -cap(CAP_NETWORK_CONFIG, PII_IF_CUSTOMIZED, - min_size=0, max_size=40*KB) -cap(CAP_NETWORK_STATUS, PII_YES, max_size=19*KB, - max_time=30) -cap(CAP_PAM, PII_NO, max_size=50*KB) -cap(CAP_PERSISTENT_STATS, PII_MAYBE, max_size=50*MB, - max_time=60) -cap(CAP_PROCESS_LIST, PII_YES, max_size=30*KB, - max_time=20) -cap(CAP_SYSTEM_LOGS, PII_MAYBE, max_size=50*MB, - max_time=5) -cap(CAP_SYSTEM_SERVICES, PII_NO, max_size=5*KB, - max_time=20) -cap(CAP_TAPDISK_LOGS, PII_NO, max_size=64*KB) -cap(CAP_VNCTERM, PII_MAYBE, checked = False) -cap(CAP_WLB, PII_NO, max_size=3*MB, - max_time=20) -cap(CAP_X11_LOGS, PII_NO, max_size=100*KB) -cap(CAP_X11_AUTH, PII_NO, max_size=100*KB) -cap(CAP_XAPI_DEBUG, PII_MAYBE, max_size=10*MB) -cap(CAP_XAPI_SUBPROCESS, PII_NO, max_size=5*KB, - max_time=10) -cap(CAP_XENRT, PII_NO, min_size=0, max_size=500*MB, - checked=False, hidden=True) -cap(CAP_XENSERVER_CONFIG, PII_MAYBE, max_size=80*KB, - max_time=5) -cap(CAP_XENSERVER_DOMAINS, PII_NO, max_size=1*KB, - max_time=5) -cap(CAP_XENSERVER_DATABASES, PII_YES, min_size=500*KB,max_size=2*MB, - max_time=40) -cap(CAP_XENSERVER_INSTALL, PII_MAYBE, min_size=10*KB, max_size=300*KB) -cap(CAP_XENSERVER_LOGS, PII_MAYBE, min_size=0, max_size=70*MB) -cap(CAP_XEN_INFO, PII_MAYBE, max_size=20*KB, - max_time=10) -cap(CAP_XHA_LIVESET, PII_MAYBE, max_size=10*KB, - max_time=10) -cap(CAP_YUM, PII_IF_CUSTOMIZED, max_size=10*KB, - max_time=30) - -ANSWER_YES_TO_ALL = False -SILENT_MODE = False -entries = None -data = {} -dev_null = open('/dev/null', 'r+') - -def output(x): - global SILENT_MODE - if not SILENT_MODE: - print x - -def output_ts(x): - output("[%s] %s" % (time.strftime("%x %X %Z"), x)) - -def cmd_output(cap, args, label = None, filter = None): - if cap in entries: - if not label: - if isinstance(args, list): - a = [aa for aa in args] - a[0] = os.path.basename(a[0]) - label = ' '.join(a) - else: - label = args - data[label] = {'cap': cap, 'cmd_args': args, 'filter': filter} - -def file_output(cap, path_list): - if cap in entries: - for p in path_list: - if os.path.exists(p): - if unlimited_data or caps[cap][MAX_SIZE] == -1 or \ - cap_sizes[cap] < caps[cap][MAX_SIZE]: - data[p] = {'cap': cap, 'filename': p} - try: - s = os.stat(p) - cap_sizes[cap] += s.st_size - except: - pass - else: - output("Omitting %s, size constraint of %s exceeded" % (p, cap)) - -def tree_output(cap, path, pattern = None, negate = False): - if cap in entries: - if os.path.exists(path): - for f in os.listdir(path): - fn = os.path.join(path, f) - if os.path.isfile(fn) and matches(fn, pattern, negate): - file_output(cap, [fn]) - elif os.path.isdir(fn): - tree_output(cap, fn, pattern, negate) - -def func_output(cap, label, func): - if cap in entries: - t = str(func).split() - data[label] = {'cap': cap, 'func': func} - -def collect_data(): - process_lists = {} - - for (k, v) in data.items(): - cap = v['cap'] - if v.has_key('cmd_args'): - v['output'] = StringIOmtime() - if not process_lists.has_key(cap): - process_lists[cap] = [] - process_lists[cap].append(ProcOutput(v['cmd_args'], caps[cap][MAX_TIME], v['output'], v['filter'])) - elif v.has_key('filename') and v['filename'].startswith('/proc/'): - # proc files must be read into memory - try: - f = open(v['filename'], 'r') - s = f.read() - f.close() - if unlimited_data or caps[cap][MAX_SIZE] == -1 or \ - cap_sizes[cap] < caps[cap][MAX_SIZE]: - v['output'] = StringIOmtime(s) - cap_sizes[cap] += len(s) - else: - output("Omitting %s, size constraint of %s exceeded" % (v['filename'], cap)) - except: - pass - elif v.has_key('func'): - try: - s = v['func'](cap) - except Exception, e: - s = str(e) - if unlimited_data or caps[cap][MAX_SIZE] == -1 or \ - cap_sizes[cap] < caps[cap][MAX_SIZE]: - v['output'] = StringIOmtime(s) - cap_sizes[cap] += len(s) - else: - output("Omitting %s, size constraint of %s exceeded" % (k, cap)) - - run_procs(process_lists.values()) - - -def main(argv = None): - global ANSWER_YES_TO_ALL, SILENT_MODE - global entries, data, dbg - - # we need access to privileged files, exit if we are not running as root - if os.getuid() != 0: - print >>sys.stderr, "Error: xen-bugtool must be run as root" - return 1 - - output_type = 'tar.bz2' - output_fd = -1 - - if argv is None: - argv = sys.argv - - try: - (options, params) = getopt.gnu_getopt( - argv, 'sy', ['capabilities', 'silent', 'yestoall', 'entries=', - 'output=', 'outfd=', 'all', 'unlimited', 'debug']) - except getopt.GetoptError, opterr: - print >>sys.stderr, opterr - return 2 - - try: - load_plugins(True) - except: - pass - - inventory = readKeyValueFile(XENSOURCE_INVENTORY) - if inventory.has_key('OEM_BUILD_NUMBER'): - cap(CAP_OEM, PII_MAYBE, max_size=5*MB, - max_time=90) - - if os.getenv('XEN_RT'): - entries = [CAP_BLOBS, CAP_BOOT_LOADER, CAP_CVSM, CAP_DISK_INFO, CAP_FIRSTBOOT, CAP_HARDWARE_INFO, - CAP_HOST_CRASHDUMP_DUMPS, CAP_HOST_CRASHDUMP_LOGS, CAP_KERNEL_INFO, CAP_LOSETUP_A, - CAP_NETWORK_CONFIG, CAP_NETWORK_STATUS, CAP_PROCESS_LIST, CAP_HIGH_AVAILABILITY, - CAP_PAM, CAP_PERSISTENT_STATS, CAP_MULTIPATH, - CAP_SYSTEM_LOGS, CAP_SYSTEM_SERVICES, CAP_TAPDISK_LOGS, - CAP_VNCTERM, CAP_WLB, CAP_X11_LOGS, CAP_X11_AUTH, CAP_XAPI_DEBUG, CAP_XAPI_SUBPROCESS, - CAP_XENRT, CAP_XENSERVER_CONFIG, CAP_XENSERVER_DOMAINS, CAP_XENSERVER_DATABASES, - CAP_XENSERVER_INSTALL, CAP_XENSERVER_LOGS, CAP_XEN_INFO, CAP_XHA_LIVESET, CAP_YUM] - else: - entries = [e for e in caps.keys() if caps[e][CHECKED]] - - for (k, v) in options: - if k == '--capabilities': - update_capabilities() - print_capabilities() - return 0 - - if k == '--output': - if v in ['tar', 'tar.bz2', 'zip']: - output_type = v - else: - print >>sys.stderr, "Invalid output format '%s'" % v - return 2 - - # "-s" or "--silent" means suppress output (except for the final - # output filename at the end) - if k in ['-s', '--silent']: - SILENT_MODE = True - - if k == '--entries' and v != '': - entries = v.split(',') - - # If the user runs the script with "-y" or "--yestoall" we don't ask - # all the really annoying questions. - if k in ['-y', '--yestoall']: - ANSWER_YES_TO_ALL = True - - if k == '--outfd': - output_fd = int(v) - try: - old = fcntl.fcntl(output_fd, fcntl.F_GETFD) - fcntl.fcntl(output_fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC) - except: - print >>sys.stderr, "Invalid output file descriptor", output_fd - return 2 - - elif k == '--all': - entries = caps.keys() - elif k == '--unlimited': - unlimited_data = True - elif k == '--debug': - dbg = True - ProcOutput.debug = True - - if len(params) != 1: - print >>sys.stderr, "Invalid additional arguments", str(params) - return 2 - - if output_fd != -1 and output_type != 'tar': - print >>sys.stderr, "Option '--outfd' only valid with '--output=tar'" - return 2 - - if ANSWER_YES_TO_ALL: - output("Warning: '--yestoall' argument provided, will not prompt for individual files.") - - output(''' -This application will collate the Xen dmesg output, details of the -hardware configuration of your machine, information about the build of -Xen that you are using, plus, if you allow it, various logs. - -The collated information will be saved as a .%s for archiving or -sending to a Technical Support Representative. - -The logs may contain private information, and if you are at all -worried about that, you should exit now, or you should explicitly -exclude those logs from the archive. - -''' % output_type) - - # assemble potential data - tree_output(CAP_BLOBS, XAPI_BLOBS) - - file_output(CAP_BOOT_LOADER, [GRUB_CONFIG, EXTLINUX_CONFIG]) - cmd_output(CAP_BOOT_LOADER, [LS, '-lR', '/boot']) - cmd_output(CAP_BOOT_LOADER, [MD5SUM, BOOT_KERNEL, BOOT_INITRD], label='vmlinuz-initrd.md5sum') - - func_output(CAP_CVSM, 'csl_logs', csl_logs) - - cmd_output(CAP_DISK_INFO, [FDISK, '-l']) - file_output(CAP_DISK_INFO, [PROC_PARTITIONS, PROC_MOUNTS]) - file_output(CAP_DISK_INFO, [FSTAB, ISCSI_CONF, ISCSI_INITIATOR]) - cmd_output(CAP_DISK_INFO, [DF, '-alT']) - cmd_output(CAP_DISK_INFO, [DF, '-alTi']) - for d in disk_list(): - cmd_output(CAP_DISK_INFO, [HDPARM, '-I', '/dev/%s' % d]) - if len(pidof('iscsid')) != 0: - cmd_output(CAP_DISK_INFO, [ISCSIADM, '-m', 'node']) - cmd_output(CAP_DISK_INFO, [VGSCAN]) - cmd_output(CAP_DISK_INFO, [PVS]) - cmd_output(CAP_DISK_INFO, [VGS]) - cmd_output(CAP_DISK_INFO, [LVS]) - file_output(CAP_DISK_INFO, [LVM_CACHE, LVM_CONFIG]) - cmd_output(CAP_DISK_INFO, [LS, '-R', '/sys/class/scsi_host']) - cmd_output(CAP_DISK_INFO, [LS, '-R', '/sys/class/scsi_disk']) - cmd_output(CAP_DISK_INFO, [LS, '-R', '/sys/class/fc_transport']) - cmd_output(CAP_DISK_INFO, [SG_MAP, '-x']) - func_output(CAP_DISK_INFO, 'scsi-hosts', dump_scsi_hosts) - tree_output(CAP_DISK_INFO, PROC_DRIVER_CCISS_DIR) - cmd_output(CAP_DISK_INFO, [LVDISPLAY, '--map']) - - tree_output(CAP_FIRSTBOOT, FIRSTBOOT_DIR) - - file_output(CAP_HARDWARE_INFO, [PROC_CPUINFO, PROC_MEMINFO, PROC_IOPORTS, PROC_INTERRUPTS]) - cmd_output(CAP_HARDWARE_INFO, [DMIDECODE]) - cmd_output(CAP_HARDWARE_INFO, [LSPCI, '-n']) - cmd_output(CAP_HARDWARE_INFO, [LSPCI, '-vv']) - file_output(CAP_HARDWARE_INFO, [PROC_USB_DEV, PROC_SCSI]) - file_output(CAP_HARDWARE_INFO, [BOOT_TIME_CPUS, BOOT_TIME_MEMORY]) - file_output(CAP_HARDWARE_INFO, [SYSCONFIG_HWCONF]) - cmd_output(CAP_HARDWARE_INFO, [LS, '-lR', '/dev']) - # FIXME IDE? - - for d in disk_list(): - cmd_output(CAP_HDPARM_T, [HDPARM, '-tT', '/dev/%s' % d]) - - file_output(CAP_HIGH_AVAILABILITY, [XHAD_CONF, XHA_LOG]) - - tree_output(CAP_HOST_CRASHDUMP_DUMPS, HOST_CRASHDUMPS_DIR, - HOST_CRASHDUMP_LOGS_RE, True) - tree_output(CAP_HOST_CRASHDUMP_LOGS, HOST_CRASHDUMPS_DIR, - HOST_CRASHDUMP_LOGS_RE, False) - - file_output(CAP_KERNEL_INFO, [PROC_VERSION, PROC_MODULES, PROC_DEVICES, - PROC_FILESYSTEMS, PROC_CMDLINE]) - cmd_output(CAP_KERNEL_INFO, [ZCAT, PROC_CONFIG], label='config') - cmd_output(CAP_KERNEL_INFO, [SYSCTL, '-A']) - file_output(CAP_KERNEL_INFO, [MODPROBE_CONF]) - tree_output(CAP_KERNEL_INFO, MODPROBE_DIR) - func_output(CAP_KERNEL_INFO, 'modinfo', module_info) - - cmd_output(CAP_LOSETUP_A, [LOSETUP, '-a']) - - file_output(CAP_MULTIPATH, [MULTIPATH_CONF, MPP_CONF]) - cmd_output(CAP_MULTIPATH, [DMSETUP, 'table']) - func_output(CAP_MULTIPATH, 'multipathd_topology', multipathd_topology) - cmd_output(CAP_MULTIPATH, [MPPUTIL, '-a']) - if CAP_MULTIPATH in entries: - dump_rdac_groups(CAP_MULTIPATH) - - file_output(CAP_NETWORK_CONFIG, [NETWORK_CONF]) - file_output(CAP_NETWORK_CONFIG, [NETWORK_DBCACHE]) - tree_output(CAP_NETWORK_CONFIG, SYSCONFIG_NETWORK_SCRIPTS, IFCFG_RE) - tree_output(CAP_NETWORK_CONFIG, SYSCONFIG_NETWORK_SCRIPTS, ROUTE_RE) - file_output(CAP_NETWORK_CONFIG, [SYSCONFIG_NETWORK, RESOLV_CONF, NSSWITCH_CONF, HOSTS]) - file_output(CAP_NETWORK_CONFIG, [NTP_CONF, IPTABLES_CONFIG, HOSTS_ALLOW, HOSTS_DENY]) - file_output(CAP_NETWORK_CONFIG, [OPENVSWITCH_CONF, OPENVSWITCH_CONF_DB]) - - cmd_output(CAP_NETWORK_STATUS, [IFCONFIG, '-a']) - cmd_output(CAP_NETWORK_STATUS, [ROUTE, '-n']) - cmd_output(CAP_NETWORK_STATUS, [ARP, '-n']) - cmd_output(CAP_NETWORK_STATUS, [NETSTAT, '-an']) - tree_output(CAP_NETWORK_STATUS, DHCP_LEASE_DIR) - cmd_output(CAP_NETWORK_STATUS, [IPTABLES, '-nL']) - cmd_output(CAP_NETWORK_STATUS, [BRCTL, 'show']) - cmd_output(CAP_NETWORK_STATUS, [BIOSDEVNAME, '-d']) - for p in os.listdir('/sys/class/net/'): - if os.path.isdir('/sys/class/net/%s/bridge' % p): - cmd_output(CAP_NETWORK_STATUS, [BRCTL, 'showmacs', p]) - else: - try: - f = open('/sys/class/net/%s/type' % p, 'r') - t = f.readline() - f.close() - if int(t) == 1: - # ARPHRD_ETHER - cmd_output(CAP_NETWORK_STATUS, [ETHTOOL, p]) - cmd_output(CAP_NETWORK_STATUS, [ETHTOOL, '-S', p]) - cmd_output(CAP_NETWORK_STATUS, [ETHTOOL, '-k', p]) - cmd_output(CAP_NETWORK_STATUS, [ETHTOOL, '-i', p]) - cmd_output(CAP_NETWORK_STATUS, [ETHTOOL, '-c', p]) - cmd_output(CAP_NETWORK_STATUS, - [TC, '-s', '-d', 'class', 'show', 'dev', p]) - except: - pass - tree_output(CAP_NETWORK_STATUS, PROC_NET_BONDING_DIR) - tree_output(CAP_NETWORK_STATUS, PROC_NET_VLAN_DIR) - cmd_output(CAP_NETWORK_STATUS, [TC, '-s', 'qdisc']) - file_output(CAP_NETWORK_STATUS, [PROC_NET_SOFTNET_STAT]) - tree_output(CAP_NETWORK_STATUS, OPENVSWITCH_CORE_DIR) - if os.path.exists(OPENVSWITCH_VSWITCHD_PID): - cmd_output(CAP_NETWORK_STATUS, [OVS_DPCTL, 'show']) - for d in dp_list(): - cmd_output(CAP_NETWORK_STATUS, [OVS_OFCTL, 'show', d]) - cmd_output(CAP_NETWORK_STATUS, [OVS_OFCTL, 'status', d]) - cmd_output(CAP_NETWORK_STATUS, [OVS_OFCTL, 'dump-flows', d]) - cmd_output(CAP_NETWORK_STATUS, [OVS_DPCTL, 'dump-flows', d]) - try: - vspidfile = open(OPENVSWITCH_VSWITCHD_PID) - vspid = int(vspidfile.readline().strip()) - vspidfile.close() - for b in bond_list(vspid): - cmd_output(CAP_NETWORK_STATUS, - [OVS_APPCTL, '-t', '/var/run/ovs-vswitchd.%s.ctl' % vspid, '-e' 'bond/show %s' % b], - 'ovs-appctl-bond-show-%s.out' % b) - except e: - pass - - tree_output(CAP_PAM, PAM_DIR) - file_output(CAP_PAM, [KRB5_CONF]) - tree_output(CAP_PAM, LIKEWISE_DIR) - - func_output(CAP_PERSISTENT_STATS, 'xapi_rrd-host', dump_xapi_rrds) - - cmd_output(CAP_PROCESS_LIST, [PS, 'wwwaxf', '-eo', 'pid,tty,stat,time,nice,psr,pcpu,pmem,nwchan,wchan:25,args'], label='process-tree') - func_output(CAP_PROCESS_LIST, 'fd_usage', fd_usage) - - file_output(CAP_SYSTEM_LOGS, - [ VAR_LOG_DIR + x for x in - [ 'crit.log', 'kern.log', 'daemon.log', 'user.log', 'syslog', 'messages', - 'monitor_memory.log', 'secure', 'debug', 'dmesg', 'boot.msg', 'blktap.log' ] + - [ f % n for n in range(1, 20) \ - for f in ['crit.log.%d', 'crit.log.%d.gz', - 'kern.log.%d', 'kern.log.%d.gz', - 'daemon.log.%d', 'daemon.log.%d.gz', - 'user.log.%d', 'user.log.%d.gz', - 'messages.%d', 'messages.%d.gz', - 'monitor_memory.log.%d', 'monitor_memory.log.%d.gz', - 'secure.%d', 'secure.%d.gz', - 'blktap.log.%d']]]) - if not os.path.exists('/var/log/dmesg') and not os.path.exists('/var/log/boot.msg'): - cmd_output(CAP_SYSTEM_LOGS, [DMESG]) - file_output(CAP_SYSTEM_LOGS, [LWIDENTITY_JOIN_LOG, HOSTS_LWIDENTITY_ORIG]) - - cmd_output(CAP_SYSTEM_SERVICES, [CHKCONFIG, '--list']) - - if CAP_TAPDISK_LOGS in entries: - generate_tapdisk_logs() - - tree_output(CAP_VNCTERM, VNCTERM_CORE_DIR) - - cmd_output(CAP_WLB, [XE, 'pool-retrieve-wlb-configuration']) - cmd_output(CAP_WLB, [XE, 'pool-retrieve-wlb-diagnostics']) - - tree_output(CAP_X11_LOGS, X11_LOGS_DIR, X11_LOGS_RE) - tree_output(CAP_X11_AUTH, X11_AUTH_DIR, X11_AUTH_RE) - - tree_output(CAP_XAPI_DEBUG, XAPI_DEBUG_DIR) - - func_output(CAP_XAPI_SUBPROCESS, 'xapi_subprocesses', dump_xapi_subprocess_info) - - tree_output(CAP_XENRT, '/tmp', FIST_RE) - # CA-45540: capture QEMU core files - tree_output(CAP_XENRT, '/var/xen/qemu') - tree_output(CAP_XENRT, '/tmp', re.compile(r'^.*xen\.qemu-dm\.')) - - file_output(CAP_XENSERVER_CONFIG, [INITIAL_INVENTORY]) - file_output(CAP_XENSERVER_CONFIG, [POOL_CONF, PTOKEN, XAPI_CONF, XAPI_SSL_CONF, - XENSOURCE_INVENTORY, VENDORKERNEL_INVENTORY]) - cmd_output(CAP_XENSERVER_CONFIG, [LS, '-lR', '/opt/xensource']) - cmd_output(CAP_XENSERVER_CONFIG, [BIN_STATIC_VDIS, 'list']) - tree_output(CAP_XENSERVER_CONFIG, OEM_CONFIG_DIR, OEM_CONFIG_FILES_RE) - tree_output(CAP_XENSERVER_CONFIG, STATIC_VDIS) - cmd_output(CAP_XENSERVER_CONFIG, [LS, '-lR', STATIC_VDIS]) - - func_output(CAP_XENSERVER_DATABASES, 'xapi-db.xml', dump_filtered_xapi_db) - cmd_output(CAP_XENSERVER_DATABASES, [XENSTORE_LS, '-f']) - file_output(CAP_XENSERVER_DATABASES, [DB_CONF, DB_CONF_RIO, DB_DEFAULT_FIELDS, DB_SCHEMA_SQL]) - tree_output(CAP_XENSERVER_DATABASES, OEM_CONFIG_DIR, OEM_DB_FILES_RE) - file_output(CAP_XENSERVER_DATABASES, [XENSTORED_DB, XENSTORED_DB + '.bak']) - cmd_output(CAP_XENSERVER_DATABASES, [XE, 'pool-dump-database', 'file-name='], - label="xapi-db-dumped.xml", filter=filter_db_pii) - cmd_output(CAP_XENSERVER_DATABASES, [XS, 'debug', 'watches']) - cmd_output(CAP_XENSERVER_DATABASES, [XS, 'debug', 'quotas']) - - cmd_output(CAP_XENSERVER_DOMAINS, [LIST_DOMAINS]) - - tree_output(CAP_XENSERVER_INSTALL, VAR_LOG_DIR + 'installer') - file_output(CAP_XENSERVER_INSTALL, - [ VAR_LOG_DIR + x for x in - [ 'firstboot-SR-commands-log', - 'upgrade-commands-log', 'generate-iscsi-iqn-log']] + - [ '/root/' + x for x in - [ 'blockdevs-log', 'cmdline-log', 'devcontents-log', - 'dmesg-log', 'install-log', 'lspci-log', 'modules-log', - 'pci-log', 'processes-log', 'tty-log', 'uname-log', - 'vgscan-log']]) - tree_output(CAP_XENSERVER_INSTALL, INSTALLED_REPOS_DIR) - tree_output(CAP_XENSERVER_INSTALL, PATCH_APPLIED_DIR) - - file_output(CAP_XENSERVER_LOGS, [LOG_CONF, XENGUEST_LOG]) - file_output(CAP_XENSERVER_LOGS, XENSERVER_LOGS) - file_output(CAP_XENSERVER_LOGS, LICENSE_LOGS) - tree_output(CAP_XENSERVER_LOGS, OEM_CONFIG_DIR, OEM_XENSERVER_LOGS_RE) - - try: - def xen_dmesg(xc): - data = xc.readconsolering() - xc.send_debug_keys('q') - time.sleep(1) - return data - - xc = xen.lowlevel.xc.xc() - - func_output(CAP_XEN_INFO, 'xen-dmesg', lambda x: xen_dmesg(xc)) - func_output(CAP_XEN_INFO, 'physinfo', lambda x: prettyDict(xc.physinfo())) - func_output(CAP_XEN_INFO, 'xeninfo', lambda x: prettyDict(xc.xeninfo())) - except: - pass - file_output(CAP_XEN_INFO, [PROC_XEN_BALLOON]) - - cmd_output(CAP_XHA_LIVESET, [HA_QUERY_LIVESET]) - - file_output(CAP_YUM, [YUM_LOG]) - tree_output(CAP_YUM, YUM_REPOS_DIR) - cmd_output(CAP_YUM, [RPM, '-qa']) - - try: - load_plugins() - except: - pass - - # permit the user to filter out data - for k in sorted(data.keys()): - if not ANSWER_YES_TO_ALL and not yes("Include '%s'? [Y/n]: " % k): - del data[k] - - # collect selected data now - output_ts('Running commands to collect data') - collect_data() - - subdir = os.getenv('XENRT_BUGTOOL_BASENAME') - if subdir: - subdir = os.path.basename(subdir) - if subdir == '..' or subdir == '.': - subdir = None - if not subdir: - subdir = "bug-report-%s" % time.strftime("%Y%m%d%H%M%S") - - # include inventory - data['inventory.xml'] = {'cap': None, 'output': StringIOmtime(make_inventory(data, subdir))} - - # create archive - if output_fd == -1 and not os.path.exists(BUG_DIR): - try: - os.makedirs(BUG_DIR) - except: - pass - - if output_fd == -1: - output_ts('Creating output file') - - if output_type.startswith('tar'): - make_tar(subdir, output_type, output_fd) - else: - make_zip(subdir) - - clean_tapdisk_logs() - - if dbg: - print >>sys.stderr, "Category sizes (max, actual):\n" - for c in caps.keys(): - print >>sys.stderr, " %s (%d, %d)" % (c, caps[c][MAX_SIZE], - cap_sizes[c]) - return 0 - -def find_tapdisk_logs(): - return glob.glob('/var/log/blktap/*.log*') - -def generate_tapdisk_logs(): - for pid in pidof('tapdisk'): - try: - os.kill(pid, SIGUSR1) - output_ts("Including logs for tapdisk process %d" % pid) - except : - pass - # give processes a second to write their logs - time.sleep(1) - file_output(CAP_TAPDISK_LOGS, find_tapdisk_logs()) - -def clean_tapdisk_logs(): - for filename in find_tapdisk_logs(): - try: - os.remove(filename) - except : - pass - -def dump_xapi_subprocess_info(cap): - """Check which fds are open by xapi and its subprocesses to diagnose faults like CA-10543. - Returns a string containing a pretty-printed pstree-like structure. """ - pids = filter(lambda x: x.isdigit(), os.listdir("/proc")) - def readlines(filename): - lines = '' - try: - f = open(filename, "r") - lines = f.readlines() - f.close() - except: - pass - return lines - def cmdline(pid): - all = readlines("/proc/" + pid + "/cmdline") - if all == []: - return "" - else: - return all[0].replace('\x00', ' ') - def parent(pid): - for i in readlines("/proc/" + pid + "/status"): - if i.startswith("PPid:"): - return i.split()[-1] - return None - def pstree(pid): - result = { "cmdline": cmdline(pid) } - child_pids = filter(lambda x:parent(x) == pid, pids) - children = { } - for child in child_pids: - children[child] = pstree(child) - result['children'] = children - fds = { } - for fd in os.listdir("/proc/" + pid + "/fd"): - try: - fds[fd] = os.readlink("/proc/" + pid + "/fd/" + fd) - except: - pass - result['fds'] = fds - return result - xapis = filter(lambda x: cmdline(x).startswith("/opt/xensource/bin/xapi"), pids) - xapis = filter(lambda x: parent(x) == "1", xapis) - result = {} - for xapi in xapis: - result[xapi] = pstree(xapi) - pp = pprint.PrettyPrinter(indent=4) - return pp.pformat(result) - -def dump_xapi_rrds(cap): - socket.setdefaulttimeout(5) - session = XenAPI.xapi_local() - session.xenapi.login_with_password('', '') - this_host = session.xenapi.session.get_this_host(session._session) - # better way to find pool master? - pool = session.xenapi.pool.get_all_records().values()[0] - i_am_master = (this_host == pool['master']) - - for vm in session.xenapi.VM.get_all_records().values(): - if vm['is_a_template']: - continue - if vm['resident_on'] == this_host or (i_am_master and vm['power_state'] in ['Suspended', 'Halted']): - rrd = urllib.urlopen('http://localhost/vm_rrd?session_id=%s&uuid=%s' % (session._session, vm['uuid'])) - try: - (i, o, x) = select([rrd], [], [], 5.0) - if len(i) == 1: - data['xapi_rrd-%s' % vm['uuid']] = {'cap': cap, - 'output': StringIOmtime(rrd.read())} - finally: - rrd.close() - - output = '' - rrd = urllib.urlopen('http://localhost/host_rrd?session_id=%s' % session._session) - try: - for line in rrd: - output += line - finally: - rrd.close() - - session.xenapi.session.logout() - return output - -'''Filter a Xapi XML database. - - There is one important assumption made in this class: - - the XML document does not contain any characters between the end of one - tag and the beginning of the next, ie every > is immediately followed by - a < -''' -class DBFilter: - def __init__(self): - self.result = '' - self.rest = '' - self.state = {} - - def filter_secrets(self, s): - if 'in_secret_table' not in self.state: - self.state['in_secret_table'] = False - - # this logic doesn't deal with <table name="secret" /> properly!!! - if s.startswith('<table ') and 'name="secret"' in s: - self.state['in_secret_table'] = True - elif s.startswith('</table>'): - self.state['in_secret_table'] = False - - if self.state['in_secret_table'] and s.startswith("<row"): # match only on DB rows - s = re.sub(r'(value=")[^"]+(")', r'\1REMOVED\2', s) - return s - - def feed(self, s): - rem = self.rest + s - p = rem.find('>') - while p != -1: - s = rem[:p+1] - rem = rem[p+1:] - self.result += self.filter_secrets(s) - p = rem.find('>') - self.rest = rem - - def output(self): - r = self.result + self.filter_secrets(self.rest) - self.result, self.rest = '', '' - self.state = {} - return r - -def filter_db_pii(s, state): - dbfilter = DBFilter() - dbfilter.feed(s) - return dbfilter.output() - -def dump_filtered_xapi_db(cap): - db_file = None - format = None - state = {} - - # determine db format - c = open(DB_CONF, 'r') - try: - for line in c: - l = line.rstrip('\n') - if l.startswith('['): - db_file = l[1:-1] - if l.startswith('format:'): - format = l[7:] - break - finally: - c.close() - - pipe = None - ih = None - output = '' - - if format == 'sqlite': - pipe = Popen([XAPI_DB_PROCESS, '-xmltostdout'], bufsize=1, stdin=dev_null, - stdout=PIPE, stderr=dev_null) - ih = pipe.stdout - elif db_file: - ih = open(db_file, 'r') - - if not ih: - return '' - - dbfilter = DBFilter() - rec = ih.read(2048) - while rec != '': - dbfilter.feed(rec) - rec = ih.read(2048) - output = dbfilter.output() - - if pipe: - pipe.wait() - else: - ih.close() - return output - -def dump_scsi_hosts(cap): - output = '' - l = os.listdir('/sys/class/scsi_host') - l.sort() - - for h in l: - procname = '' - try: - f = open('/sys/class/scsi_host/%s/proc_name' % h) - procname = f.readline().strip("\n") - f.close() - except: - pass - modelname = None - try: - f = open('/sys/class/scsi_host/%s/model_name' % h) - modelname = f.readline().strip("\n") - f.close() - except: - pass - - output += "%s:\n" %h - output += " %s%s\n" % (procname, modelname and (" -> %s" % modelname) or '') - - return output - -def module_info(cap): - output = StringIO.StringIO() - modules = open(PROC_MODULES, 'r') - procs = [] - - for line in modules: - module = line.split()[0] - procs.append(ProcOutput([MODINFO, module], caps[cap][MAX_TIME], output)) - modules.close() - - run_procs([procs]) - - return output.getvalue() - -def csl_logs(cap): - socket.setdefaulttimeout(5) - session = XenAPI.xapi_local() - session.xenapi.login_with_password('', '') - this_host = session.xenapi.session.get_this_host(session._session) - # better way to find pool master? - pool = session.xenapi.pool.get_all_records().values()[0] - i_am_master = (this_host == pool['master']) - - output = StringIO.StringIO() - procs = [] - csl_targets_fetched = [] - - for pbd in session.xenapi.PBD.get_all_records().values(): - if pbd.has_key('device_config') and pbd['device_config'].has_key('target'): - if pbd['device_config']['target'] in csl_targets_fetched: - continue - sr = session.xenapi.SR.get_record(pbd['SR']) - if sr.has_key('type') and sr['type'] == 'cslg': - if sr['shared'] and pbd['host'] != this_host and not i_am_master: - continue - - dev_cfg = pbd['device_config'] - server = "server=%s" % socket.gethostbyname(dev_cfg['target']) - if dev_cfg.has_key('port'): - server += ':' + dev_cfg['port'] - if dev_cfg.has_key('username'): - server += ',' + dev_cfg['username'] - if dev_cfg.has_key('password_secret'): - sec_ref = session.xenapi.secret.get_by_uuid(dev_cfg['password_secret']) - server += ',' + session.xenapi.secret.get_value(sec_ref) - procs.append(ProcOutput([CSL, server, 'srv-log-get'], caps[cap][MAX_TIME], output)) - csl_targets_fetched.append(dev_cfg['target']) - - session.xenapi.session.logout() - - run_procs([procs]) - - return output.getvalue() - -def multipathd_topology(cap): - pipe = Popen([MULTIPATHD, '-k'], bufsize=1, stdin=PIPE, - stdout=PIPE, stderr=dev_null) - stdout, stderr = pipe.communicate('show topology') - - return stdout - -def dp_list(): - output = StringIO.StringIO() - procs = [ProcOutput([OVS_DPCTL, 'dump-dps'], caps[CAP_NETWORK_STATUS][MAX_TIME], output)] - - run_procs([procs]) - - if not procs[0].timed_out: - return output.getvalue().splitlines() - return [] - -def bond_list(pid): - output = StringIO.StringIO() - procs = [ProcOutput([OVS_APPCTL, '-t', '/var/run/ovs-vswitchd.%s.ctl' % pid, '-e' 'bond/list'], caps[CAP_NETWORK_STATUS][MAX_TIME], output)] - - run_procs([procs]) - - if not procs[0].timed_out: - bonds = output.getvalue().splitlines()[1:] - return [x.split('\t')[1] for x in bonds] - return [] - -def fd_usage(cap): - output = '' - fd_dict = {} - for d in [p for p in os.listdir('/proc') if p.isdigit()]: - try: - fh = open('/proc/'+d+'/cmdline') - name = fh.readline() - num_fds = len(os.listdir(os.path.join('/proc/'+d+'/fd'))) - if num_fds > 0: - if not num_fds in fd_dict: - fd_dict[num_fds] = [] - fd_dict[num_fds].append(name.replace('\0', ' ').strip()) - finally: - fh.close() - keys = fd_dict.keys() - keys.sort(lambda a, b: int(b) - int(a)) - for k in keys: - output += "%s: %s\n" % (k, str(fd_dict[k])) - return output - -def dump_rdac_groups(cap): - output = StringIO.StringIO() - procs = [ProcOutput([MPPUTIL, '-a'], caps[cap][MAX_TIME], output)] - - run_procs([procs]) - - if not procs[0].timed_out: - proc_line = 0 - for line in output.getvalue().splitlines(): - if line.startswith('ID'): - proc_line = 2 - elif line.startswith('----'): - proc_line -= 1 - elif proc_line > 0: - group, _ = line.split(None, 1) - cmd_output(cap, [MPPUTIL, '-g', group]) - -def load_plugins(just_capabilities = False): - def getText(nodelist): - rc = "" - for node in nodelist: - if node.nodeType == node.TEXT_NODE: - rc += node.data - return rc.encode() - - def getBoolAttr(el, attr, default = False): - ret = default - val = el.getAttribute(attr).lower() - if val in ['true', 'false', 'yes', 'no']: - ret = val in ['true', 'yes'] - return ret - - for dir in [d for d in os.listdir(PLUGIN_DIR) if os.path.isdir(os.path.join(PLUGIN_DIR, d))]: - if not caps.has_key(dir): - if not os.path.exists("%s/%s.xml" % (PLUGIN_DIR, dir)): - continue - xmldoc = parse("%s/%s.xml" % (PLUGIN_DIR, dir)) - assert xmldoc.documentElement.tagName == "capability" - - pii, min_size, max_size, min_time, max_time, mime = \ - PII_MAYBE, -1,-1,-1,-1, MIME_TEXT - - if xmldoc.documentElement.getAttribute("pii") in [PII_NO, PII_YES, PII_MAYBE, PII_IF_CUSTOMIZED]: - pii = xmldoc.documentElement.getAttribute("pii") - if xmldoc.documentElement.getAttribute("min_size") != '': - min_size = long(xmldoc.documentElement.getAttribute("min_size")) - if xmldoc.documentElement.getAttribute("max_size") != '': - max_size = long(xmldoc.documentElement.getAttribute("max_size")) - if xmldoc.documentElement.getAttribute("min_time") != '': - min_time = int(xmldoc.documentElement.getAttribute("min_time")) - if xmldoc.documentElement.getAttribute("max_time") != '': - max_time = int(xmldoc.documentElement.getAttribute("max_time")) - if xmldoc.documentElement.getAttribute("mime") in [MIME_DATA, MIME_TEXT]: - mime = xmldoc.documentElement.getAttribute("mime") - checked = getBoolAttr(xmldoc.documentElement, 'checked', True) - hidden = getBoolAttr(xmldoc.documentElement, 'hidden', False) - - cap(dir, pii, min_size, max_size, min_time, max_time, mime, checked, hidden) - - if just_capabilities: - continue - - plugdir = os.path.join(PLUGIN_DIR, dir) - for file in [f for f in os.listdir(plugdir) if f.endswith('.xml')]: - xmldoc = parse(os.path.join(plugdir, file)) - assert xmldoc.documentElement.tagName == "collect" - - for el in xmldoc.documentElement.getElementsByTagName("*"): - if el.tagName == "files": - file_output(dir, getText(el.childNodes).split()) - elif el.tagName == "directory": - pattern = el.getAttribute("pattern") - if pattern == '': pattern = None - negate = getBoolAttr(el, 'negate') - tree_output(dir, getText(el.childNodes), pattern and re.compile(pattern) or None, negate) - elif el.tagName == "command": - label = el.getAttribute("label") - if label == '': label = None - cmd_output(dir, getText(el.childNodes), label) - -def make_tar(subdir, suffix, output_fd): - global SILENT_MODE, data - - mode = 'w' - if suffix == 'tar.bz2': - mode = 'w:bz2' - filename = "%s/%s.%s" % (BUG_DIR, subdir, suffix) - - if output_fd == -1: - tf = tarfile.open(filename, mode) - else: - tf = tarfile.open(None, 'w', os.fdopen(output_fd, 'a')) - - try: - for (k, v) in data.items(): - try: - tar_filename = os.path.join(subdir, construct_filename(k, v)) - ti = tarfile.TarInfo(tar_filename) - - ti.uname = 'root' - ti.gname = 'root' - - if v.has_key('output'): - ti.mtime = v['output'].mtime - ti.size = len(v['output'].getvalue()) - v['output'].seek(0) - tf.addfile(ti, v['output']) - elif v.has_key('filename'): - s = os.stat(v['filename']) - ti.mtime = s.st_mtime - ti.size = s.st_size - tf.addfile(ti, file(v['filename'])) - except: - pass - finally: - tf.close() - - if output_fd == -1: - output ('Writing tarball %s successful.' % filename) - if SILENT_MODE: - print filename - - -def make_zip(subdir): - global SILENT_MODE, data - - filename = "%s/%s.zip" % (BUG_DIR, subdir) - zf = zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) - - try: - for (k, v) in data.items(): - try: - dest = os.path.join(subdir, construct_filename(k, v)) - - if v.has_key('output'): - zf.writestr(dest, v['output'].getvalue()) - elif v.has_key('filename'): - if os.stat(v['filename']).st_size < 50: - compress_type = zipfile.ZIP_STORED - else: - compress_type = zipfile.ZIP_DEFLATED - zf.write(v['filename'], dest, compress_type) - except: - pass - finally: - zf.close() - - output ('Writing archive %s successful.' % filename) - if SILENT_MODE: - print filename - - -def make_inventory(inventory, subdir): - document = getDOMImplementation().createDocument( - None, INVENTORY_XML_ROOT, None) - - # create summary entry - s = document.createElement(INVENTORY_XML_SUMMARY) - user = os.getenv('SUDO_USER', os.getenv('USER')) - if user: - s.setAttribute('user', user) - s.setAttribute('date', time.strftime('%c')) - s.setAttribute('hostname', platform.node()) - s.setAttribute('uname', ' '.join(platform.uname())) - s.setAttribute('uptime', commands.getoutput(UPTIME)) - document.getElementsByTagName(INVENTORY_XML_ROOT)[0].appendChild(s) - - map(lambda (k, v): inventory_entry(document, subdir, k, v), - inventory.items()) - return document.toprettyxml() - -def inventory_entry(document, subdir, k, v): - try: - el = document.createElement(INVENTORY_XML_ELEMENT) - el.setAttribute('capability', v['cap']) - el.setAttribute('filename', os.path.join(subdir, construct_filename(k, v))) - el.setAttribute('md5sum', md5sum(v)) - document.getElementsByTagName(INVENTORY_XML_ROOT)[0].appendChild(el) - except: - pass - - -def md5sum(d): - m = md5.new() - if d.has_key('filename'): - f = open(d['filename']) - data = f.read(1024) - while len(data) > 0: - m.update(data) - data = f.read(1024) - f.close() - elif d.has_key('output'): - m.update(d['output'].getvalue()) - return m.hexdigest() - - -def construct_filename(k, v): - if v.has_key('filename'): - if v['filename'][0] == '/': - return v['filename'][1:] - else: - return v['filename'] - s = k.replace(' ', '-') - s = s.replace('--', '-') - s = s.replace('/', '%') - if s.find('.') == -1: - s += '.out' - - return s - - -def update_capabilities(): - update_cap_size(CAP_HOST_CRASHDUMP_LOGS, - size_of_dir(HOST_CRASHDUMPS_DIR, HOST_CRASHDUMP_LOGS_RE)) - update_cap_size(CAP_HOST_CRASHDUMP_DUMPS, - size_of_dir(HOST_CRASHDUMPS_DIR, HOST_CRASHDUMP_LOGS_RE, - True)) - update_cap_size(CAP_XAPI_DEBUG, size_of_dir(XAPI_DEBUG_DIR)) - update_cap_size(CAP_XENSERVER_LOGS, size_of_all(XENSERVER_LOGS)) - - -def update_cap_size(cap, size): - update_cap(cap, MIN_SIZE, size) - update_cap(cap, MAX_SIZE, size) - update_cap(cap, CHECKED, size > 0) - - -def update_cap(cap, k, v): - global caps - l = list(caps[cap]) - l[k] = v - caps[cap] = tuple(l) - - -def size_of_dir(d, pattern = None, negate = False): - if os.path.isdir(d): - return size_of_all([os.path.join(d, fn) for fn in os.listdir(d)], - pattern, negate) - else: - return 0 - - -def size_of_all(files, pattern = None, negate = False): - return sum([size_of(f, pattern, negate) for f in files]) - - -def matches(f, pattern, negate): - if negate: - return not matches(f, pattern, False) - else: - return pattern is None or pattern.match(f) - - -def size_of(f, pattern, negate): - if os.path.isfile(f) and matches(f, pattern, negate): - return os.stat(f)[6] - else: - return size_of_dir(f, pattern, negate) - - -def print_capabilities(): - document = getDOMImplementation().createDocument( - "ns", CAP_XML_ROOT, None) - map(lambda key: capability(document, key), [k for k in caps.keys() if not caps[k][HIDDEN]]) - print document.toprettyxml() - -def capability(document, key): - c = caps[key] - el = document.createElement(CAP_XML_ELEMENT) - el.setAttribute('key', c[KEY]) - el.setAttribute('pii', c[PII]) - el.setAttribute('min-size', str(c[MIN_SIZE])) - el.setAttribute('max-size', str(c[MAX_SIZE])) - el.setAttribute('min-time', str(c[MIN_TIME])) - el.setAttribute('max-time', str(c[MAX_TIME])) - el.setAttribute('content-type', c[MIME]) - el.setAttribute('default-checked', c[CHECKED] and 'yes' or 'no') - document.getElementsByTagName(CAP_XML_ROOT)[0].appendChild(el) - - -def prettyDict(d): - format = '%%-%ds: %%s' % max(map(len, [k for k, _ in d.items()])) - return '\n'.join([format % i for i in d.items()]) + '\n' - - -def yes(prompt): - yn = raw_input(prompt) - - return len(yn) == 0 or yn.lower()[0] == 'y' - - -partition_re = re.compile(r'(.*[0-9]+$)|(^xvd)') - -def disk_list(): - disks = [] - try: - f = open('/proc/partitions') - f.readline() - f.readline() - for line in f.readlines(): - (major, minor, blocks, name) = line.split() - if int(major) < 254 and not partition_re.match(name): - disks.append(name) - f.close() - except: - pass - return disks - - -class ProcOutput: - debug = False - - def __init__(self, command, max_time, inst=None, filter=None): - self.command = command - self.max_time = max_time - self.inst = inst - self.running = False - self.status = None - self.timed_out = False - self.failed = False - self.timeout = int(time.time()) + self.max_time - self.filter = filter - self.filter_state = {} - - def __del__(self): - self.terminate() - - def cmdAsStr(self): - return isinstance(self.command, list) and ' '.join(self.command) or self.command - - def run(self): - self.timed_out = False - try: - if ProcOutput.debug: - output_ts("Starting '%s'" % self.cmdAsStr()) - self.proc = Popen(self.command, bufsize=1, stdin=dev_null, stdout=PIPE, stderr=dev_null, shell=isinstance(self.command, str)) - old = fcntl.fcntl(self.proc.stdout.fileno(), fcntl.F_GETFD) - fcntl.fcntl(self.proc.stdout.fileno(), fcntl.F_SETFD, old | fcntl.FD_CLOEXEC) - self.running = True - self.failed = False - except: - output_ts("'%s' failed" % self.cmdAsStr()) - self.running = False - self.failed = True - - def terminate(self): - if self.running: - try: - os.kill(self.proc.pid, SIGTERM) - except: - pass - self.proc = None - self.running = False - self.status = SIGTERM - - def read_line(self): - assert self.running - line = self.proc.stdout.readline() - if line == '': - # process exited - self.status = self.proc.wait() - self.proc = None - self.running = False - else: - if self.filter: - line = self.filter(line, self.filter_state) - if self.inst: - self.inst.write(line) - -def run_procs(procs): - while True: - pipes = [] - active_procs = [] - - for pp in procs: - for p in pp: - if p.running: - active_procs.append(p) - pipes.append(p.proc.stdout) - break - elif p.status == None and not p.failed and not p.timed_out: - p.run() - if p.running: - active_procs.append(p) - pipes.append(p.proc.stdout) - break - - if len(pipes) == 0: - # all finished - break - - (i, o, x) = select(pipes, [], [], 1.0) - now = int(time.time()) - - # handle process output - for p in active_procs: - if p.proc.stdout in i: - p.read_line() - - # handle timeout - if p.running and now > p.timeout: - output_ts("'%s' timed out" % p.cmdAsStr()) - if p.inst: - p.inst.write("\n** timeout **\n") - p.timed_out = True - p.terminate() - - -def pidof(name): - pids = [] - - for d in [p for p in os.listdir('/proc') if p.isdigit()]: - try: - if os.path.basename(os.readlink('/proc/%s/exe' % d)) == name: - pids.append(int(d)) - except: - pass - - return pids - - -def readKeyValueFile(filename, allowed_keys = None, strip_quotes = True, assert_quotes = True): - """ Reads a KEY=Value style file (e.g. xensource-inventory). Returns a - dictionary of key/values in the file. Not designed for use with large files - as the file is read entirely into memory.""" - - f = open(filename, "r") - lines = [x.strip("\n") for x in f.readlines()] - f.close() - - # remove lines contain - if allowed_keys: - lines = filter(lambda x: True in [x.startswith(y) for y in allowed_keys], - lines) - - defs = [ (l[:l.find("=")], l[(l.find("=") + 1):]) for l in lines ] - - if strip_quotes: - def quotestrip(x): - if assert_quotes: - assert x.startswith("'") and x.endswith("'") - return x.strip("'") - defs = [ (a, quotestrip(b)) for (a,b) in defs ] - - return dict(defs) - - -class StringIOmtime(StringIO.StringIO): - def __init__(self, buf = ''): - StringIO.StringIO.__init__(self, buf) - self.mtime = time.time() - - def write(self, s): - StringIO.StringIO.write(self, s) - self.mtime = time.time() - - -if __name__ == "__main__": - try: - sys.exit(main()) - except KeyboardInterrupt: - print "\nInterrupted." - sys.exit(3) diff --git a/xenserver/usr_share_openvswitch_scripts_xen-bugtool-tc-class-show b/xenserver/usr_share_openvswitch_scripts_xen-bugtool-tc-class-show new file mode 100755 index 000000000..df07f2a8c --- /dev/null +++ b/xenserver/usr_share_openvswitch_scripts_xen-bugtool-tc-class-show @@ -0,0 +1,25 @@ +#! /bin/sh + +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General +# Public License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# +# Copyright (C) 2011 Nicira Networks. + +for iface in $(cd /sys/class/net && echo *); do + if [ -d /sys/class/net/$iface ]; then + echo Interface $iface: + # indent tc output so it's clear which interface it pertains to + /sbin/tc -s -d class show dev $iface | /bin/sed 's/^/ /' + fi +done |