tools: remove xend and associated python modules

I've retained xen.lowlevel.{xc,xs} since they seem more widely useful. I also
kept xen.lowlevel.xl even though it is disabled by default and IMHO useless in
its current form.

I've tried to clean up the various associated bits like example configs, init
scripts, udev rules etc but no doubt I have missed something, those can easily
be cleaned up later.

I've also removed xm-test since although it could in theory be reworked to
test xl it hasn't been touched for years. If someone wants to resurrect it
then they could do so via the git history.

This has been built but not runtime tested.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
v2: Clean out some .*ignore cruft
    Remove some xm/xend docs.
This commit is contained in:
Ian Campbell committed 2014-04-03 17:39:09 +01:00
1 parent e04254f7bc
commit 9e8672f1c3
503 files changed
+7 -83858

No files matched your search

-14
View File
@@ -245,8 +245,6 @@ tools/vtpm/tpm_emulator/*
tools/vtpm/vtpm/*
tools/vtpm_manager/manager/vtpm_managerd
tools/xcutils/lsevtchn
tools/xcutils/xc_restore
tools/xcutils/xc_save
tools/xcutils/readnotes
tools/xenfb/sdlfb
tools/xenfb/vncfb
@@ -279,18 +277,6 @@ tools/xentrace/xentrace_setsize
tools/xentrace/tbctl
tools/xentrace/xenctx
tools/xentrace/xentrace
tools/xm-test/ramdisk/buildroot
tools/xm-test/aclocal.m4
tools/xm-test/autom4te
tools/xm-test/install-sh
tools/xm-test/mkinstalldirs
tools/xm-test/missing
tools/xm-test/config(ure|.log|.status|.guess|.sub)
tools/xm-test/Makefile(.in)*
tools/xm-test/*/Makefile(.in)*
tools/xm-test/lib/XmTestLib/config.py
tools/xm-test/lib/XmTestReport/xmtest.py
tools/xm-test/tests/*.test
tools/ocaml-xenstored*
xen/.banner
xen/System.map
-12
View File
@@ -278,18 +278,6 @@
^tools/xentrace/tbctl$
^tools/xentrace/xenctx$
^tools/xentrace/xentrace$
^tools/xm-test/ramdisk/buildroot
^tools/xm-test/aclocal.m4$
^tools/xm-test/autom4te
^tools/xm-test/install-sh$
^tools/xm-test/mkinstalldirs$
^tools/xm-test/missing$
^tools/xm-test/config(ure|.log|.status|.guess|.sub)$
^tools/xm-test/Makefile(.in)*$
^tools/xm-test/.*/Makefile(.in)*$
^tools/xm-test/lib/XmTestLib/config.py$
^tools/xm-test/lib/XmTestReport/xmtest.py$
^tools/xm-test/tests/.*\.test$
^tools/firmware/ovmf-remote
^tools/firmware/ovmf$
^tools/qemu-xen-traditional-dir-remote
-2
View File
@@ -255,8 +255,6 @@ REMUS
M: Shriram Rajagopalan <rshriram@cs.ubc.ca>
S: Maintained
F: tools/remus/
F: tools/python/xen/remus/
F: tools/python/xen/lowlevel/checkpoint/
F: tools/blktap2/drivers/block-remus.c
F: tools/blktap2/drivers/hashtable*
-1
View File
@@ -54,7 +54,6 @@ CONFIG_ROMBIOS := @rombios@
CONFIG_SEABIOS := @seabios@
CONFIG_QEMU_TRAD := @qemu_traditional@
CONFIG_QEMU_XEN := @qemu_xen@
CONFIG_XEND := @xend@
CONFIG_BLKTAP1 := @blktap1@
#System options
-158
View File
@@ -1,158 +0,0 @@
=head1 NAME
xend-config.sxp - Xen daemon configuration file
=head1 SYNOPSIS
/etc/xen/xend-config.sxp
=head1 DESCRIPTION
The xend(1) program requires xend-config.sxp to specify operating
parameters which determine the behavior of the daemon at runtime.
The parameters are specified in S-expression format. See the example
configuration file in I</etc/xen/xend-config.sxp> for details.
=head1 OPTIONS
The following lists the daemon configuration parameters:
=over 4
=item I<logfile>
The location of the file to record runtime log messages. Defaults to
I</var/log/xen/xend.log>.
=item I<loglevel>
Filters out messages below the specified level. Possible values are
DEBUG, INFO, WARNING, ERROR, CRITICAL. Defaults to I<DEBUG>.
=item I<xend-http-server>
A boolean value that tells xend whether or not to start the http
stream socket management server. Defaults to I<no>.
=item I<xend-unix-server>
A boolean value that tells xend whether or not to start the unix
domain socket management server. This is required for the CLI tools
to operate. Defaults to I<yes>.
=item I<xend-relocation-server>
A boolean value that tells xend whether or not to start the relocation
server. This is required for cross-machine migrations. Defaults to
I<no>.
=item I<xend-unix-path>
The location of the unix domain socket the xend-unix-server will use
to communicate with the management tools. Defaults to
I</var/lib/xend/xend-socket>.
=item I<xend-port>
The port that will be used by the http management server. Defaults to
I<8000>.
=item I<xend-relocation-port>
The port that will be used by the relocation server. Defaults to
I<8002>.
=item I<xend-address>
The address to which the http management server will bind. Defaults
to I<''> which means "all interfaces".
=item I<xend-relocation-address>
The address to which the relocation server will bind. Defaults to
I<''> which means "all interfaces".
=item I<console-limit>
The kilobyte buffer limit that will be enforced by the console server.
This limit is set per-domain, and is needed to prevent a single domain
from overwhelming the console server with massive amounts of data.
Defaults to I<1024>.
=item I<network-script>
The name of the script in I</etc/xen/scripts> that will be run to
setup the networking environment. This can be any name, but in
general is either I<network-bridge> or I<network-route>.
=item I<vif-script>
The name of the script in I</etc/xen/scripts> that will be run to
setup a virtual interface when it is created or destroyed. This needs
to (in general) work in unison with the I<network-script>.
=item I<dom0-min-mem>
This specifies the minimum number of megabytes that will be reserved
for Domain0. If this value is positive, Domain0 will be automatically
ballooned down to this limit to make space for new domains. If this
is set to 0, Domain0 will not be automatically ballooned.
=item I<dom0-cpus>
This specifies the number of CPUs that Domain0 will be allowed to use.
If the value is 0, all available CPUs will be used by Domain0.
=item I<enable-dump>
A boolean value that tells xend whether or not core dumps of guest
domains should be saved when a crash occurs. Defaults to I<no>.
=item I<external-migration-tool>
The name of an application or script that can handle external device
migration, such as for example virtual TPM migration. An example
script is I</etc/xen/scripts/external-device-migrate>.
=item I<device-create-timeout>
Integer value that tells xend how long it should wait for a new device
to be created. Defaults to I<100>.
=item I<device-destroy-timeout>
Integer value that tells xend how long it should wait for a device to
be destroyed. Defaults to I<100>.
=back
=head1 EXAMPLES
An example configuration with relocation enabled for the local network:
=over 4
(xend-relocation-server yes)
(xend-relocation-address 192.0.2.192)
(network-script network-bridge)
(vif-script vif-bridge)
(dom0-min-mem 0)
(dom0-cpus 0)
=back
=head1 CAVEATS
Note that relocation is currently unsecured and is very dangerous if
left enabled. No authentication is performed, and very little sanity
checking takes place. Enable at your own risk.
=head1 SEE ALSO
B<xend>(1)
=head1 AUTHOR
Dan Smith <danms@us.ibm.com>
-1
View File
@@ -12,7 +12,6 @@ The B<xl> program is the new tool for managing Xen guest
domains. The program can be used to create, pause, and shutdown
domains. It can also be used to list current domains, enable or pin
VCPUs, and attach or detach virtual block devices.
The old B<xm> tool is deprecated and should not be used.
The basic structure of every B<xl> command is almost always:
-1004
View File
File diff suppressed because it is too large. Load diff
-358
View File
@@ -1,358 +0,0 @@
=head1 NAME
xmdomain.cfg - xm domain config file format
=head1 SYNOPSIS
/etc/xen/myxendomain
/etc/xen/myxendomain2
/etc/xen/auto/myxenautostarted
=head1 DESCRIPTION
The B<xm>(1) program uses python executable config files to define
domains to create from scratch. Each of these config files needs to
contain a number of required options, and may specify many more.
Domain configuration files live in /etc/xen by default, if you store
config files anywhere else the full path to the config file must be
specified in the I<xm create> command.
/etc/xen/auto is a special case. Domain config files in that
directory will be started automatically at system boot if the
xendomain init script is enabled. The contents of /etc/xen/auto
should be symlinks to files in /etc/xen to allow I<xm create> to be
used without full paths.
Options are specified by I<name = value> statements in the
xmdomain.cfg files.
=head1 OPTIONS
The following lists the most commonly used options for a domain config
file.
=over 4
=item B<kernel>
The kernel image for the domain. The format of the parameter is the
fully qualified path to the kernel image file,
i.e. I</boot/vmlinuz-2.6.12-xenU>.
=item B<ramdisk>
The initial ramdisk for the domain. The format of the parameter is
the fully qualified path to the initrd, i.e. I</boot/initrd.gz>. On
many Linux distros you will not need a ramdisk if using the default
xen kernel.
=item B<memory>
The amount of RAM, in megabytes, to allocate to the domain when it
starts. Allocating insufficient memory for a domain may produce
extremely bizarre behavior. If there isn't enough free memory left on
the machine to fulfil this request, the domain will fail to start.
Xen does not support overcommit of memory, so the total memory of all
guests (+ 64 MB needed for Xen) must be less than or equal to the
physical RAM in the machine.
=item B<name>
A unique name for the domain. Attempting to create two domains with
the same name will cause an error.
=item B<root>
Specifies the root device for the domain. This is required for Linux
domains, and possibly other OSes.
=item B<nics>
The number of network interfaces allocated to the domain on boot. It
defaults to 1.
=item B<disk>
An array of block device stanzas, in the form:
disk = [ "stanza1", "stanza2", ... ]
Each stanza has 3 terms, separated by commas,
"backend-dev,frontend-dev,mode".
=over 4
=item I<backend-dev>
The device in the backend domain that will be exported to the guest
(frontend) domain. Supported formats include:
I<phy:device> - export the physical device listed. The device can be
in symbolic form, as in sda7, or as the hex major/minor number, as in
0x301 (which is hda1).
I<file://path/to/file> - export the file listed as a loopback device.
This will take care of the loopback setup before exporting the device.
=item I<frontend-dev>
How the device should appear in the guest domain. The device can be
in symbolic form, as in sda7, or as the hex major/minor number, as in
0x301 (which is hda1).
=item I<mode>
The access mode for the device. There are currently 2 valid options,
I<r> (read-only), I<w> (read/write).
=back
=item B<vif>
An array of virtual interface stanzas in the form:
vif = [ "stanza1", "stanza2", ... ]
Each stanza specifies a set of I<name = value> options separated by
commas, in the form: "name1=value1, name2=value2, ..."
B<OPTIONS>
=over 4
=item I<bridge>
The network bridge to be used for this device. This is especially
needed if multiple bridges exist on the machine.
=item I<mac>
The MAC address for the virtual interface. If mac is not specified,
one will be randomly chosen by xen with the 00:16:3e vendor id prefix.
=back
=item B<vfb>
A virtual frame buffer stanza in the form:
vfb = [ "stanza" ]
The stanza specifies a set of I<name = value> options separated by
commas, in the form: "name1=value1, name2=value2, ..."
B<OPTIONS>
=over 4
=item I<type>
There are currently two valid options: I<vnc> starts a VNC server that
lets you connect an external VNC viewer, and I<sdl> starts an internal
viewer.
=item I<vncdisplay>
The VNC display number to use, defaults to the domain ID. The
VNC server listens on port 5900 + display number.
=item I<vnclisten>
The listening address for the VNC server, default 127.0.0.1.
=item I<vncunused>
If non-zero, the VNC server listens on the first unused port above
5900.
=item I<vncpasswd>
Overrides the XenD configured default password.
=item I<display>
Display to use for the internal viewer, defaults to environment
variable I<DISPLAY>.
=item I<xauthority>
Authority file to use for the internal viewer, defaults to environment
variable I<XAUTHORITY>.
=back
=back
=head1 ADDITIONAL OPTIONS
The following options are also supported in the config file, though
are far more rarely used.
=over 4
=item B<builder>
Which builder should be used to construct the domain. This defaults
to the I<linux> if not specified, which is the builder for
paravirtualized Linux domains.
=item B<cpu>
Specifies which CPU the domain should be started on, where 0 specifies
the first cpu, 1 the second, and so on. This defaults to -1, which
means Xen is free to pick which CPU to start on.
=item B<cpus>
Specifies a list of CPUs on which the domains' VCPUs are allowed to
execute upon. The syntax supports ranges (0-3), and negation, ^1.
For instance:
cpus = "0-3,5,^1"
Will result in CPUs 0, 2, 3, 5 being available for use by the domain.
=item B<extra>
Extra information to append to the end of the kernel parameter line.
The format is a string, the contents of which can be anything that the
kernel supports. For instance:
extra = "4"
Will cause the domain to boot to runlevel 4.
=item B<nfs_server>
The IP address of the NFS server to use as the root device for the
domain. In order to do this you'll need to specify I<root=/dev/nfs>,
and specify I<nfs_root>.
=item B<nfs_root>
The directory on the NFS server to be used as the root filesystem.
Specified as a fully qualified path, i.e. I</full/path/to/root/dir>.
=item B<vcpus>
The number of virtual cpus to allocate to the domain. In order to use
this the xen kernel must be compiled with SMP support.
This defaults to 1, meaning running the domain as a UP.
=back
=head1 DOMAIN SHUTDOWN OPTIONS
There are 3 options which control domain shutdown (both planned and
unplanned) under certain events. The 3 events currently captured are:
=over 4
=item B<on_shutdown>
Triggered on either an I<xm shutdown> or graceful shutdown from inside
the DomU.
=item B<on_reboot>
Triggered on either an I<xm reboot> or graceful reboot from inside the
DomU.
=item B<on_crash>
Triggered when a DomU goes to the crashed state for any reason.
=back
All of them take one of 4 valid states listed below.
=over 4
=item B<destroy>
The domain will be cleaned up completely. No attempt at respawning
will occur. This is what a typical shutdown would look like.
=item B<restart>
The domain will be restarted with the same name as the old domain.
This is what a typical reboot would look like.
=item B<preserve>
The domain will not be cleaned up at all. This is often useful for
crash state domains which ensures that enough evidence is to debug the
real issue.
=item B<rename-restart>
The old domain will not be cleaned up, but will be renamed so a new
domain can be restarted in it's place. The old domain will be renamed with
a suffix -1, -2, etc, and assigned a new random UUID; the new domain will
keep the original name and UUID. The old domain will release the devices that
it holds, so that the new one may take them.
=back
Additionally, the "on_crash" event can also take:
=over 4
=item B<coredump-destroy>
Dump the crashed domain's core and then destroy it.
=item B<coredump-restart>
Dump the crashed domain's core and then restart it.
=back
=head1 EXAMPLES
The following are quick examples of ways that domains might be
configured. They should not be considered an exhaustive set.
=over 4
=item I<A Loopback File as Root>
kernel = "/boot/vmlinuz-2.6-xenU"
memory = 128
name = "MyLinux"
root = "/dev/hda1 ro"
disk = [ "file:/var/xen/mylinux.img,hda1,w" ]
This creates a domain called MyLinux with 128 MB of memory using a
default xen kernel, and the file /var/xen/mylinux.img loopback mounted
at hda1, which is the root filesystem.
=item I<NFS Root>
FIXME: write me
=item I<LVM Root>
FIXME: write me
=item I<Two Networks>
FIXME: write me
=back
=head1 SEE ALSO
B<xm>(1)
=head1 AUTHOR
Sean Dague <sean at dague dot net>
=head1 BUGS
Not all options are currently documented
-48
View File
@@ -688,7 +688,6 @@ seabios_path
qemu_xen
qemu_traditional
blktap1
xend
debug
seabios
rombios
@@ -765,7 +764,6 @@ enable_ovmf
enable_rombios
enable_seabios
enable_debug
enable_xend
enable_blktap1
enable_qemu_traditional
with_system_qemu
@@ -1427,7 +1425,6 @@ Optional Features:
--disable-rombios Disable ROM BIOS (default is ENABLED)
--disable-seabios Disable SeaBIOS (default is ENABLED)
--disable-debug Disable debug build of tools (default is ENABLED)
--enable-xend Enable xend toolstack (default is DISABLED)
--enable-blktap1 Enable blktap1 tools (default is DISABLED)
--enable-qemu-traditional
Enable qemu traditional device model, (DEFAULT is on
@@ -3747,29 +3744,6 @@ debug=$ax_cv_debug
# Check whether --enable-xend was given.
if test "${enable_xend+set}" = set; then :
enableval=$enable_xend;
fi
if test "x$enable_xend" = "xno"; then :
ax_cv_xend="n"
elif test "x$enable_xend" = "xyes"; then :
ax_cv_xend="y"
elif test -z $ax_cv_xend; then :
ax_cv_xend="n"
fi
xend=$ax_cv_xend
# Check whether --enable-blktap1 was given.
if test "${enable_blktap1+set}" = set; then :
enableval=$enable_blktap1;
@@ -9480,25 +9454,3 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
if test "x$xend" = "xy" ; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You have enabled the xend toolstack.
xend is deprecated and scheduled for removal. Please migrate to another
toolstack ASAP.
See http://wiki.xen.org/wiki/Choice_of_Toolstacks for information on
other alternatives, including xl which is designed to be a drop in
replacement for xm (http://wiki.xen.org/wiki/XL).
" >&5
$as_echo "$as_me: WARNING: You have enabled the xend toolstack.
xend is deprecated and scheduled for removal. Please migrate to another
toolstack ASAP.
See http://wiki.xen.org/wiki/Choice_of_Toolstacks for information on
other alternatives, including xl which is designed to be a drop in
replacement for xm (http://wiki.xen.org/wiki/XL).
" >&2;}
fi
-13
View File
@@ -58,7 +58,6 @@ AX_ARG_DEFAULT_DISABLE([ovmf], [Enable OVMF])
AX_ARG_DEFAULT_ENABLE([rombios], [Disable ROM BIOS])
AX_ARG_DEFAULT_ENABLE([seabios], [Disable SeaBIOS])
AX_ARG_DEFAULT_ENABLE([debug], [Disable debug build of tools])
AX_ARG_DEFAULT_DISABLE([xend], [Enable xend toolstack])
AX_ARG_DEFAULT_DISABLE([blktap1], [Enable blktap1 tools])
AC_ARG_ENABLE([qemu-traditional],
@@ -245,15 +244,3 @@ AC_CHECK_HEADERS([yajl/yajl_version.h sys/eventfd.h])
AC_OUTPUT()
AS_IF([test "x$xend" = "xy" ], [
AC_MSG_WARN(
[You have enabled the xend toolstack.
xend is deprecated and scheduled for removal. Please migrate to another
toolstack ASAP.
See http://wiki.xen.org/wiki/Choice_of_Toolstacks for information on
other alternatives, including xl which is designed to be a drop in
replacement for xm (http://wiki.xen.org/wiki/XL).
])
])
-12
View File
@@ -5,18 +5,6 @@ include $(XEN_ROOT)/tools/Rules.mk
XEN_READMES = README
XEN_READMES += README.incompatibilities
XEN_CONFIGS-$(CONFIG_XEND) += xend-config.sxp
XEN_CONFIGS-$(CONFIG_XEND) += xm-config.xml
XEN_CONFIGS-$(CONFIG_XEND) += xmexample1
XEN_CONFIGS-$(CONFIG_XEND) += xmexample2
XEN_CONFIGS-$(CONFIG_XEND) += xmexample3
XEN_CONFIGS-$(CONFIG_XEND) += xmexample.hvm
XEN_CONFIGS-$(CONFIG_XEND) += xmexample.hvm-stubdom
XEN_CONFIGS-$(CONFIG_XEND) += xmexample.pv-grub
XEN_CONFIGS-$(CONFIG_XEND) += xmexample.nbd
XEN_CONFIGS-$(CONFIG_XEND) += xend-pci-quirks.sxp
XEN_CONFIGS-$(CONFIG_XEND) += xend-pci-permissive.sxp
XEN_CONFIGS += xlexample.hvm
XEN_CONFIGS += xlexample.pvlinux
XEN_CONFIGS += xl.conf
-304
View File
@@ -1,304 +0,0 @@
# -*- sh -*-
#
# Xend configuration file.
#
# This example configuration is appropriate for an installation that
# utilizes a bridged network configuration. Access to xend via http
# is disabled.
# Commented out entries show the default for that entry, unless otherwise
# specified.
#(logfile /var/log/xen/xend.log)
#(loglevel DEBUG)
# Uncomment the line below. Set the value to flask, acm, or dummy to
# select a security module.
#(xsm_module_name dummy)
# The Xen-API server configuration.
#
# This value configures the ports, interfaces, and access controls for the
# Xen-API server. Each entry in the list starts with either unix, a port
# number, or an address:port pair. If this is "unix", then a UDP socket is
# opened, and this entry applies to that. If it is a port, then Xend will
# listen on all interfaces on that TCP port, and if it is an address:port
# pair, then Xend will listen on the specified port, using the interface with
# the specified address.
#
# The subsequent string configures the user-based access control for the
# listener in question. This can be one of "none" or "pam", indicating either
# that users should be allowed access unconditionally, or that the local
# Pluggable Authentication Modules configuration should be used. If this
# string is missing or empty, then "pam" is used.
#
# The final string gives the host-based access control for that listener. If
# this is missing or empty, then all connections are accepted. Otherwise,
# this should be a space-separated sequence of regular expressions; any host
# with a fully-qualified domain name or an IP address that matches one of
# these regular expressions will be accepted.
#
# Example: listen on TCP port 9363 on all interfaces, accepting connections
# only from machines in example.com or localhost, and allow access through
# the unix domain socket unconditionally:
#
# (xen-api-server ((9363 pam '^localhost$ example\\.com$')
# (unix none)))
#
# Optionally, the TCP Xen-API server can use SSL by specifying the private
# key and certificate location:
#
# (9367 pam '' xen-api.key xen-api.crt)
#
# Default:
# (xen-api-server ((unix)))
#(xend-http-server no)
#(xend-unix-server no)
#(xend-tcp-xmlrpc-server no)
#(xend-unix-xmlrpc-server yes)
#(xend-relocation-server no)
(xend-relocation-server yes)
#(xend-relocation-ssl-server no)
#(xend-udev-event-server no)
#(xend-unix-path /var/lib/xend/xend-socket)
# Address and port xend should use for the legacy TCP XMLRPC interface,
# if xend-tcp-xmlrpc-server is set.
#(xend-tcp-xmlrpc-server-address 'localhost')
#(xend-tcp-xmlrpc-server-port 8006)
# SSL key and certificate to use for the legacy TCP XMLRPC interface.
# Setting these will mean that this port serves only SSL connections as
# opposed to plaintext ones.
#(xend-tcp-xmlrpc-server-ssl-key-file xmlrpc.key)
#(xend-tcp-xmlrpc-server-ssl-cert-file xmlrpc.crt)
# Port xend should use for the HTTP interface, if xend-http-server is set.
#(xend-port 8000)
# Port xend should use for the relocation interface, if xend-relocation-server
# is set.
#(xend-relocation-port 8002)
# Port xend should use for the ssl relocation interface, if
# xend-relocation-ssl-server is set.
#(xend-relocation-ssl-port 8003)
# SSL key and certificate to use for the ssl relocation interface, if
# xend-relocation-ssl-server is set.
#(xend-relocation-server-ssl-key-file xmlrpc.key)
#(xend-relocation-server-ssl-cert-file xmlrpc.crt)
# Whether to use ssl as default when relocating.
#(xend-relocation-ssl no)
# Address xend should listen on for HTTP connections, if xend-http-server is
# set.
# Specifying 'localhost' prevents remote connections.
# Specifying the empty string '' (the default) allows all connections.
#(xend-address '')
#(xend-address localhost)
# Address xend should listen on for relocation-socket connections, if
# xend-relocation-server is set.
# Meaning and default as for xend-address above.
# Also, interface name is allowed (e.g. eth0) there to get the
# relocation address to be bound on.
#(xend-relocation-address '')
# The hosts allowed to talk to the relocation port. If this is empty (the
# default), then all connections are allowed (assuming that the connection
# arrives on a port and interface on which we are listening; see
# xend-relocation-port and xend-relocation-address above). Otherwise, this
# should be a space-separated sequence of regular expressions. Any host with
# a fully-qualified domain name or an IP address that matches one of these
# regular expressions will be accepted.
#
# For example:
# (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
#
#(xend-relocation-hosts-allow '')
(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
# The limit (in kilobytes) on the size of the console buffer
#(console-limit 1024)
##
# To bridge network traffic, like this:
#
# dom0: ----------------- bridge -> real eth0 -> the network
# |
# domU: fake eth0 -> vifN.0 -+
#
# use
#
# (network-script network-bridge)
#
# Your default ethernet device is used as the outgoing interface, by default.
# To use a different one (e.g. eth1) use
#
# (network-script 'network-bridge netdev=eth1')
#
# The bridge is named eth0, by default (yes, really!)
#
# It is normally much better to create the bridge yourself in
# /etc/network/interfaces. network-bridge start does nothing if you
# already have a bridge, and network-bridge stop does nothing if the
# default bridge name (normally eth0) is not a bridge. See
# bridge-utils-interfaces(5) for full information on the syntax in
# /etc/network/interfaces, but you probably want something like this:
# iface xenbr0 inet static
# address [etc]
# netmask [etc]
# [etc]
# bridge_ports eth0
#
# To have network-bridge create a differently-named bridge, use:
# (network-script 'network-bridge bridge=<name>')
#
# It is possible to use the network-bridge script in more complicated
# scenarios, such as having two outgoing interfaces, with two bridges, and
# two fake interfaces per guest domain. To do things like this, write
# yourself a wrapper script, and call network-bridge from it, as appropriate.
#
(network-script network-bridge)
# The script used to control virtual interfaces. This can be overridden on a
# per-vif basis when creating a domain or a configuring a new vif. The
# vif-bridge script is designed for use with the network-bridge script, or
# similar configurations.
#
# If you have overridden the bridge name using
# (network-script 'network-bridge bridge=<name>') then you may wish to do the
# same here. The bridge name can also be set when creating a domain or
# configuring a new vif, but a value specified here would act as a default.
#
# If you are using only one bridge, the vif-bridge script will discover that,
# so there is no need to specify it explicitly. The default is to use
# the bridge which is listed first in the output from brctl.
#
(vif-script vif-bridge)
## Use the following if network traffic is routed, as an alternative to the
# settings for bridged networking given above.
#(network-script network-route)
#(vif-script vif-route)
## Use the following if network traffic is routed with NAT, as an alternative
# to the settings for bridged networking given above.
#(network-script network-nat)
#(vif-script vif-nat)
# dom0-min-mem is the lowest permissible memory level (in MB) for dom0.
# This is a minimum both for auto-ballooning (as enabled by
# enable-dom0-ballooning below) and for xm mem-set when applied to dom0.
(dom0-min-mem 196)
# Whether to enable auto-ballooning of dom0 to allow domUs to be created.
# If enable-dom0-ballooning = no, dom0 will never balloon out.
(enable-dom0-ballooning yes)
# 32-bit paravirtual domains can only consume physical
# memory below 168GB. On systems with memory beyond that address,
# they'll be confined to memory below 128GB.
# Using total_available_memory (in GB) to specify the amount of memory reserved
# in the memory pool exclusively for 32-bit paravirtual domains.
# Additionally you should use dom0_mem = <-Value> as a parameter in
# xen kernel to reserve the memory for 32-bit paravirtual domains, default
# is "0" (0GB).
(total_available_memory 0)
# In SMP system, dom0 will use dom0-cpus # of CPUS
# If dom0-cpus = 0, dom0 will take all cpus available
(dom0-cpus 0)
# Whether to enable core-dumps when domains crash.
#(enable-dump no)
# The tool used for initiating virtual TPM migration
#(external-migration-tool '')
# The interface for VNC servers to listen on. Defaults
# to 127.0.0.1 To restore old 'listen everywhere' behaviour
# set this to 0.0.0.0
#(vnc-listen '127.0.0.1')
# The default password for VNC console on HVM domain.
# Empty string is no authentication.
(vncpasswd '')
# The VNC server can be told to negotiate a TLS session
# to encryption all traffic, and provide x509 cert to
# clients enabling them to verify server identity. The
# GTK-VNC widget, virt-viewer, virt-manager and VeNCrypt
# all support the VNC extension for TLS used in QEMU. The
# TightVNC/RealVNC/UltraVNC clients do not.
#
# To enable this create x509 certificates / keys in the
# directory ${XEN_CONFIG_DIR} + vnc
#
# ca-cert.pem - The CA certificate
# server-cert.pem - The Server certificate signed by the CA
# server-key.pem - The server private key
#
# and then uncomment this next line
# (vnc-tls 1)
# The certificate dir can be pointed elsewhere..
#
# (vnc-x509-cert-dir vnc)
# The server can be told to request & validate an x509
# certificate from the client. Only clients with a cert
# signed by the trusted CA will be able to connect. This
# is more secure the password auth alone. Passwd auth can
# used at the same time if desired. To enable client cert
# checking uncomment this:
#
# (vnc-x509-verify 1)
# The default keymap to use for the VM's virtual keyboard
# when not specififed in VM's configuration
#(keymap 'en-us')
# Script to run when the label of a resource has changed.
#(resource-label-change-script '')
# Rotation count of qemu-dm log file.
#(qemu-dm-logrotate-count 10)
# Path where persistent domain configuration is stored.
# Default is /var/lib/xend/domains/
#(xend-domains-path /var/lib/xend/domains)
# Number of seconds xend will wait for device creation and
# destruction
#(device-create-timeout 100)
#(device-destroy-timeout 100)
# When assigning device to HVM guest, we use the strict check for HVM guest by
# default. (For PV guest, we use loose check automatically if necessary.)
# When we assign device to HVM guest, if we meet with the co-assignment
# issues or the ACS issue, we could try changing the option to 'no' -- however,
# we have to realize this may incur security issue and we can't make sure the
# device assignment could really work properly even after we do this.
#(pci-passthrough-strict-check yes)
# If we have a very big scsi device configuration, start of xend is slow,
# because xend scans all the device paths to build its internal PSCSI device
# list. If we need only a few devices for assigning to a guest, we can reduce
# the scan to this device. Set list list of device paths in same syntax like in
# command lsscsi, e.g. ('16:0:0:0' '15:0')
# (pscsi-device-mask ('*'))
-27
View File
@@ -1,27 +0,0 @@
###############################################################################
# Configuration file for granting quiry PCI devices full write access to their
# configuration space. This file should only be used when you are unable to
# determine the exact registers required by your device. Even so, it should
# be used only temporarily.
#
# SEND A MESSAGE TO xen-devel@lists.xensource.com IF YOU USE THIS FILE.
#
# Using this file should NOT be necessary. If you must use it to make some
# device work, send a message to the above list with as much information about
# your device as possible so the developers can make accomodations for it.
# Once developers make the necessary updates you can remove the corresponding
# entry for your device.
###############################################################################
# Entries are formated as follows: <vendor>:<device>[:<subvendor>:<subdevice>]
#
# Example: Appending to an existing list
#
# (unconstrained_dev_ids
# ('XXXX:XXXX:XXXX:XXXX' # existing entry
# 'YYYY:YYYY:YYYY:YYYY' # new entry 1
# 'ZZZZ:ZZZZ') # new entry 2
# )
###############################################################################
(unconstrained_dev_ids
#('0123:4567:89AB:CDEF')
)
-96
View File
@@ -1,96 +0,0 @@
###############################################################################
# Configuration file for quirky PCI devices that require write-access to
# parts of the configuration space. Use this file to specific PCI device
# IDs and the configuration space fields to which those devices must be
# able to write.
#
# Length is important, so be sure to match new entries with the
# lengths of comparable existing entries.
#
# Additions to this file take effect as soon as a new domain with a
# matching device is started. However, to remove a field that was
# previously applied to a device you must unbind the device from
# pciback.
###############################################################################
# This is a bogus entry to show how a new device would be added to the list
#
# (new_quirky_dev_name
# (pci_ids
# ('0123:4567:890A:BCEF')
# )
#
# (pci_config_space_fields
# ('12345678:1:00000000')
# )
# )
###############################################################################
(tg3
(pci_ids
# Entries are formated as follows:
# <vendor>:<device>[:<subvendor>:<subdevice>]
('14e4:1644' # Broadcom Tigon3 5700
'14e4:1645' # Broadcom Tigon3 5701
'14e4:1646' # Broadcom Tigon3 5702
'14e4:1647' # Broadcom Tigon3 5703
'14e4:1648' # Broadcom Tigon3 5704
'14e4:164d' # Broadcom Tigon3 5702FE
'14e4:1653' # Broadcom Tigon3 5705
'14e4:1654' # Broadcom Tigon3 5705_2
'14e4:165d' # Broadcom Tigon3 5705M
'14e4:165e' # Broadcom Tigon3 5705M_2
'14e4:16a6' # Broadcom Tigon3 5702X
'14e4:16a7' # Broadcom Tigon3 5703X
'14e4:16a8' # Broadcom Tigon3 5704S
'14e4:16c6' # Broadcom Tigon3 5702A3
'14e4:16c7' # Broadcom Tigon3 5703A3
'14e4:1696' # Broadcom Tigon3 5782
'14e4:169c' # Broadcom Tigon3 5788
'14e4:169d' # Broadcom Tigon3 5789
'14e4:170d' # Broadcom Tigon3 5901
'14e4:1649' # Broadcom Tigon3 5704S_2
'14e4:166e' # Broadcom Tigon3 5705F
'14e4:1658' # Broadcom Tigon3 5720
'14e4:1659' # Broadcom Tigon3 5721
'14e4:1676' # Broadcom Tigon3 5750
'14e4:1677' # Broadcom Tigon3 5751
'14e4:167c' # Broadcom Tigon3 5750M
'14e4:167d' # Broadcom Tigon3 5751M
'14e4:167e' # Broadcom Tigon3 5751F
'14e4:1600' # Broadcom Tigon3 5752
'14e4:1601' # Broadcom Tigon3 5752M
'14e4:16f7' # Broadcom Tigon3 5753
'14e4:16fd' # Broadcom Tigon3 5753M
'14e4:16fe' # Broadcom Tigon3 5753F
'14e4:1668' # Broadcom Tigon3 5714
'14e4:1678' # Broadcom Tigon3 5715
'14e4:166a' # Broadcom Tigon3 5780
'14e4:166b' # Broadcom Tigon3 5780S
'14e4:16dd' # Broadcom Tigon3 5781
'1148:4400' # Syskonnect 9DXX
'1148:4500' # Syskonnect 9MXX
'173b:03e8' # Altima AC1000
'173b:03e9' # Altima AC1001
'173b:03eb' # Altima AC1003
'173b:03ea' # Altima AC9100
'106b:1645') # Apple Tigon3
)
(pci_config_space_fields
# Entries are formated as follows:
# <register>:<size>:<mask>
# size is measured in bytes (1,2,4 are valid sizes)
# mask is currently unused; use all zero's
('00000078:4:00000000' # TG3PCI_REG_BASE_ADDR
'0000007c:4:00000000' # TG3PCI_MEM_WIN_BASE_ADDR
'00000080:4:00000000' # TG3PCI_REG_DATA
'00000084:4:00000000' # TG3PCI_MEM_WIN_DATA
'00000090:4:00000000' # TG3PCI_MISC_LOCAL_CTRL
'00000068:4:00000000' # TG3PCI_MISC_HOST_CTRL
'0000009C:4:00000000' # TG3PCI_STD_RING_PROD_IDX + TG3_64BIT_REG_LOW
'00000098:4:00000000' # TG3PCI_STD_RING_PROD_IDX + TG3_64BIT_REG_HIGH
'000000a4:4:00000000' # TG3PCI_RCV_RET_RING_CON_IDX + TG3_64BIT_REG_LOW
'000000a0:4:00000000' # TG3PCI_RCV_RET_RING_CON_IDX + TG3_64BIT_REG_HIGH
'00000070:4:00000000') # TG3PCI_PCISTATE
)
)
-45
View File
@@ -1,45 +0,0 @@
<!--
Copyright (C) 2006 XenSource Inc.
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
-->
<!--
This is a configuration file for xm; it should be placed in
/etc/xen/xm-config.xml. If this file is missing, then xm will fall back to
the normal behaviour that's in Xen 3.0.4 and below. The settings here are
most useful for experimenting with the Xen-API preview in Xen 3.0.4.
-->
<xm>
<!-- The server element describes how to talk to Xend. The type may be
Xen-API or LegacyXMLRPC (the default). The URI is that of the
server; you might try http://server:9363/ or
httpu:///var/run/xend/xen-api.sock for the Xen-API, or
httpu:///var/run/xend/xmlrpc.sock for the legacy server.
The username and password attributes will be used to log in if Xen-API
is being used.
-->
<!--
<server type='Xen-API'
uri='http://localhost:9363/'
username='me'
password='mypassword' />
-->
</xm>
-373
View File
@@ -1,373 +0,0 @@
# -*- mode: python; -*-
#============================================================================
# Python configuration setup for 'xm create'.
# This script sets the parameters used when a domain is created using 'xm create'.
# You use a separate script for each domain you want to create, or
# you can set the parameters for the domain on the xm command line.
#============================================================================
#----------------------------------------------------------------------------
# Kernel image file.
kernel = "hvmloader"
# The domain build function. HVM domain uses 'hvm'.
builder='hvm'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 128
# Shadow pagetable memory for the domain, in MB.
# If not explicictly set, xend will pick an appropriate value.
# Should be at least 2KB per MB of domain memory, plus a few MB per vcpu.
# shadow_memory = 8
# Whether to transparently share this domain's memory with other domains.
# default = 0
# memory_sharing = 0
# A name for your domain. All domains must have different names.
name = "ExampleHVMDomain"
# 128-bit UUID for the domain. The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
#-----------------------------------------------------------------------------
# The number of cpus guest platform has, default=1
#vcpus=1
# Enable/disable HVM guest PAE, default=1 (enabled)
#pae=1
# Enable/disable HVM guest ACPI, default=1 (enabled)
#acpi=1
# Enable/disable HVM APIC mode, default=1 (enabled)
# Note that this option is ignored if vcpus > 1
#apic=1
# Enable/disable extended power management support within HVM guest, i.e., beyond
# S3, S4, S5 within guest like exposing battery meter.
# 0 (default option, extended power management support disabled)
# 1 (pass-through mode; uses pass-through as needed; efficient but limited in scope)
# 2 (non pass-through mode; extended scope, likely to work on all applicable environment
# but comparitively less efficient than pass-through mode)
# xen_extended_power_mgmt=0
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
#cpus = "0" # all vcpus run on CPU0
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
# type=ioemu specify the NIC is an ioemu device not netfront
vif = [ 'type=ioemu, bridge=xenbr0' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
#disk = [ 'phy:hda1,hda1,r' ]
disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
# may specify:
#
# "destroy", meaning that the domain is cleaned up as normal;
# "restart", meaning that a new domain is started in place of the old
# one;
# "preserve", meaning that no clean-up is done until the domain is
# manually destroyed (using xm destroy, for example); or
# "rename-restart", meaning that the old domain is not cleaned up, but is
# renamed and a new domain started in its place.
#
# In the event a domain stops due to a crash, you have the additional options:
#
# "coredump-destroy", meaning dump the crashed domain's core and then destroy;
# "coredump-restart', meaning dump the crashed domain's core and the restart.
#
# The default is
#
# on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# For backwards compatibility we also support the deprecated option restart
#
# restart = 'onreboot' means on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'destroy'
#
# restart = 'always' means on_poweroff = 'restart'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# restart = 'never' means on_poweroff = 'destroy'
# on_reboot = 'destroy'
# on_crash = 'destroy'
#on_poweroff = 'destroy'
#on_reboot = 'restart'
#on_crash = 'restart'
#============================================================================
# Device Model to be used
device_model = 'qemu-dm'
#-----------------------------------------------------------------------------
# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
# default: hard disk, cd-rom, floppy
#boot="cda"
#-----------------------------------------------------------------------------
# write to temporary files instead of disk image files
#snapshot=1
#----------------------------------------------------------------------------
# enable SDL library for graphics, default = 0
sdl=0
#----------------------------------------------------------------------------
# enable OpenGL for texture rendering inside the SDL window, default = 1
# valid only if sdl is enabled.
opengl=1
#----------------------------------------------------------------------------
# enable VNC library for graphics, default = 1
vnc=1
#----------------------------------------------------------------------------
# address that should be listened on for the VNC server if vnc is set.
# default is to use 'vnc-listen' setting from
# auxbin.xen_configdir() + /xend-config.sxp
#vnclisten="127.0.0.1"
#----------------------------------------------------------------------------
# set VNC display number, default = domid
#vncdisplay=1
#----------------------------------------------------------------------------
# try to find an unused port for the VNC server, default = 1
#vncunused=1
#----------------------------------------------------------------------------
# set password for domain's VNC console
# default is depents on vncpasswd in xend-config.sxp
vncpasswd=''
#----------------------------------------------------------------------------
# no graphics, use serial port
#nographic=0
#----------------------------------------------------------------------------
# enable stdvga, default = 0 (use cirrus logic device model)
stdvga=0
#-----------------------------------------------------------------------------
# serial port re-direct to pty deivce, /dev/pts/n
# then xm console or minicom can connect
serial='pty'
#----------------------------------------------------------------------------
# tsc_mode : TSC mode (0=default, 1=native TSC, 2=never emulate, 3=pvrdtscp)
# emulate TSC provides synced TSC for all vcpus, but lose perfomrance.
# native TSC leverages hardware's TSC(no perf loss), but vcpu's TSC may lose
# sync due to hardware's unreliable/unsynced TSC between CPUs.
# default intelligently uses native TSC on machines where it is safe, but
# switches to emulated if necessary after save/restore/migration
# pvrdtscp is for intelligent apps that use special Xen-only paravirtualized
# cpuid instructions to obtain offset/scaling/migration info and maximize
# performance within pools of machines that support the rdtscp instruction
tsc_mode=0
#-----------------------------------------------------------------------------
# Qemu Monitor, default is disable
# Use ctrl-alt-2 to connect
#monitor=1
#-----------------------------------------------------------------------------
# enable sound card support, [sb16|es1370|all|..,..], default none
#soundhw='sb16'
#-----------------------------------------------------------------------------
# set the real time clock to local time [default=0 i.e. set to utc]
#localtime=1
#-----------------------------------------------------------------------------
# set the real time clock offset in seconds [default=0 i.e. same as dom0]
#rtc_timeoffset=3600
#-----------------------------------------------------------------------------
# start in full screen
#full-screen=1
#-----------------------------------------------------------------------------
# Enable USB support (specific devices specified at runtime through the
# monitor window)
#usb=1
# Enable USB mouse support (only enable one of the following, `mouse' for
# PS/2 protocol relative mouse, `tablet' for
# absolute mouse)
#usbdevice='mouse'
#usbdevice='tablet'
#-----------------------------------------------------------------------------
# Set keyboard layout, default is en-us keyboard.
#keymap='ja'
#-----------------------------------------------------------------------------
# Enable/disable xen platform PCI device, default=1 (enabled)
#xen_platform_pci=1
#-----------------------------------------------------------------------------
# Configure guest CPUID responses:
#
#cpuid=[ '1:ecx=xxxxxxxxxxx00xxxxxxxxxxxxxxxxxxx,
# eax=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ]
# - Unset the SSE4 features (CPUID.1[ECX][20-19])
# - Default behaviour for all other bits in ECX And EAX registers.
#
# Each successive character represent a lesser-significant bit:
# '1' -> force the corresponding bit to 1
# '0' -> force to 0
# 'x' -> Get a safe value (pass through and mask with the default policy)
# 'k' -> pass through the host bit value
# 's' -> as 'k' but preserve across save/restore and migration
#
# Expose to the guest multi-core cpu instead of multiple processors
# Example for intel, expose a 8-core processor :
#cpuid=['1:edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx,
# ebx=xxxxxxxx00010000xxxxxxxxxxxxxxxx',
# '4,0:eax=001111xxxxxxxxxxxxxxxxxxxxxxxxxx']
# - CPUID.1[EDX][HT] : Enable HT
# - CPUID.1[EBX] : Number of vcpus * 2
# - CPUID.4,0[EAX] : Number of vcpus * 2 - 1
#vcpus=8
#
# Example for amd, expose a 5-core processor :
# cpuid = ['1:ebx=xxxxxxxx00001010xxxxxxxxxxxxxxxx,
# edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
# '0x80000001:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x',
# '0x80000008:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx001001']
# - CPUID.1[EBX] : Threads per Core * Cores per Socket (2 * #vcpus)
# - CPUID.1[EDX][HT] : Enable HT
# - CPUID.0x80000001[CmpLegacy] : Use legacy method
# - CPUID.0x80000008[ECX] : #vcpus * 2 - 1
#vcpus=5
#
# Downgrade the cpuid to make a better compatibility for migration :
# Look like a generic 686 :
# cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
# '1:eax=0x06b1,
# ecx=xxxxxxxxxxx0000xx00xxx0000000xx0,
# edx=xxx00000xxxxxxx0xxxxxxxxx0xxxxxx',
# '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
# '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0']
# with the highest leaf
# - CPUID.0[EAX] : Set the highest leaf
# - CPUID.1[EAX] : 686
# - CPUID.1[ECX] : Mask some features
# - CPUID.1[EDX] : Mask some features
# - CPUID.4 : Reply like the highest leaf, in our case CPUID.3
# - CPUID.0x80000000 : No extension we are on a Pentium III, reply like the
# highest leaf (CPUID.3).
#
# Configure host CPUID consistency checks, which must be satisfied for this
# VM to be allowed to run on this host's processor type:
#cpuid_check=[ '1:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx1xxxxx' ]
# - Host must have VMX feature flag set
#
# The format is similar to the above for 'cpuid':
# '1' -> the bit must be '1'
# '0' -> the bit must be '0'
# 'x' -> we don't care (do not check)
# 's' -> the bit must be the same as on the host that started this VM
#-----------------------------------------------------------------------------
# Configure passthrough PCI{,-X,e} devices:
#
# pci=[ '[SSSS:]BB:DD.F[,option1[,option2[...]]]', ... ]
#
# [SSSS]:BB:DD.F "bus segment:bus:device.function"(1) of the device to
# be assigned, bus segment is optional. All fields are
# in hexadecimal and no field should be longer than that
# as shown in the pattern. Successful assignment may need
# certain hardware support and additional configurations
# (e.g. VT-d, see docs/misc/vtd.txt for more details).
#
# (1) bus segment is sometimes also referred to as the PCI "domain",
# not to be confused with Xen domain.
#
#
# optionN per-device options in "key=val" format. Current
# available options are:
# - msitranslate=0|1
# per-device overriden of pci_msitranslate, see below
# - power_mgmt=0|1
# per-device overriden of pci_power_mgmt, see below
#
#pci=[ '07:00.0', '07:00.1' ]
# MSI-INTx translation for MSI capable devices:
#
# If it's set, Xen will enable MSI for the device that supports it even
# if the guest don't use MSI. In the case, an IO-APIC type interrupt will
# be injected to the guest every time a corresponding MSI message is
# received.
# If the guest enables MSI or MSI-X, the translation is automatically
# turned off.
#
#pci_msitranslate=1
# PCI Power Management:
#
# If it's set, the guest OS will be able to program D0-D3hot states of the
# PCI device for the purpose of low power consumption.
#
#pci_power_mgmt=0
# Enable graphics passthrough:
#
# If it's set, and specify graphics device BDF in pci passthrough option,
# like pci=['xx:xx.x'], it enables graphics passthrough, default=0 (disabled)
#gfx_passthru=0
#-----------------------------------------------------------------------------
# Configure PVSCSI devices:
#
#vscsi=[ 'PDEV, VDEV' ]
#
# PDEV gives physical SCSI device to be attached to specified guest
# domain by one of the following identifier format.
# - XX:XX:XX:XX (4-tuples with decimal notation which shows
# "host:channel:target:lun")
# - /dev/sdxx or sdx
# - /dev/stxx or stx
# - /dev/sgxx or sgx
# - result of 'scsi_id -gu -s'.
# ex. # scsi_id -gu -s /block/sdb
# 36000b5d0006a0000006a0257004c0000
#
# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
# which the specified guest domain recognize.
#
#vscsi = [ '/dev/sdx, 0:0:0:0' ]
-317
View File
@@ -1,317 +0,0 @@
# -*- mode: python; -*-
#============================================================================
# Python configuration setup for 'xm create'.
# This script sets the parameters used when a domain is created using 'xm create'.
# You use a separate script for each domain you want to create, or
# you can set the parameters for the domain on the xm command line.
#============================================================================
#
# This is a version using a stubdomain for device model
# The differences with xmexample.hvm are marked with "STUBDOM"
#----------------------------------------------------------------------------
# Kernel image file.
kernel = "hvmloader"
# The domain build function. HVM domain uses 'hvm'.
builder='hvm'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 128
# Shadow pagetable memory for the domain, in MB.
# If not explicictly set, xend will pick an appropriate value.
# Should be at least 2KB per MB of domain memory, plus a few MB per vcpu.
# shadow_memory = 8
# A name for your domain. All domains must have different names.
name = "xmexample.hvm"
# 128-bit UUID for the domain. The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
#-----------------------------------------------------------------------------
# The number of cpus guest platform has, default=1
#vcpus=1
# Enable/disable HVM guest PAE, default=1 (enabled)
#pae=1
# Enable/disable HVM guest ACPI, default=1 (enabled)
#acpi=1
# Enable/disable HVM APIC mode, default=1 (enabled)
# Note that this option is ignored if vcpus > 1
#apic=1
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
#cpus = "0" # all vcpus run on CPU0
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
# type=ioemu specify the NIC is an ioemu device not netfront
vif = [ 'type=ioemu, bridge=xenbr0' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
disk = [ 'file:/var/images/min-el3-i386.img,hda,w', 'phy:/dev/cdrom,hdc:cdrom,r' ]
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
# may specify:
#
# "destroy", meaning that the domain is cleaned up as normal;
# "restart", meaning that a new domain is started in place of the old
# one;
# "preserve", meaning that no clean-up is done until the domain is
# manually destroyed (using xm destroy, for example); or
# "rename-restart", meaning that the old domain is not cleaned up, but is
# renamed and a new domain started in its place.
#
# In the event a domain stops due to a crash, you have the additional options:
#
# "coredump-destroy", meaning dump the crashed domain's core and then destroy;
# "coredump-restart', meaning dump the crashed domain's core and the restart.
#
# The default is
#
# on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# For backwards compatibility we also support the deprecated option restart
#
# restart = 'onreboot' means on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'destroy'
#
# restart = 'always' means on_poweroff = 'restart'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# restart = 'never' means on_poweroff = 'destroy'
# on_reboot = 'destroy'
# on_crash = 'destroy'
#on_poweroff = 'destroy'
#on_reboot = 'restart'
#on_crash = 'restart'
#============================================================================
# Device Model to be used
#
# STUBDOM: this is a script that creates the stub domain running the device
# model
device_model = 'stubdom-dm'
#-----------------------------------------------------------------------------
# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
# default: hard disk, cd-rom, floppy
boot="cda"
#-----------------------------------------------------------------------------
# write to temporary files instead of disk image files
#snapshot=1
#----------------------------------------------------------------------------
# enable SDL library for graphics, default = 0
#
sdl=0
#----------------------------------------------------------------------------
# enable OpenGL for texture rendering inside the SDL window, default = 1
# valid only if sdl is enabled.
#
opengl=1
#----------------------------------------------------------------------------
# enable VNC library for graphics, default = 1
vnc=1
#----------------------------------------------------------------------------
# address that should be listened on for the VNC server if vnc is set.
# default is to use 'vnc-listen' setting from
# auxbin.xen_configdir() + /xend-config.sxp
#vnclisten="127.0.0.1"
#----------------------------------------------------------------------------
# set VNC display number, default = domid
#vncdisplay=1
#----------------------------------------------------------------------------
# try to find an unused port for the VNC server, default = 1
#vncunused=1
#----------------------------------------------------------------------------
# enable spawning vncviewer for domain's console
# (only valid when vnc=1), default = 0
#vncconsole=0
#----------------------------------------------------------------------------
# set password for domain's VNC console
# default is depents on vncpasswd in xend-config.sxp
vncpasswd=''
#----------------------------------------------------------------------------
# no graphics, use serial port
#nographic=0
#----------------------------------------------------------------------------
# enable stdvga, default = 0 (use cirrus logic device model)
stdvga=0
#-----------------------------------------------------------------------------
# serial port re-direct to pty deivce, /dev/pts/n
# then xm console or minicom can connect
#
# In the stubdoms case this option adds a secondary console to the
# stubdom because there is always one for logging.
# To connect to the guest serial you can use "xm console -n 1"
# followed by the domain name of the stubdom.
#serial='pty'
#-----------------------------------------------------------------------------
# Qemu Monitor, default is disable
# Use ctrl-alt-2 to connect
#monitor=1
#-----------------------------------------------------------------------------
# enable sound card support, [sb16|es1370|all|..,..], default none
#
# STUBDOM: not supported
#soundhw='sb16'
#-----------------------------------------------------------------------------
# set the real time clock to local time [default=0 i.e. set to utc]
#localtime=1
#-----------------------------------------------------------------------------
# set the real time clock offset in seconds [default=0 i.e. same as dom0]
#rtc_timeoffset=3600
#-----------------------------------------------------------------------------
# start in full screen
#full-screen=1
#-----------------------------------------------------------------------------
# Enable USB support (specific devices specified at runtime through the
# monitor window)
#usb=1
# Enable USB mouse support (only enable one of the following, `mouse' for
# PS/2 protocol relative mouse, `tablet' for
# absolute mouse)
#usbdevice='mouse'
#usbdevice='tablet'
#-----------------------------------------------------------------------------
# Set keyboard layout, default is en-us keyboard.
#keymap='ja'
#-----------------------------------------------------------------------------
# Configure guest CPUID responses:
#
#cpuid=[ '1:ecx=xxxxxxxxxxx00xxxxxxxxxxxxxxxxxxx,
# eax=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ]
# - Unset the SSE4 features (CPUID.1[ECX][20-19])
# - Default behaviour for all other bits in ECX And EAX registers.
#
# Each successive character represent a lesser-significant bit:
# '1' -> force the corresponding bit to 1
# '0' -> force to 0
# 'x' -> Get a safe value (pass through and mask with the default policy)
# 'k' -> pass through the host bit value
# 's' -> as 'k' but preserve across save/restore and migration
#
# Expose to the guest multi-core cpu instead of multiple processors
# Example for intel, expose a 8-core processor :
#cpuid=['1:edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx,
# ebx=xxxxxxxx00010000xxxxxxxxxxxxxxxx',
# '4,0:eax=001111xxxxxxxxxxxxxxxxxxxxxxxxxx']
# - CPUID.1[EDX][HT] : Enable HT
# - CPUID.1[EBX] : Number of vcpus * 2
# - CPUID.4,0[EAX] : Number of vcpus * 2 - 1
#vcpus=8
#
# Example for amd, expose a 5-core processor :
# cpuid = ['1:ebx=xxxxxxxx00001010xxxxxxxxxxxxxxxx,
# edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
# '0x80000001:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x',
# '0x80000008:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx001001']
# - CPUID.1[EBX] : Threads per Core * Cores per Socket (2 * #vcpus)
# - CPUID.1[EDX][HT] : Enable HT
# - CPUID.0x80000001[CmpLegacy] : Use legacy method
# - CPUID.0x80000008[ECX] : #vcpus * 2 - 1
#vcpus=5
#
# Downgrade the cpuid to make a better compatibility for migration :
# Look like a generic 686 :
# cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
# '1:eax=0x06b1,
# ecx=xxxxxxxxxx0000xx00xxx0000000xx0,
# edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx',
# '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
# '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0']
# with the highest leaf
# - CPUID.0[EAX] : Set the highest leaf
# - CPUID.1[EAX] : 686
# - CPUID.1[ECX] : Mask some features
# - CPUID.1[EDX] : Mask some features
# - CPUID.4 : Reply like the highest leaf, in our case CPUID.3
# - CPUID.0x80000000 : No extension we are on a Pentium III, reply like the
# highest leaf (CPUID.3).
#
# Configure host CPUID consistency checks, which must be satisfied for this
# VM to be allowed to run on this host's processor type:
#cpuid_check=[ '1:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx1xxxxx' ]
# - Host must have VMX feature flag set
#
# The format is similar to the above for 'cpuid':
# '1' -> the bit must be '1'
# '0' -> the bit must be '0'
# 'x' -> we don't care (do not check)
# 's' -> the bit must be the same as on the host that started this VM
#-----------------------------------------------------------------------------
# Configure PVSCSI devices:
#
#vscsi=[ 'PDEV, VDEV' ]
#
# PDEV gives physical SCSI device to be attached to specified guest
# domain by one of the following identifier format.
# - XX:XX:XX:XX (4-tuples with decimal notation which shows
# "host:channel:target:lun")
# - /dev/sdxx or sdx
# - /dev/stxx or stx
# - /dev/sgxx or sgx
# - result of 'scsi_id -gu -s'.
# ex. # scsi_id -gu -s /block/sdb
# 36000b5d0006a0000006a0257004c0000
#
# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
# which the specified guest domain recognize.
#
#vscsi = [ '/dev/sdx, 0:0:0:0' ]
-26
View File
@@ -1,26 +0,0 @@
# -*- mode: python; -*-
#
# xm create configuration example.
#
# This configuration is appropriate for using Network Block Device (NBD)
# filesystems.
#
# Each of these parameters will need changing to match your setup.
#
kernel = "/boot/vmlinuz-2.6.13-15b-xen"
ramdisk = "/boot/initrd-2.6.13-15b-xen"
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 128
name = "nbd4"
vif = [ '' ]
# Please change PORT
disk = [ 'nbd:134.100.233.115 20004,hda1,w' ]
dhcp = "dhcp"
hostname= "nbd4"
root = "/dev/hda1 ro"
extra = "3"
-172
View File
@@ -1,172 +0,0 @@
# -*- mode: python; -*-
#============================================================================
# Python configuration setup for 'xm create'.
# This script sets the parameters used when a domain is created using 'xm create'.
# You use a separate script for each domain you want to create, or
# you can set the parameters for the domain on the xm command line.
#============================================================================
#----------------------------------------------------------------------------
# PV GRUB image file.
kernel = "pv-grub.gz"
# Optional provided menu.lst.
#ramdisk = "/boot/guests/menu.lst"
# Sets path to menu.lst
extra = "(hd0,0)/boot/grub/menu.lst"
# can be a TFTP-served path (DHCP will automatically be run)
# extra = "(nd)/netboot/menu.lst"
# can be configured automatically by GRUB's DHCP option 150 (see grub manual)
# extra = ""
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 128
# A name for your domain. All domains must have different names.
name = "ExampleDomain"
# 128-bit UUID for the domain. The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
#cpus = "0" # all vcpus run on CPU0
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
# Number of Virtual CPUS to use, default is 1
#vcpus = 1
#----------------------------------------------------------------------------
# Define network interfaces.
# By default, no network interfaces are configured. You may have one created
# with sensible defaults using an empty vif clause:
#
# vif = [ '' ]
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
#
# or more than one interface may be configured:
#
# vif = [ '', 'bridge=xenbr1' ]
vif = [ '' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
disk = [ 'phy:hda1,hda1,w' ]
#----------------------------------------------------------------------------
# Define frame buffer device.
#
# By default, no frame buffer device is configured.
#
# To create one using the SDL backend and sensible defaults:
#
# vfb = [ 'sdl=1' ]
#
# This uses environment variables XAUTHORITY and DISPLAY. You
# can override that:
#
# vfb = [ 'sdl=1,xauthority=/home/bozo/.Xauthority,display=:1' ]
#
# To create one using the VNC backend and sensible defaults:
#
# vfb = [ 'vnc=1' ]
#
# The backend listens on 127.0.0.1 port 5900+N by default, where N is
# the domain ID. You can override both address and N:
#
# vfb = [ 'vnc=1,vnclisten=127.0.0.1,vncdisplay=1' ]
#
# Or you can bind the first unused port above 5900:
#
# vfb = [ 'vnc=1,vnclisten=0.0.0.0,vncunused=1' ]
#
# You can override the password:
#
# vfb = [ 'vnc=1,vncpasswd=MYPASSWD' ]
#
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
# may specify:
#
# "destroy", meaning that the domain is cleaned up as normal;
# "restart", meaning that a new domain is started in place of the old
# one;
# "preserve", meaning that no clean-up is done until the domain is
# manually destroyed (using xm destroy, for example); or
# "rename-restart", meaning that the old domain is not cleaned up, but is
# renamed and a new domain started in its place.
#
# In the event a domain stops due to a crash, you have the additional options:
#
# "coredump-destroy", meaning dump the crashed domain's core and then destroy;
# "coredump-restart', meaning dump the crashed domain's core and the restart.
#
# The default is
#
# on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# For backwards compatibility we also support the deprecated option restart
#
# restart = 'onreboot' means on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'destroy'
#
# restart = 'always' means on_poweroff = 'restart'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# restart = 'never' means on_poweroff = 'destroy'
# on_reboot = 'destroy'
# on_crash = 'destroy'
#on_poweroff = 'destroy'
#on_reboot = 'restart'
#on_crash = 'restart'
#-----------------------------------------------------------------------------
# Configure PVSCSI devices:
#
#vscsi=[ 'PDEV, VDEV' ]
#
# PDEV gives physical SCSI device to be attached to specified guest
# domain by one of the following identifier format.
# - XX:XX:XX:XX (4-tuples with decimal notation which shows
# "host:channel:target:lun")
# - /dev/sdxx or sdx
# - /dev/stxx or stx
# - /dev/sgxx or sgx
# - result of 'scsi_id -gu -s'.
# ex. # scsi_id -gu -s /block/sdb
# 36000b5d0006a0000006a0257004c0000
#
# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
# which the specified guest domain recognize.
#
#vscsi = [ '/dev/sdx, 0:0:0:0' ]
#============================================================================
-197
View File
@@ -1,197 +0,0 @@
# -*- mode: python; -*-
#============================================================================
# Python configuration setup for 'xm create'.
# This script sets the parameters used when a domain is created using 'xm create'.
# You use a separate script for each domain you want to create, or
# you can set the parameters for the domain on the xm command line.
#============================================================================
#----------------------------------------------------------------------------
# Kernel image file.
kernel = "/boot/vmlinuz-2.6.10-xenU"
# Optional ramdisk.
#ramdisk = "/boot/initrd.gz"
# The domain build function. Default is 'linux'.
#builder='linux'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 64
# A name for your domain. All domains must have different names.
name = "ExampleDomain"
# 128-bit UUID for the domain. The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
#cpus = "0" # all vcpus run on CPU0
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
# Number of Virtual CPUS to use, default is 1
#vcpus = 1
#----------------------------------------------------------------------------
# Define network interfaces.
# By default, no network interfaces are configured. You may have one created
# with sensible defaults using an empty vif clause:
#
# vif = [ '' ]
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
#
# or more than one interface may be configured:
#
# vif = [ '', 'bridge=xenbr1' ]
vif = [ '' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
disk = [ 'phy:hda1,hda1,w' ]
#----------------------------------------------------------------------------
# Define frame buffer device.
#
# By default, no frame buffer device is configured.
#
# To create one using the SDL backend and sensible defaults:
#
# vfb = [ 'sdl=1' ]
#
# This uses environment variables XAUTHORITY and DISPLAY. You
# can override that:
#
# vfb = [ 'sdl=1,xauthority=/home/bozo/.Xauthority,display=:1' ]
#
# To create one using the VNC backend and sensible defaults:
#
# vfb = [ 'vnc=1' ]
#
# The backend listens on 127.0.0.1 port 5900+N by default, where N is
# the domain ID. You can override both address and N:
#
# vfb = [ 'vnc=1,vnclisten=127.0.0.1,vncdisplay=1' ]
#
# Or you can bind the first unused port above 5900:
#
# vfb = [ 'vnc=1,vnclisten=0.0.0.0,vncunused=1' ]
#
# You can override the password:
#
# vfb = [ 'vnc=1,vncpasswd=MYPASSWD' ]
#
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Set the kernel command line for the new domain.
# You only need to define the IP parameters and hostname if the domain's
# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
# You can use 'extra' to set the runlevel and custom environment
# variables used by custom rc scripts (e.g. VMID=, usr= ).
# Set if you want dhcp to allocate the IP address.
#dhcp="dhcp"
# Set netmask.
#netmask=
# Set default gateway.
#gateway=
# Set the hostname.
#hostname= "vm%d" % vmid
# Set root device.
root = "/dev/hda1 ro"
# Root device for nfs.
#root = "/dev/nfs"
# The nfs server.
#nfs_server = '192.0.2.1'
# Root directory on the nfs server.
#nfs_root = '/full/path/to/root/directory'
# Sets runlevel 4.
extra = "4"
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
# may specify:
#
# "destroy", meaning that the domain is cleaned up as normal;
# "restart", meaning that a new domain is started in place of the old
# one;
# "preserve", meaning that no clean-up is done until the domain is
# manually destroyed (using xm destroy, for example); or
# "rename-restart", meaning that the old domain is not cleaned up, but is
# renamed and a new domain started in its place.
#
# In the event a domain stops due to a crash, you have the additional options:
#
# "coredump-destroy", meaning dump the crashed domain's core and then destroy;
# "coredump-restart', meaning dump the crashed domain's core and the restart.
#
# The default is
#
# on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# For backwards compatibility we also support the deprecated option restart
#
# restart = 'onreboot' means on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'destroy'
#
# restart = 'always' means on_poweroff = 'restart'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# restart = 'never' means on_poweroff = 'destroy'
# on_reboot = 'destroy'
# on_crash = 'destroy'
#on_poweroff = 'destroy'
#on_reboot = 'restart'
#on_crash = 'restart'
#-----------------------------------------------------------------------------
# Configure PVSCSI devices:
#
#vscsi=[ 'PDEV, VDEV' ]
#
# PDEV gives physical SCSI device to be attached to specified guest
# domain by one of the following identifier format.
# - XX:XX:XX:XX (4-tuples with decimal notation which shows
# "host:channel:target:lun")
# - /dev/sdxx or sdx
# - /dev/stxx or stx
# - /dev/sgxx or sgx
# - result of 'scsi_id -gu -s'.
# ex. # scsi_id -gu -s /block/sdb
# 36000b5d0006a0000006a0257004c0000
#
# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
# which the specified guest domain recognize.
#
#vscsi = [ '/dev/sdx, 0:0:0:0' ]
#============================================================================
-232
View File
@@ -1,232 +0,0 @@
# -*- mode: python; -*-
#============================================================================
# Example Python setup script for 'xm create'.
# This script sets the parameters used when a domain is created using 'xm create'.
#
# This is a relatively advanced script that uses a parameter, vmid, to control
# the settings. So this script can be used to start a set of domains by
# setting the vmid parameter on the 'xm create' command line. For example:
#
# xm create vmid=1
# xm create vmid=2
# xm create vmid=3
#
# The vmid is purely a script variable, and has no effect on the the domain
# id assigned to the new domain.
#============================================================================
# Define script variables here.
# xm_vars is defined automatically, use xm_vars.var() to define a variable.
# This function checks that 'vmid' has been given a valid value.
# It is called automatically by 'xm create'.
def vmid_check(var, val):
val = int(val)
if val <= 0:
raise ValueError
return val
# Define the 'vmid' variable so that 'xm create' knows about it.
xm_vars.var('vmid',
use="Virtual machine id. Integer greater than 0.",
check=vmid_check)
# Check the defined variables have valid values..
xm_vars.check()
#----------------------------------------------------------------------------
# Kernel image file.
kernel = "/boot/vmlinuz-2.6.10-xenU"
# Optional ramdisk.
#ramdisk = "/boot/initrd.gz"
# The domain build function. Default is 'linux'.
#builder='linux'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 64
# A name for the new domain. All domains have to have different names,
# so we use the vmid to create a name.
name = "VM%d" % vmid
# 128-bit UUID for the domain. The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
#cpus = "0" # all vcpus run on CPU0
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
#cpus = "%s" % vmid # set based on vmid (mod number of CPUs)
# Number of Virtual CPUS to use, default is 1
#vcpus = 1
vcpus = 4 # make your domain a 4-way
#----------------------------------------------------------------------------
# Define network interfaces.
# By default, no network interfaces are configured. You may have one created
# with sensible defaults using an empty vif clause:
#
# vif = [ '' ]
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
#
# or more than one interface may be configured:
#
# vif = [ '', 'bridge=xenbr1' ]
vif = [ '' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
# This makes the disk device depend on the vmid - assuming
# that devices sda7, sda8 etc. exist. The device is exported
# to all domains as sda1.
# All domains get sda6 read-only (to use for /usr, see below).
disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
'phy:sda6,sda6,r' ]
#----------------------------------------------------------------------------
# Define frame buffer device.
#
# By default, no frame buffer device is configured.
#
# To create one using the SDL backend and sensible defaults:
#
# vfb = [ 'sdl=1' ]
#
# This uses environment variables XAUTHORITY and DISPLAY. You
# can override that:
#
# vfb = [ 'sdl=1,xauthority=/home/bozo/.Xauthority,display=:1' ]
#
# To create one using the VNC backend and sensible defaults:
#
# vfb = [ 'vnc=1' ]
#
# The backend listens on 127.0.0.1 port 5900+N by default, where N is
# the domain ID. You can override both address and N:
#
# vfb = [ 'vnc=1,vnclisten=127.0.0.1,vncdisplay=%d' % vmid ]
#
# Or you can bind the first unused port above 5900:
#
# vfb = [ 'vnc=1,vnclisten=0.0.0.0,vncunused=1' ]
#
# You can override the password:
#
# vfb = [ 'vnc=1,vncpasswd=MYPASSWD' ]
#
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Set the kernel command line for the new domain.
# You only need to define the IP parameters and hostname if the domain's
# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
# You can use 'extra' to set the runlevel and custom environment
# variables used by custom rc scripts (e.g. VMID=, usr= ).
# Set if you want dhcp to allocate the IP address.
#dhcp="dhcp"
# Set netmask.
#netmask=
# Set default gateway.
#gateway=
# Set the hostname.
#hostname= "vm%d" % vmid
# Set root device.
root = "/dev/sda1 ro"
# Root device for nfs.
#root = "/dev/nfs"
# The nfs server.
#nfs_server = '192.0.2.1'
# Root directory on the nfs server.
#nfs_root = '/full/path/to/root/directory'
# Sets runlevel 4 and the device for /usr.
extra = "4 VMID=%d usr=/dev/sda6" % vmid
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
# may specify:
#
# "destroy", meaning that the domain is cleaned up as normal;
# "restart", meaning that a new domain is started in place of the old
# one;
# "preserve", meaning that no clean-up is done until the domain is
# manually destroyed (using xm destroy, for example); or
# "rename-restart", meaning that the old domain is not cleaned up, but is
# renamed and a new domain started in its place.
#
# In the event a domain stops due to a crash, you have the additional options:
#
# "coredump-destroy", meaning dump the crashed domain's core and then destroy;
# "coredump-restart', meaning dump the crashed domain's core and the restart.
#
# The default is
#
# on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# For backwards compatibility we also support the deprecated option restart
#
# restart = 'onreboot' means on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'destroy'
#
# restart = 'always' means on_poweroff = 'restart'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# restart = 'never' means on_poweroff = 'destroy'
# on_reboot = 'destroy'
# on_crash = 'destroy'
#on_poweroff = 'destroy'
#on_reboot = 'restart'
#on_crash = 'restart'
#-----------------------------------------------------------------------------
# Configure PVSCSI devices:
#
#vscsi=[ 'PDEV, VDEV' ]
#
# PDEV gives physical SCSI device to be attached to specified guest
# domain by one of the following identifier format.
# - XX:XX:XX:XX (4-tuples with decimal notation which shows
# "host:channel:target:lun")
# - /dev/sdxx or sdx
# - /dev/stxx or stx
# - /dev/sgxx or sgx
# - result of 'scsi_id -gu -s'.
# ex. # scsi_id -gu -s /block/sdb
# 36000b5d0006a0000006a0257004c0000
#
# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
# which the specified guest domain recognize.
#
#vscsi = [ '/dev/sdx, 0:0:0:0' ]
#============================================================================
-218
View File
@@ -1,218 +0,0 @@
# -*- mode: python; -*-
#============================================================================
# Example Python setup script for 'xm create'.
# This script sets the parameters used when a domain is created using 'xm create'.
#
# This is a relatively advanced script that uses a parameter, vmid, to control
# the settings. So this script can be used to start a set of domains by
# setting the vmid parameter on the 'xm create' command line. For example:
#
# xm create vmid=1
# xm create vmid=2
# xm create vmid=3
#
# The vmid is purely a script variable, and has no effect on the the domain
# id assigned to the new domain.
#============================================================================
# Define script variables here.
# xm_vars is defined automatically, use xm_vars.var() to define a variable.
# This function checks that 'vmid' has been given a valid value.
# It is called automatically by 'xm create'.
def vmid_check(var, val):
val = int(val)
if val <= 0:
raise ValueError
return val
# Define the 'vmid' variable so that 'xm create' knows about it.
xm_vars.var('vmid',
use="Virtual machine id. Integer greater than 0.",
check=vmid_check)
# Check the defined variables have valid values..
xm_vars.check()
#----------------------------------------------------------------------------
# Kernel image file.
kernel = "/path/to/domU/kernel"
# Optional ramdisk.
#ramdisk = "/boot/initrd.gz"
# The domain build function. Default is 'linux'.
#builder='linux'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 64
# A name for the new domain. All domains have to have different names,
# so we use the vmid to create a name.
name = "VM%d" % vmid
# 128-bit UUID for the domain. The default behavior is to generate a new UUID
# on each call to 'xm create'.
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
#cpus = "0" # all vcpus run on CPU0
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
cpus = "%s" % vmid # set based on vmid (mod number of CPUs)
#----------------------------------------------------------------------------
# Define network interfaces.
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
vif = [ 'ip=192.168.%d.1/24' % (vmid)]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
# what you want them accessible as.
# Each disk entry is of the form phy:UNAME,DEV,MODE
# where UNAME is the device, DEV is the device name the domain will see,
# and MODE is r for read-only, w for read-write.
# This makes the disk device depend on the vmid - assuming
# tHat devices sda7, sda8 etc. exist. The device is exported
# to all domains as sda1.
# All domains get sda6 read-only (to use for /usr, see below).
disk = [ 'phy:hda%d,hda1,w' % (vmid)]
#----------------------------------------------------------------------------
# Define frame buffer device.
#
# By default, no frame buffer device is configured.
#
# To create one using the SDL backend and sensible defaults:
#
# vfb = [ 'sdl=1' ]
#
# This uses environment variables XAUTHORITY and DISPLAY. You
# can override that:
#
# vfb = [ 'sdl=1,xauthority=/home/bozo/.Xauthority,display=:1' ]
#
# To create one using the VNC backend and sensible defaults:
#
# vfb = [ 'vnc=1' ]
#
# The backend listens on 127.0.0.1 port 5900+N by default, where N is
# the domain ID. You can override both address and N:
#
# vfb = [ 'vnc=1,vnclisten=127.0.0.1,vncdisplay=%d' % vmid ]
#
# Or you can bind the first unused port above 5900:
#
# vfb = [ 'vnc=1,vnclisten=0.0.0.0,vncunused=1' ]
#
# You can override the password:
#
# vfb = [ 'vnc=1,vncpasswd=MYPASSWD' ]
#
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Set the kernel command line for the new domain.
# You only need to define the IP parameters and hostname if the domain's
# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
# You can use 'extra' to set the runlevel and custom environment
# variables used by custom rc scripts (e.g. VMID=, usr= ).
# Set if you want dhcp to allocate the IP address.
dhcp="off"
ip="192.168.%d.2" % (vmid)
# Set netmask.
netmask="255.255.255.0"
# Set default gateway.
gateway="192.168.%d.1" % (vmid)
# Set the hostname.
hostname= "domain-%d.xeno" % vmid
# Set root device.
root = "/dev/hda1 ro"
# Root device for nfs.
#root = "/dev/nfs"
# The nfs server.
#nfs_server = "10.212.4.103"
# Root directory on the nfs server.
#nfs_root = "/path/to/root/filesystem"
# Sets runlevel 4 and the device for /usr.
extra = "4 VMID=%d" % vmid
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
# may specify:
#
# "destroy", meaning that the domain is cleaned up as normal;
# "restart", meaning that a new domain is started in place of the old
# one;
# "preserve", meaning that no clean-up is done until the domain is
# manually destroyed (using xm destroy, for example); or
# "rename-restart", meaning that the old domain is not cleaned up, but is
# renamed and a new domain started in its place.
#
# In the event a domain stops due to a crash, you have the additional options:
#
# "coredump-destroy", meaning dump the crashed domain's core and then destroy;
# "coredump-restart', meaning dump the crashed domain's core and the restart.
#
# The default is
#
# on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# For backwards compatibility we also support the deprecated option restart
#
# restart = 'onreboot' means on_poweroff = 'destroy'
# on_reboot = 'restart'
# on_crash = 'destroy'
#
# restart = 'always' means on_poweroff = 'restart'
# on_reboot = 'restart'
# on_crash = 'restart'
#
# restart = 'never' means on_poweroff = 'destroy'
# on_reboot = 'destroy'
# on_crash = 'destroy'
#on_poweroff = 'destroy'
#on_reboot = 'restart'
#on_crash = 'restart'
#-----------------------------------------------------------------------------
# Configure PVSCSI devices:
#
#vscsi=[ 'PDEV, VDEV' ]
#
# PDEV gives physical SCSI device to be attached to specified guest
# domain by one of the following identifier format.
# - XX:XX:XX:XX (4-tuples with decimal notation which shows
# "host:channel:target:lun")
# - /dev/sdxx or sdx
# - /dev/stxx or stx
# - /dev/sgxx or sgx
# - result of 'scsi_id -gu -s'.
# ex. # scsi_id -gu -s /block/sdb
# 36000b5d0006a0000006a0257004c0000
#
# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
# which the specified guest domain recognize.
#
#vscsi = [ '/dev/sdx, 0:0:0:0' ]
#============================================================================
-5
View File
@@ -2,7 +2,6 @@ XEN_ROOT = $(CURDIR)/../../..
include $(XEN_ROOT)/tools/Rules.mk
# Init scripts.
XEND_INITD = init.d/xend
XENDOMAINS_INITD = init.d/xendomains
XENDOMAINS_SYSCONFIG = init.d/sysconfig.xendomains
@@ -30,7 +29,6 @@ XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
XEN_SCRIPT_DATA += block-common.sh
UDEV_RULES_DIR = $(CONFIG_DIR)/udev
UDEV_RULES-$(CONFIG_XEND) = xend.rules
UDEV_RULES = xen-backend.rules $(UDEV_RULES-y)
.PHONY: all
@@ -47,9 +45,6 @@ install: all install-initd install-scripts install-udev
install-initd:
[ -d $(DESTDIR)$(INITD_DIR) ] || $(INSTALL_DIR) $(DESTDIR)$(INITD_DIR)
[ -d $(DESTDIR)$(SYSCONFIG_DIR) ] || $(INSTALL_DIR) $(DESTDIR)$(SYSCONFIG_DIR)
ifeq ($(CONFIG_XEND),y)
$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)$(INITD_DIR)
endif
$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)$(INITD_DIR)
$(INSTALL_DATA) $(XENDOMAINS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xendomains
$(INSTALL_PROG) $(XENCOMMONS_INITD) $(DESTDIR)$(INITD_DIR)
-82
View File
@@ -1,82 +0,0 @@
#!/bin/bash
#
# xend Script to start and stop the Xen control daemon.
#
# Author: Keir Fraser <keir.fraser@cl.cam.ac.uk>
#
# chkconfig: 2345 98 01
# description: Starts and stops the Xen control daemon.
### BEGIN INIT INFO
# Provides: xend
# Required-Start: $syslog $remote_fs xenstored xenconsoled
# Should-Start:
# Required-Stop: $syslog $remote_fs xenstored xenconsoled
# Should-Stop:
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop xend
# Description: Starts and stops the Xen control daemon.
### END INIT INFO
. /etc/xen/scripts/hotplugpath.sh
shopt -s extglob
# Wait for Xend to be up
function await_daemons_up
{
i=1
rets=10
${SBINDIR}/xend status
while [ $? -ne 0 -a $i -lt $rets ]; do
sleep 1
echo -n .
i=$(($i + 1))
${SBINDIR}/xend status
done
}
case "$1" in
start)
echo "WARNING: Enabling the xend toolstack."
echo "xend is deprecated and scheduled for removal. Please migrate"
echo "to another toolstack ASAP."
if [ -z "`ps -C xenconsoled -o pid=`" ]; then
echo "xencommons should be started first."
exit 1
fi
# mkdir shouldn't be needed as most distros have this already created. Default to using subsys.
# See docs/misc/distro_mapping.txt
mkdir -p /var/lock
if [ -d /var/lock/subsys ] ; then
touch /var/lock/subsys/xend
else
touch /var/lock/xend
fi
${SBINDIR}/xend start
await_daemons_up
;;
stop)
${SBINDIR}/xend stop
rm -f /var/lock/subsys/xend /var/lock/xend
;;
status)
${SBINDIR}/xend status
;;
reload)
${SBINDIR}/xend reload
;;
restart|force-reload)
${SBINDIR}/xend restart
await_daemons_up
;;
*)
# do not advertise unreasonable commands that there is no reason
# to use with this device
echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
exit 1
esac
exit $?
-4
View File
@@ -1,4 +0,0 @@
SUBSYSTEM=="pci", RUN+="socket:/org/xen/xend/udev_event"
SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event"
SUBSYSTEM=="usb", RUN+="socket:/org/xen/xend/udev_event"
#SUBSYSTEM=="net", KERNEL!="vif[0-9]*.[0-9]*|tap[0-9]*.[0-9]*", RUN+="socket:/org/xen/xend/udev_event"
+1 -2
View File
@@ -8,8 +8,7 @@ XEN_SCRIPTS += vif-bridge
XEN_SCRIPTS += vif-ip
XEN_SCRIPT_DATA =
XEN_RCD_PROG-$(CONFIG_XEND) = rc.d/xend
XEN_RCD_PROG = rc.d/xencommons $(XEN_RCD_PROG-y) rc.d/xendomains rc.d/xen-watchdog
XEN_RCD_PROG = rc.d/xencommons rc.d/xendomains rc.d/xen-watchdog
.PHONY: all
all:
-71
View File
@@ -1,71 +0,0 @@
#!/bin/sh
#
# PROVIDE: xend
# REQUIRE: xencommons
. /etc/rc.subr
DIR=$(dirname "$0")
. "${DIR}/xen-hotplugpath.sh"
LD_LIBRARY_PATH="${LIBDIR}"
export LD_LIBRARY_PATH PYTHONPATH
PATH="${PATH}:${SBINDIR}"
export PATH
name="xend"
rcvar=$name
start_precmd="xend_precmd"
start_cmd="xend_startcmd"
stop_cmd="xend_stop"
status_cmd="xend_status"
extra_commands="status"
required_files="/kern/xen/privcmd"
XENBACKENDD_PIDFILE="/var/run/xenbackendd.pid"
#XENBACKENDD_DEBUG=1
xend_precmd()
{
mkdir -p /var/run/xend || exit 1
mkdir -p /var/run/xend/boot || exit 1
}
xend_startcmd()
{
printf "Starting xenbackendd.\n"
XENBACKENDD_ARGS=""
if [ -n "${XENBACKENDD_DEBUG}" ]; then
XENBACKENDD_ARGS="${XENBACKENDD_ARGS} -d"
fi
${SBINDIR}/xenbackendd ${XENBACKENDD_ARGS}
printf "Starting xend.\n"
${SBINDIR}/xend start >/dev/null 2>&1
}
xend_stop()
{
printf "Stopping xenbackendd, xend\n"
xb_pid=$(check_pidfile ${XENBACKENDD_PIDFILE} ${SBINDIR}/xenbackendd)
if test -n "$xb_pid";
then
kill -${sig_stop:-TERM} $xb_pid
fi
while pgrep -f ${SBINDIR}/xend >/dev/null 2>&1; do
pkill -${sig_stop:-KILL} -f ${SBINDIR}/xend
done
wait_for_pids $xb_pid
rm -f /var/lock/subsys/xend /var/lock/xend /var/run/xenbackendd.pid
}
xend_status()
{
${SBINDIR}/xend status
}
load_rc_config $name
run_rc_command "$1"
-16
View File
@@ -33,8 +33,6 @@
#include "libxlutil.h"
#include "xl.h"
#define XEND_LOCK { "/var/lock/subsys/xend", "/var/lock/xend" }
xentoollog_logger_stdiostream *logger;
int dryrun_only;
int force_execution;
@@ -299,7 +297,6 @@ int main(int argc, char **argv)
int ret;
void *config_data = 0;
int config_len = 0;
const char *locks[] = XEND_LOCK;
while ((opt = getopt(argc, argv, "+vftN")) >= 0) {
switch (opt) {
@@ -357,19 +354,6 @@ int main(int argc, char **argv)
ret = 1;
goto xit;
}
if (cspec->modifies && !dryrun_only) {
for (int i = 0; i < sizeof(locks)/sizeof(locks[0]); i++) {
if (!access(locks[i], F_OK) && !force_execution) {
fprintf(stderr,
"xend is running, which may cause unpredictable results when using\n"
"this xl command. Please shut down xend before continuing.\n\n"
"(This check can be overridden with the -f option.)\n"
);
ret = 1;
goto xit;
}
}
}
ret = cspec->cmd_impl(argc, argv);
} else if (!strcmp(cmd, "help")) {
help(argv[1]);
+3 -15
View File
@@ -16,26 +16,14 @@ build: genpath genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \
$(XEN_ROOT)/tools/libxl/libxl_types.idl \
xen/lowlevel/xl/_pyxl_types.h \
xen/lowlevel/xl/_pyxl_types.c
CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py build --xend=$(CONFIG_XEND)
CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py build
.PHONY: install
install: install-dtd
install:
CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py install \
$(PYTHON_PREFIX_ARG) --root="$(DESTDIR)" --force --xend=$(CONFIG_XEND)
$(PYTHON_PREFIX_ARG) --root="$(DESTDIR)" --force
$(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
ifeq ($(CONFIG_XEND),y)
$(INSTALL_PYTHON_PROG) xen/xm/xm $(DESTDIR)$(SBINDIR)/xm
$(INSTALL_PYTHON_PROG) xen/xend/xend $(DESTDIR)$(SBINDIR)/xend
endif
install-dtd: all
ifeq ($(CONFIG_XEND),y)
$(INSTALL_DIR) $(DESTDIR)$(SHAREDIR)/xen
$(INSTALL_DATA) xen/xm/create.dtd $(DESTDIR)$(SHAREDIR)/xen
else
:
endif
.PHONY: test
test:
@@ -1,25 +0,0 @@
Metadata-Version: 1.0
Name: logging
Version: 0.4.9.2
Summary: A logging module for Python
Home-page: http://www.red-dove.com/python_logging.html
Author: Vinay Sajip
Author-email: vinay_sajip@red-dove.com
License: Copyright (C) 2001-2004 by Vinay Sajip. All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Vinay Sajip
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Description: This module is intended to provide a standard error logging mechanism in Python as per PEP 282.
Platform: UNKNOWN
@@ -1,311 +0,0 @@
This module is intended to provide error logging functionality for Python
programs. It aims to be aligned with Python Enhancement Proposal (PEP) 282.
For more information on the package itself, see python_logging.html. In it,
there is a description of each file in the distribution.
You can also use pydoc to browse the interfaces.
Change History
--------------
Version Date Description
=============================================================================
0.4.9.2 28 Feb 2004 Traceback text is now cached.
Tracebacks can be propagated across sockets as text.
Added makeLogRecord() to allow a LogRecord to be
created from a dictionary.
Closing a handler now removes it from the internal list
used by shutdown().
Made close() call flush() for handlers where this makes
sense (thanks to Jim Jewett).
The exc_info keyword parameter can be used to pass an
exception tuple as well as a flag indicating that the
current exception should be logged.
A shutdown hook is registered to call shutdown() on
application (Python) exit (thanks to Jim Jewett).
Removed redundant error check in setLoggerClass().
Added RESET_ERROR to logging.config.
SocketHandler now uses an exponential backoff strategy
(thanks to Robert Olson).
Minor documentation corrections.
-----------------------------------------------------------------------------
0.4.8 22 Apr 2003 Made _listener global in stopListening().
Made listen() correctly pass the specified port.
Removed some redundant imports in __init__.py.
Added the record being processed as a parameter to
handleError (thanks to Gordon den Otter for the idea).
Handler.handle returns the result of applying the
filter to the record (thanks to Gordon den Otter for
the idea).
Added a seek(0, 2) in RotatingFileHandler before the
tell() call. This is because under Windows, tell()
returns 0 until the first actual write (thanks to
Gordon den Otter for the patch).
Altered findCaller to not use inspect (thanks to
Jeremy Hylton for the patch).
Renamed warn and WARN to warning and WARNING. This may
break existing code, but the standard Python module
will use warning/WARNING rather than warn/WARN. The
fatal and FATAL synonyms for critical and CRITICAL
have also been removed.
Added defaultEncoding and some support for encoding
Unicode messages (thanks to Stéphane Bidoul for the
suggestion).
Added process ID to the list of LogRecord attributes.
Modified Logger.removeHandler so that it does not
close the handler on removal.
Modified SMTPHandler to treat a single "to address"
correctly (thanks to Anthony Baxter).
Modified SMTPHandler to add a date header to the SMTP
message (thanks to David Driver for the suggestion).
Modified HTTPHandler to factor out the mapping of
a LogRecord to a dictionary (thanks to Franz Glasner
for the patch).
-----------------------------------------------------------------------------
0.4.7 15 Nov 2002 Made into a package with three modules: __init__ (the
core code), handlers (all handlers other than
FileHandler and its bases) and config (all the config
stuff). Before doing this:
Updated docstrings to include a short line, then a
blank line, then more descriptive text.
Renamed 'lvl' to 'level' in various functions.
Changed FileHandler to use "a" and "w" instead of "a+"
and "w+".
Moved log file rotation functionality from FileHandler
to a new class RotatingFileHandler.
Improved docstring describing rollover.
Updated makePickle to use 4-byte length and struct
module, likewise logrecv.py. Also updated on-the-fly
config reader to use 4-byte length/struct module.
Altered ConfigParser test to look at 'readline' rather
than 'read'.
Added optional "defaults" argument to fileConfig, to
be passed to ConfigParser.
Renamed ALL to NOTSET to avoid confusion.
Commented out getRootLogger(), as obsolete.
To do regression testing, run log_test.py and compare
the created files stdout.log and stderr.log against
the files stdout.exp and stderr.exp. They should match
except fir a couple of exception messages which give
absolute file paths.
Updated python_logging.html to remove links to
logging_pydoc.html, which has been removed from the
distribution.
Changed default for raiseExceptions to 1.
-----------------------------------------------------------------------------
0.4.6 08 Jul 2002 Added raiseExceptions to allow conditional propagation
of exceptions which occur during handling.
Added converter to Formatter to allow use of any
function to convert time from seconds to a tuple. It
still defaults to time.localtime but now you can also
use time.gmtime.
Added log_test22.py to test the conversion feature.
Changed rootlogger default level to WARN - was DEBUG.
Updated some docstrings.
Moved import of threading to where thread is imported.
If either is unavailable, threading support is off.
Updated minor defects in python_logging.html.
Check to see if ConfigParser has readfp method; if it
does and an object with a 'read' method is passed in,
assumes a file-like object and uses readfp to read it
in.
-----------------------------------------------------------------------------
0.4.5 04 Jun 2002 Fixed bug which caused problem if no args to message
(suggested by Hye-Shik Chang).
Fixed bug in _fixupParents (thanks to Nicholas Veeser)
and added log_test19.py as a test case for this bug.
Added getMessage to LogRecord (code was moved here from
Formatter.format)
Applied str() to record.msg to allow arbitrary classes
to determine the formatting (as msg can now be a class
instance).
Table of Contents added to python_logging.html, the
section on Loggers updated, and the logconf.ini file
section annotated.
Added log_test20.py which demonstrates how to use
class instances to provide alternatives to numeric
severities as mechanisms for control of logging.
Added log_test21.py which builds on log_test20.py to
show how you can use a regular expression-based Filter
for flexible matching similar to e.g. Protomatter
Syslog, where you can filter on e.g. "a.*" or "*.b" or
"a.*.c".
_levelNames changed to contain reverse mappings as well
as forward mappings (leveltext->level as well as level
-> leveltext). The reverse mappings are used by
fileConfig().
fileConfig() now more forgiving of missing options in
.ini file - sensible defaults now used when some
options are absent. Also, eval() is used less when
interpreting .ini file contents - int() and dict lookup
are used in more places.
-----------------------------------------------------------------------------
0.4.4 02 May 2002 getEffectiveLevel() returns ALL instead of None when
nothing found. Modified references to level=0 to
level=ALL in a couple of places.
SocketHandler now inherits from Handler (it used to
inherit from StreamHandler, for no good reason).
getLock() renamed to createLock().
Docstring tidy-ups, and some tidying up of
DatagramHandler.
Factored out unpickling in logrecv.py.
Added log_test18.py to illustrate MatchFilter, which is
a general matching filter.
Improved FileHandler.doRollover() so that the base
file name is always the most recent, then .1, then .2
etc. up to the maximum backup count. Renamed formal
args and attributes used in rollover.
Changed LogRecord attributes lvl -> levelno, level ->
levelname (less ambiguity)
Formatter.format searches for "%(asctime)" rather than
"(asctime)"
Renamed _start_time to _startTime
Formatter.formatTime now returns the time
Altered logrecv.py to support stopping servers
programmatically
Added log_test.py as overall test harness
basicConfig() can now be safely called more than once
Modified test scripts to make it easier to call them
from log_test.py
Moved SOAPHandler from core to log_test13.py. It's not
general enough to be in the core; most production use
will have differing RPC signatures.
-----------------------------------------------------------------------------
0.4.3 14 Apr 2002 Bug fix one-off error message to go to sys.stderr
rather than sys.stdout.
logrecv.py fix TCP for busy network.
Thread safety - added locking to Handler and for shared
data in module, and log_test16.py to test it.
Added socket listener to allow on-the-fly configuration
and added log_test17.py to test it.
-----------------------------------------------------------------------------
0.4.2 11 Apr 2002 Bug fix fileConfig() - setup of MemoryHandler target
and errors when loggers have no handlers set or
handlers have no formatters set
logconf.py - seems to hang if window closed when combo
dropdown is showing - added code to close popup on exit
Some tweaks to _srcfile computation (normpath added)
findCaller() optimized, now a lot faster!
Logger.removeHandler now closes the handler before
removing it
fileConfig() removes existing handlers before adding
the new set, to avoid memory leakage when repeated
calls are made
Fixed logrecv.py bug which hogged CPU time when TCP
connection was closed from the client
Added log_test14.py to demonstrate/test a DBHandler
which writes logging records into an RDBMS using the
Python Database API 2.0 (to run, you need something
which supports this already installed - I tested with
mxODBC)
Made getLogger name argument optional - returns root
logger if omitted
Altered Filter to take a string initializer, filtering
a sub-hierarchy rooted at a particular point (idea from
Denis S. Otkidach).
Added log_test15.py to test Filter initializer
Minor docstring changes
-----------------------------------------------------------------------------
0.4.1 03 Apr 2002 Bug fix SMTPHandler - extra \r\n needed (Oleg Orlov)
Added BufferingHandler, BufferingFormatter
Renamed getChainedPriority to getEffectiveLevel
Removed Logger.getRoot as it is redundant
Added log_test9.py to test Buffering classes and
to show an XMLFormatter example.
Added setLoggerClass.
Added log_test10.py to test setLoggerClass, using an
example Logger-derived class which outputs exception
info even for DEBUG level logging calls
Added log_test11.py to test a buffering implementation
of SMTPHandler
Changed logging call implementation to allow keyword
arguments (Kevin Butler and others)
Changed default SysLogHandler implementation.
Renamed "additive" to "propagate" as it better
describes the attribute.
Added HTTPHandler.
Modified logrecv.py to remove "both" option and to add
"HTTP" and "SOAP" options (SOAP option needs you to
have PyXML-0.6.6 and ZSI installed - for logrecv.py
only, and not for the core logging module itself).
Added log_test12.py to test HTTPHandler.
Added log_test13.py to test SOAPHandler.
Formatted to Python source guidelines (spaces, indent
of 4, within 80 columns).
More method renamings (result of feedback) - _handle()
renamed to emit(), _logRecord() renamed to handle().
Renamed FATAL to CRITICAL (David Goodger), but left
fatal() and FATAL in (until PEP is changed)
Changed configuration file format to ConfigParser
format.
Factored filter application functionality out to a new
Filterer class. The isLoggable() method is renamed to
filter() in both Filter and Filterer classes.
Altered SMTPHandler __init__ to accept (host, port)
for the mail internet address.
Added GUI configurator which uses Tkinter and the new
configuration file format. (See logconf.py and an
example configuration file in logconf.ini)
Altered log_test3.py to test with the new file format.
-----------------------------------------------------------------------------
0.4 21 Mar 2002 Incorporated comments/patches from Ollie Rutherfurd:
-Added level filtering for handlers.
-Return root logger if no name specified in getLogger.
Incorporated comments from Greg Ward:
-Added distutils setup.py script.
Added formatter initialization in Handler.__init__.
Tidied up docstrings.
Added removeHandler to Logger.
Added removeFilter to Logger and Handler.
logrecv.py modified to keep connection alive until
client closes it.
SocketHandler modified to not reset connection after
each logging event.
Added shutdown function which closes open sockets
Renamed DEFAULT_LOGGING_PORT->DEFAULT_TCP_LOGGING_PORT
Added DEFAULT_UDP_LOGGING_PORT
Added log_test4.py (example of arbitrary levels)
Added addLevelName, changed behaviour of getLevelName
Fixed bugs in DatagramHandler
Added SMTPHandler implementation
Added log_test5.py to test SMTPHandler
Added SysLogHandler (contribution from Nicolas Untz
based on Sam Rushing's syslog.py)
Modified log_test1.py to add a SysLogHandler
Added rollover functionality to FileHandler
Added NTEventLogHandler (based on Win32 extensions)
Added MemoryHandler implementation
Added log_test7.py to test MemoryHandler
Added log_test8.py to test FileHandler rollover
Added logException method to Logger
Added formatException method to Formatter
Added log_test6.py to test NTEventHandler and
logException
Numerous internal method renamings (sorry - but better
to do this now, rather than when we enter beta status).
-----------------------------------------------------------------------------
0.3 14 Mar 2002 First public release, for early feedback
-----------------------------------------------------------------------------
0.2 Consolidated into single file (for internal use only)
-----------------------------------------------------------------------------
0.1 Initial implementation (for internal use only)
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
COPYRIGHT
-----------------------------------------------------------------------------
Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Vinay Sajip
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -1,32 +0,0 @@
BODY, P, UL, OL {font-family: Verdana, Arial, Helvetica, Geneva, sans-serif ; background: white; color: black; font-size: 10pt; }
CODE {font-family: "Courier New", Courier, Monaco, monospace ; }
PRE {font-family: "Courier New", Courier, Monaco, monospace ; }
.program { color: navy; font-family: "Courier New", Courier, Monaco, monospace }
.output { color: maroon }
HR {color: gray ; }
.navbar { font-family: Verdana, Arial, Helvetica, Geneva, sans-serif; background: #FFFF66 ; border-style: none none solid none; border-width: thin; padding: 2px;}
.navarea { background: #FFFF66 ; }
TR { font-size: 10pt }
.red { color: #FF0000 }
.maroon { color: #800000 }
.comment { color: green }
.optional { color: silver }
.strong { font-weight: bold }
TR.tblheading { background: silver ; }
.notrecommended {color: #666666 ; }
.deemphasized {color: #666666 ; }
TABLE.densetable {font-size: 80% ; }
TH { text-align: left; background: silver }
TR.summaryrow { font-size: 90%; background: #00FFFF ; }
CAPTION {font-size: 100% ; }
.embeddedfloat {float: right; margin-left: 3em}
.bigtd { font-size: 18pt }
TD, .normaltd { vertical-align: top; background: #EEEEEE; font-family: Verdana, Arial, Helvetica, Geneva, sans-serif; font-size: 10pt }
H1, H2, H3, H4, H5, H6 {font-family: Verdana, Arial, Helvetica, Geneva, sans-serif ; }
H4 {margin-bottom: 0.5em }
H5, H6 {margin-bottom: 0.1em }
A:link {color: blue ; }
A:visited {color: purple ; }
A:active {color: red ; }
A { font-family: Verdana, Arial, Helvetica, Geneva, sans-serif; font-size: 10pt }
.warning { color: red }
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,301 +0,0 @@
# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
Configuration functions for the logging package for Python. The core package
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
by Apache's log4j system.
Should work under Python versions >= 1.5.2, except that source line
information is not available unless 'sys._getframe()' is.
Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging' and log away!
"""
import sys, logging, logging.handlers, string, thread, threading, socket, struct, os
from SocketServer import ThreadingTCPServer, StreamRequestHandler
DEFAULT_LOGGING_CONFIG_PORT = 9030
if sys.platform == "win32":
RESET_ERROR = 10054 #WSAECONNRESET
else:
RESET_ERROR = 104 #ECONNRESET
#
# The following code implements a socket listener for on-the-fly
# reconfiguration of logging.
#
# _listener holds the server object doing the listening
_listener = None
def fileConfig(fname, defaults=None):
"""
Read the logging configuration from a ConfigParser-format file.
This can be called several times from an application, allowing an end user
the ability to select from various pre-canned configurations (if the
developer provides a mechanism to present the choices and load the chosen
configuration).
In versions of ConfigParser which have the readfp method [typically
shipped in 2.x versions of Python], you can pass in a file-like object
rather than a filename, in which case the file-like object will be read
using readfp.
"""
import ConfigParser
cp = ConfigParser.ConfigParser(defaults)
if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
cp.readfp(fname)
else:
cp.read(fname)
#first, do the formatters...
flist = cp.get("formatters", "keys")
if len(flist):
flist = string.split(flist, ",")
formatters = {}
for form in flist:
sectname = "formatter_%s" % form
opts = cp.options(sectname)
if "format" in opts:
fs = cp.get(sectname, "format", 1)
else:
fs = None
if "datefmt" in opts:
dfs = cp.get(sectname, "datefmt", 1)
else:
dfs = None
f = logging.Formatter(fs, dfs)
formatters[form] = f
#next, do the handlers...
#critical section...
logging._acquireLock()
try:
try:
#first, lose the existing handlers...
logging._handlers.clear()
#now set up the new ones...
hlist = cp.get("handlers", "keys")
if len(hlist):
hlist = string.split(hlist, ",")
handlers = {}
fixups = [] #for inter-handler references
for hand in hlist:
sectname = "handler_%s" % hand
klass = cp.get(sectname, "class")
opts = cp.options(sectname)
if "formatter" in opts:
fmt = cp.get(sectname, "formatter")
else:
fmt = ""
klass = eval(klass, vars(logging))
args = cp.get(sectname, "args")
args = eval(args, vars(logging))
h = apply(klass, args)
if "level" in opts:
level = cp.get(sectname, "level")
h.setLevel(logging._levelNames[level])
if len(fmt):
h.setFormatter(formatters[fmt])
#temporary hack for FileHandler and MemoryHandler.
if klass == logging.handlers.MemoryHandler:
if "target" in opts:
target = cp.get(sectname,"target")
else:
target = ""
if len(target): #the target handler may not be loaded yet, so keep for later...
fixups.append((h, target))
handlers[hand] = h
#now all handlers are loaded, fixup inter-handler references...
for fixup in fixups:
h = fixup[0]
t = fixup[1]
h.setTarget(handlers[t])
#at last, the loggers...first the root...
llist = cp.get("loggers", "keys")
llist = string.split(llist, ",")
llist.remove("root")
sectname = "logger_root"
root = logging.root
log = root
opts = cp.options(sectname)
if "level" in opts:
level = cp.get(sectname, "level")
log.setLevel(logging._levelNames[level])
for h in root.handlers[:]:
root.removeHandler(h)
hlist = cp.get(sectname, "handlers")
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
log.addHandler(handlers[hand])
#and now the others...
#we don't want to lose the existing loggers,
#since other threads may have pointers to them.
#existing is set to contain all existing loggers,
#and as we go through the new configuration we
#remove any which are configured. At the end,
#what's left in existing is the set of loggers
#which were in the previous configuration but
#which are not in the new configuration.
existing = root.manager.loggerDict.keys()
#now set up the new ones...
for log in llist:
sectname = "logger_%s" % log
qn = cp.get(sectname, "qualname")
opts = cp.options(sectname)
if "propagate" in opts:
propagate = cp.getint(sectname, "propagate")
else:
propagate = 1
logger = logging.getLogger(qn)
if qn in existing:
existing.remove(qn)
if "level" in opts:
level = cp.get(sectname, "level")
logger.setLevel(logging._levelNames[level])
for h in logger.handlers[:]:
logger.removeHandler(h)
logger.propagate = propagate
logger.disabled = 0
hlist = cp.get(sectname, "handlers")
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
logger.addHandler(handlers[hand])
#Disable any old loggers. There's no point deleting
#them as other threads may continue to hold references
#and by disabling them, you stop them doing any logging.
for log in existing:
root.manager.loggerDict[log].disabled = 1
except:
import traceback
ei = sys.exc_info()
traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
del ei
finally:
logging._releaseLock()
def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
"""
Start up a socket server on the specified port, and listen for new
configurations.
These will be sent as a file suitable for processing by fileConfig().
Returns a Thread object on which you can call start() to start the server,
and which you can join() when appropriate. To stop the server, call
stopListening().
"""
if not thread:
raise NotImplementedError, "listen() needs threading to work"
class ConfigStreamHandler(StreamRequestHandler):
"""
Handler for a logging configuration request.
It expects a completely new logging configuration and uses fileConfig
to install it.
"""
def handle(self):
"""
Handle a request.
Each request is expected to be a 4-byte length,
followed by the config file. Uses fileConfig() to do the
grunt work.
"""
import tempfile
try:
conn = self.connection
chunk = conn.recv(4)
if len(chunk) == 4:
slen = struct.unpack(">L", chunk)[0]
chunk = self.connection.recv(slen)
while len(chunk) < slen:
chunk = chunk + conn.recv(slen - len(chunk))
#Apply new configuration. We'd like to be able to
#create a StringIO and pass that in, but unfortunately
#1.5.2 ConfigParser does not support reading file
#objects, only actual files. So we create a temporary
#file and remove it later.
file = tempfile.mktemp(".ini")
f = open(file, "w")
f.write(chunk)
f.close()
fileConfig(file)
os.remove(file)
except socket.error, e:
if type(e.args) != types.TupleType:
raise
else:
errcode = e.args[0]
if errcode != RESET_ERROR:
raise
class ConfigSocketReceiver(ThreadingTCPServer):
"""
A simple TCP socket-based logging config receiver.
"""
allow_reuse_address = 1
def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
handler=None):
ThreadingTCPServer.__init__(self, (host, port), handler)
logging._acquireLock()
self.abort = 0
logging._releaseLock()
self.timeout = 1
def serve_until_stopped(self):
import select
abort = 0
while not abort:
rd, wr, ex = select.select([self.socket.fileno()],
[], [],
self.timeout)
if rd:
self.handle_request()
logging._acquireLock()
abort = self.abort
logging._releaseLock()
def serve(rcvr, hdlr, port):
server = rcvr(port=port, handler=hdlr)
global _listener
logging._acquireLock()
_listener = server
logging._releaseLock()
server.serve_until_stopped()
return threading.Thread(target=serve,
args=(ConfigSocketReceiver,
ConfigStreamHandler, port))
def stopListening():
"""
Stop the listening server which was created with a call to listen().
"""
global _listener
if _listener:
logging._acquireLock()
_listener.abort = 1
_listener = None
logging._releaseLock()
@@ -1,787 +0,0 @@
# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
Additional handlers for the logging package for Python. The core package is
based on PEP 282 and comments thereto in comp.lang.python, and influenced by
Apache's log4j system.
Should work under Python versions >= 1.5.2, except that source line
information is not available unless 'sys._getframe()' is.
Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging' and log away!
"""
import sys, logging, socket, types, os, string, cPickle, struct, time
from SocketServer import ThreadingTCPServer, StreamRequestHandler
#
# Some constants...
#
DEFAULT_TCP_LOGGING_PORT = 9020
DEFAULT_UDP_LOGGING_PORT = 9021
DEFAULT_HTTP_LOGGING_PORT = 9022
DEFAULT_SOAP_LOGGING_PORT = 9023
SYSLOG_UDP_PORT = 514
class RotatingFileHandler(logging.FileHandler):
def __init__(self, filename, mode="a", maxBytes=0, backupCount=0):
"""
Open the specified file and use it as the stream for logging.
By default, the file grows indefinitely. You can specify particular
values of maxBytes and backupCount to allow the file to rollover at
a predetermined size.
Rollover occurs whenever the current log file is nearly maxBytes in
length. If backupCount is >= 1, the system will successively create
new files with the same pathname as the base file, but with extensions
".1", ".2" etc. appended to it. For example, with a backupCount of 5
and a base file name of "app.log", you would get "app.log",
"app.log.1", "app.log.2", ... through to "app.log.5". The file being
written to is always "app.log" - when it gets filled up, it is closed
and renamed to "app.log.1", and if files "app.log.1", "app.log.2" etc.
exist, then they are renamed to "app.log.2", "app.log.3" etc.
respectively.
If maxBytes is zero, rollover never occurs.
"""
logging.FileHandler.__init__(self, filename, mode)
self.maxBytes = maxBytes
self.backupCount = backupCount
if maxBytes > 0:
self.mode = "a"
def doRollover(self):
"""
Do a rollover, as described in __init__().
"""
self.stream.close()
if self.backupCount > 0:
for i in range(self.backupCount - 1, 0, -1):
sfn = "%s.%d" % (self.baseFilename, i)
dfn = "%s.%d" % (self.baseFilename, i + 1)
if os.path.exists(sfn):
#print "%s -> %s" % (sfn, dfn)
if os.path.exists(dfn):
os.remove(dfn)
os.rename(sfn, dfn)
dfn = self.baseFilename + ".1"
if os.path.exists(dfn):
os.remove(dfn)
os.rename(self.baseFilename, dfn)
#print "%s -> %s" % (self.baseFilename, dfn)
self.stream = open(self.baseFilename, "w")
def emit(self, record):
"""
Emit a record.
Output the record to the file, catering for rollover as described
in doRollover().
"""
if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record)
self.stream.seek(0, 2) #due to non-posix-compliant Windows feature
if self.stream.tell() + len(msg) >= self.maxBytes:
self.doRollover()
logging.FileHandler.emit(self, record)
class SocketHandler(logging.Handler):
"""
A handler class which writes logging records, in pickle format, to
a streaming socket. The socket is kept open across logging calls.
If the peer resets it, an attempt is made to reconnect on the next call.
The pickle which is sent is that of the LogRecord's attribute dictionary
(__dict__), so that the receiver does not need to have the logging module
installed in order to process the logging event.
To unpickle the record at the receiving end into a LogRecord, use the
makeLogRecord function.
"""
def __init__(self, host, port):
"""
Initializes the handler with a specific host address and port.
The attribute 'closeOnError' is set to 1 - which means that if
a socket error occurs, the socket is silently closed and then
reopened on the next logging call.
"""
logging.Handler.__init__(self)
self.host = host
self.port = port
self.sock = None
self.closeOnError = 0
self.retryTime = None
#
# Exponential backoff parameters.
#
self.retryStart = 1.0
self.retryMax = 30.0
self.retryFactor = 2.0
def makeSocket(self):
"""
A factory method which allows subclasses to define the precise
type of socket they want.
"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.host, self.port))
return s
def createSocket(self):
"""
Try to create a socket, using an exponential backoff with
a max retry time. Thanks to Robert Olson for the original patch
(SF #815911) which has been slightly refactored.
"""
now = time.time()
# Either retryTime is None, in which case this
# is the first time back after a disconnect, or
# we've waited long enough.
if self.retryTime is None:
attempt = 1
else:
attempt = (now >= self.retryTime)
if attempt:
try:
self.sock = self.makeSocket()
self.retryTime = None # next time, no delay before trying
except:
#Creation failed, so set the retry time and return.
if self.retryTime is None:
self.retryPeriod = self.retryStart
else:
self.retryPeriod = self.retryPeriod * self.retryFactor
if self.retryPeriod > self.retryMax:
self.retryPeriod = self.retryMax
self.retryTime = now + self.retryPeriod
def send(self, s):
"""
Send a pickled string to the socket.
This function allows for partial sends which can happen when the
network is busy.
"""
if self.sock is None:
self.createSocket()
#self.sock can be None either because we haven't reached the retry
#time yet, or because we have reached the retry time and retried,
#but are still unable to connect.
if self.sock:
try:
if hasattr(self.sock, "sendall"):
self.sock.sendall(s)
else:
sentsofar = 0
left = len(s)
while left > 0:
sent = self.sock.send(s[sentsofar:])
sentsofar = sentsofar + sent
left = left - sent
except socket.error:
self.sock.close()
self.sock = None # so we can call createSocket next time
def makePickle(self, record):
"""
Pickles the record in binary format with a length prefix, and
returns it ready for transmission across the socket.
"""
ei = record.exc_info
if ei:
dummy = self.format(record) # just to get traceback text into record.exc_text
record.exc_info = None # to avoid Unpickleable error
s = cPickle.dumps(record.__dict__, 1)
if ei:
record.exc_info = ei # for next handler
slen = struct.pack(">L", len(s))
return slen + s
def handleError(self, record):
"""
Handle an error during logging.
An error has occurred during logging. Most likely cause -
connection lost. Close the socket so that we can retry on the
next event.
"""
if self.closeOnError and self.sock:
self.sock.close()
self.sock = None #try to reconnect next time
else:
logging.Handler.handleError(self, record)
def emit(self, record):
"""
Emit a record.
Pickles the record and writes it to the socket in binary format.
If there is an error with the socket, silently drop the packet.
If there was a problem with the socket, re-establishes the
socket.
"""
try:
s = self.makePickle(record)
self.send(s)
except:
self.handleError(record)
def close(self):
"""
Closes the socket.
"""
if self.sock:
self.sock.close()
self.sock = None
logging.Handler.close(self)
class DatagramHandler(SocketHandler):
"""
A handler class which writes logging records, in pickle format, to
a datagram socket. The pickle which is sent is that of the LogRecord's
attribute dictionary (__dict__), so that the receiver does not need to
have the logging module installed in order to process the logging event.
To unpickle the record at the receiving end into a LogRecord, use the
makeLogRecord function.
"""
def __init__(self, host, port):
"""
Initializes the handler with a specific host address and port.
"""
SocketHandler.__init__(self, host, port)
self.closeOnError = 0
def makeSocket(self):
"""
The factory method of SocketHandler is here overridden to create
a UDP socket (SOCK_DGRAM).
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return s
def send(self, s):
"""
Send a pickled string to a socket.
This function no longer allows for partial sends which can happen
when the network is busy - UDP does not guarantee delivery and
can deliver packets out of sequence.
"""
self.sock.sendto(s, (self.host, self.port))
class SysLogHandler(logging.Handler):
"""
A handler class which sends formatted logging records to a syslog
server. Based on Sam Rushing's syslog module:
http://www.nightmare.com/squirl/python-ext/misc/syslog.py
Contributed by Nicolas Untz (after which minor refactoring changes
have been made).
"""
# from <linux/sys/syslog.h>:
# ======================================================================
# priorities/facilities are encoded into a single 32-bit quantity, where
# the bottom 3 bits are the priority (0-7) and the top 28 bits are the
# facility (0-big number). Both the priorities and the facilities map
# roughly one-to-one to strings in the syslogd(8) source code. This
# mapping is included in this file.
#
# priorities (these are ordered)
LOG_EMERG = 0 # system is unusable
LOG_ALERT = 1 # action must be taken immediately
LOG_CRIT = 2 # critical conditions
LOG_ERR = 3 # error conditions
LOG_WARNING = 4 # warning conditions
LOG_NOTICE = 5 # normal but significant condition
LOG_INFO = 6 # informational
LOG_DEBUG = 7 # debug-level messages
# facility codes
LOG_KERN = 0 # kernel messages
LOG_USER = 1 # random user-level messages
LOG_MAIL = 2 # mail system
LOG_DAEMON = 3 # system daemons
LOG_AUTH = 4 # security/authorization messages
LOG_SYSLOG = 5 # messages generated internally by syslogd
LOG_LPR = 6 # line printer subsystem
LOG_NEWS = 7 # network news subsystem
LOG_UUCP = 8 # UUCP subsystem
LOG_CRON = 9 # clock daemon
LOG_AUTHPRIV = 10 # security/authorization messages (private)
# other codes through 15 reserved for system use
LOG_LOCAL0 = 16 # reserved for local use
LOG_LOCAL1 = 17 # reserved for local use
LOG_LOCAL2 = 18 # reserved for local use
LOG_LOCAL3 = 19 # reserved for local use
LOG_LOCAL4 = 20 # reserved for local use
LOG_LOCAL5 = 21 # reserved for local use
LOG_LOCAL6 = 22 # reserved for local use
LOG_LOCAL7 = 23 # reserved for local use
priority_names = {
"alert": LOG_ALERT,
"crit": LOG_CRIT,
"critical": LOG_CRIT,
"debug": LOG_DEBUG,
"emerg": LOG_EMERG,
"err": LOG_ERR,
"error": LOG_ERR, # DEPRECATED
"info": LOG_INFO,
"notice": LOG_NOTICE,
"panic": LOG_EMERG, # DEPRECATED
"warn": LOG_WARNING, # DEPRECATED
"warning": LOG_WARNING,
}
facility_names = {
"auth": LOG_AUTH,
"authpriv": LOG_AUTHPRIV,
"cron": LOG_CRON,
"daemon": LOG_DAEMON,
"kern": LOG_KERN,
"lpr": LOG_LPR,
"mail": LOG_MAIL,
"news": LOG_NEWS,
"security": LOG_AUTH, # DEPRECATED
"syslog": LOG_SYSLOG,
"user": LOG_USER,
"uucp": LOG_UUCP,
"local0": LOG_LOCAL0,
"local1": LOG_LOCAL1,
"local2": LOG_LOCAL2,
"local3": LOG_LOCAL3,
"local4": LOG_LOCAL4,
"local5": LOG_LOCAL5,
"local6": LOG_LOCAL6,
"local7": LOG_LOCAL7,
}
def __init__(self, address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER):
"""
Initialize a handler.
If address is specified as a string, UNIX socket is used.
If facility is not specified, LOG_USER is used.
"""
logging.Handler.__init__(self)
self.address = address
self.facility = facility
if type(address) == types.StringType:
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
# syslog may require either DGRAM or STREAM sockets
try:
self.socket.connect(address)
except socket.error:
self.socket.close()
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.socket.connect(address)
self.unixsocket = 1
else:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.unixsocket = 0
self.formatter = None
# curious: when talking to the unix-domain '/dev/log' socket, a
# zero-terminator seems to be required. this string is placed
# into a class variable so that it can be overridden if
# necessary.
log_format_string = '<%d>%s\000'
def encodePriority (self, facility, priority):
"""
Encode the facility and priority. You can pass in strings or
integers - if strings are passed, the facility_names and
priority_names mapping dictionaries are used to convert them to
integers.
"""
if type(facility) == types.StringType:
facility = self.facility_names[facility]
if type(priority) == types.StringType:
priority = self.priority_names[priority]
return (facility << 3) | priority
def close (self):
"""
Closes the socket.
"""
if self.unixsocket:
self.socket.close()
logging.Handler.close(self)
def emit(self, record):
"""
Emit a record.
The record is formatted, and then sent to the syslog server. If
exception information is present, it is NOT sent to the server.
"""
msg = self.format(record)
"""
We need to convert record level to lowercase, maybe this will
change in the future.
"""
msg = self.log_format_string % (
self.encodePriority(self.facility,
string.lower(record.levelname)),
msg)
try:
if self.unixsocket:
self.socket.send(msg)
else:
self.socket.sendto(msg, self.address)
except:
self.handleError(record)
class SMTPHandler(logging.Handler):
"""
A handler class which sends an SMTP email for each logging event.
"""
def __init__(self, mailhost, fromaddr, toaddrs, subject):
"""
Initialize the handler.
Initialize the instance with the from and to addresses and subject
line of the email. To specify a non-standard SMTP port, use the
(host, port) tuple format for the mailhost argument.
"""
logging.Handler.__init__(self)
if type(mailhost) == types.TupleType:
host, port = mailhost
self.mailhost = host
self.mailport = port
else:
self.mailhost = mailhost
self.mailport = None
self.fromaddr = fromaddr
if type(toaddrs) == types.StringType:
toaddrs = [toaddrs]
self.toaddrs = toaddrs
self.subject = subject
def getSubject(self, record):
"""
Determine the subject for the email.
If you want to specify a subject line which is record-dependent,
override this method.
"""
return self.subject
weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
monthname = [None,
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
def date_time(self):
"""Return the current date and time formatted for a MIME header."""
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(time.time())
s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
self.weekdayname[wd],
day, self.monthname[month], year,
hh, mm, ss)
return s
def emit(self, record):
"""
Emit a record.
Format the record and send it to the specified addressees.
"""
try:
import smtplib
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
smtp = smtplib.SMTP(self.mailhost, port)
msg = self.format(record)
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
self.fromaddr,
string.join(self.toaddrs, ","),
self.getSubject(record),
self.date_time(), msg)
smtp.sendmail(self.fromaddr, self.toaddrs, msg)
smtp.quit()
except:
self.handleError(record)
class NTEventLogHandler(logging.Handler):
"""
A handler class which sends events to the NT Event Log. Adds a
registry entry for the specified application name. If no dllname is
provided, win32service.pyd (which contains some basic message
placeholders) is used. Note that use of these placeholders will make
your event logs big, as the entire message source is held in the log.
If you want slimmer logs, you have to pass in the name of your own DLL
which contains the message definitions you want to use in the event log.
"""
def __init__(self, appname, dllname=None, logtype="Application"):
logging.Handler.__init__(self)
try:
import win32evtlogutil, win32evtlog
self.appname = appname
self._welu = win32evtlogutil
if not dllname:
dllname = os.path.split(self._welu.__file__)
dllname = os.path.split(dllname[0])
dllname = os.path.join(dllname[0], r'win32service.pyd')
self.dllname = dllname
self.logtype = logtype
self._welu.AddSourceToRegistry(appname, dllname, logtype)
self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE
self.typemap = {
logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE,
logging.INFO : win32evtlog.EVENTLOG_INFORMATION_TYPE,
logging.WARNING : win32evtlog.EVENTLOG_WARNING_TYPE,
logging.ERROR : win32evtlog.EVENTLOG_ERROR_TYPE,
logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
}
except ImportError:
print "The Python Win32 extensions for NT (service, event "\
"logging) appear not to be available."
self._welu = None
def getMessageID(self, record):
"""
Return the message ID for the event record. If you are using your
own messages, you could do this by having the msg passed to the
logger being an ID rather than a formatting string. Then, in here,
you could use a dictionary lookup to get the message ID. This
version returns 1, which is the base message ID in win32service.pyd.
"""
return 1
def getEventCategory(self, record):
"""
Return the event category for the record.
Override this if you want to specify your own categories. This version
returns 0.
"""
return 0
def getEventType(self, record):
"""
Return the event type for the record.
Override this if you want to specify your own types. This version does
a mapping using the handler's typemap attribute, which is set up in
__init__() to a dictionary which contains mappings for DEBUG, INFO,
WARNING, ERROR and CRITICAL. If you are using your own levels you will
either need to override this method or place a suitable dictionary in
the handler's typemap attribute.
"""
return self.typemap.get(record.levelno, self.deftype)
def emit(self, record):
"""
Emit a record.
Determine the message ID, event category and event type. Then
log the message in the NT event log.
"""
if self._welu:
try:
id = self.getMessageID(record)
cat = self.getEventCategory(record)
type = self.getEventType(record)
msg = self.format(record)
self._welu.ReportEvent(self.appname, id, cat, type, [msg])
except:
self.handleError(record)
def close(self):
"""
Clean up this handler.
You can remove the application name from the registry as a
source of event log entries. However, if you do this, you will
not be able to see the events as you intended in the Event Log
Viewer - it needs to be able to access the registry to get the
DLL name.
"""
#self._welu.RemoveSourceFromRegistry(self.appname, self.logtype)
logging.Handler.close(self)
class HTTPHandler(logging.Handler):
"""
A class which sends records to a Web server, using either GET or
POST semantics.
"""
def __init__(self, host, url, method="GET"):
"""
Initialize the instance with the host, the request URL, and the method
("GET" or "POST")
"""
logging.Handler.__init__(self)
method = string.upper(method)
if method not in ["GET", "POST"]:
raise ValueError, "method must be GET or POST"
self.host = host
self.url = url
self.method = method
def mapLogRecord(self, record):
"""
Default implementation of mapping the log record into a dict
that is sent as the CGI data. Overwrite in your class.
Contributed by Franz Glasner.
"""
return record.__dict__
def emit(self, record):
"""
Emit a record.
Send the record to the Web server as an URL-encoded dictionary
"""
try:
import httplib, urllib
h = httplib.HTTP(self.host)
url = self.url
data = urllib.urlencode(self.mapLogRecord(record))
if self.method == "GET":
if (string.find(url, '?') >= 0):
sep = '&'
else:
sep = '?'
url = url + "%c%s" % (sep, data)
h.putrequest(self.method, url)
if self.method == "POST":
h.putheader("Content-length", str(len(data)))
h.endheaders()
if self.method == "POST":
h.send(data)
h.getreply() #can't do anything with the result
except:
self.handleError(record)
class BufferingHandler(logging.Handler):
"""
A handler class which buffers logging records in memory. Whenever each
record is added to the buffer, a check is made to see if the buffer should
be flushed. If it should, then flush() is expected to do what's needed.
"""
def __init__(self, capacity):
"""
Initialize the handler with the buffer size.
"""
logging.Handler.__init__(self)
self.capacity = capacity
self.buffer = []
def shouldFlush(self, record):
"""
Should the handler flush its buffer?
Returns true if the buffer is up to capacity. This method can be
overridden to implement custom flushing strategies.
"""
return (len(self.buffer) >= self.capacity)
def emit(self, record):
"""
Emit a record.
Append the record. If shouldFlush() tells us to, call flush() to process
the buffer.
"""
self.buffer.append(record)
if self.shouldFlush(record):
self.flush()
def flush(self):
"""
Override to implement custom flushing behaviour.
This version just zaps the buffer to empty.
"""
self.buffer = []
def close(self):
"""
Close the handler.
This version just flushes and chains to the parent class' close().
"""
self.flush()
logging.Handler.close(self)
class MemoryHandler(BufferingHandler):
"""
A handler class which buffers logging records in memory, periodically
flushing them to a target handler. Flushing occurs whenever the buffer
is full, or when an event of a certain severity or greater is seen.
"""
def __init__(self, capacity, flushLevel=logging.ERROR, target=None):
"""
Initialize the handler with the buffer size, the level at which
flushing should occur and an optional target.
Note that without a target being set either here or via setTarget(),
a MemoryHandler is no use to anyone!
"""
BufferingHandler.__init__(self, capacity)
self.flushLevel = flushLevel
self.target = target
def shouldFlush(self, record):
"""
Check for buffer full or a record at the flushLevel or higher.
"""
return (len(self.buffer) >= self.capacity) or \
(record.levelno >= self.flushLevel)
def setTarget(self, target):
"""
Set the target handler for this handler.
"""
self.target = target
def flush(self):
"""
For a MemoryHandler, flushing means just sending the buffered
records to the target, if there is one. Override if you want
different behaviour.
"""
if self.target:
for record in self.buffer:
self.target.handle(record)
self.buffer = []
def close(self):
"""
Flush, set the target to None and lose the buffer.
"""
self.flush()
self.target = None
BufferingHandler.close(self)
File diff suppressed because it is too large. Load diff
@@ -1,29 +0,0 @@
from distutils.core import setup
setup(name = "logging",
description="A logging module for Python",
long_description = """This module is intended to provide a standard error logging mechanism in Python as per PEP 282.""",
license="""Copyright (C) 2001-2004 by Vinay Sajip. All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Vinay Sajip
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.""",
version = "0.4.9.2",
author = "Vinay Sajip",
author_email = "vinay_sajip@red-dove.com",
maintainer = "Vinay Sajip",
maintainer_email = "vinay_sajip@red-dove.com",
url = "http://www.red-dove.com/python_logging.html",
packages = ["logging"],
)
@@ -1,5 +0,0 @@
import logging
logging.warning("Hello")
logging.error("Still here...")
logging.warning("Goodbye")
@@ -1,60 +0,0 @@
[loggers]
keys=root,log02,log03,log04,log05
[handlers]
keys=hand01
[formatters]
keys=form01
[logger_root]
level=WARN
propagate=1
channel=
parent=
qualname=(root)
handlers=hand01
[logger_log02]
level=CRITICAL
propagate=1
channel=A
parent=(root)
qualname=A
handlers=
[logger_log03]
level=CRITICAL
propagate=1
channel=B
parent=log02
qualname=A.B
handlers=
[logger_log04]
level=CRITICAL
propagate=1
channel=C
parent=log03
qualname=A.B.C
handlers=
[logger_log05]
level=CRITICAL
propagate=1
channel=D
parent=log04
qualname=A.B.C.D
handlers=
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
stream=sys.stderr
args=(sys.stderr,)
[formatter_form01]
format=critical.ini %(name)s %(levelname)s %(message)s
datefmt=
@@ -1,60 +0,0 @@
[loggers]
keys=root,log02,log03,log04,log05
[handlers]
keys=hand01
[formatters]
keys=form01
[logger_root]
level=WARN
propagate=1
channel=
parent=
qualname=(root)
handlers=hand01
[logger_log02]
level=DEBUG
propagate=1
channel=A
parent=(root)
qualname=A
handlers=
[logger_log03]
level=DEBUG
propagate=1
channel=B
parent=log02
qualname=A.B
handlers=
[logger_log04]
level=DEBUG
propagate=1
channel=C
parent=log03
qualname=A.B.C
handlers=
[logger_log05]
level=DEBUG
propagate=1
channel=D
parent=log04
qualname=A.B.C.D
handlers=
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
stream=sys.stderr
args=(sys.stderr,)
[formatter_form01]
format=debug.ini %(name)s %(levelname)s %(message)s
datefmt=
@@ -1,60 +0,0 @@
[loggers]
keys=root,log02,log03,log04,log05
[handlers]
keys=hand01
[formatters]
keys=form01
[logger_root]
level=WARN
propagate=1
channel=
parent=
qualname=(root)
handlers=hand01
[logger_log02]
level=ERROR
propagate=1
channel=A
parent=(root)
qualname=A
handlers=
[logger_log03]
level=ERROR
propagate=1
channel=B
parent=log02
qualname=A.B
handlers=
[logger_log04]
level=ERROR
propagate=1
channel=C
parent=log03
qualname=A.B.C
handlers=
[logger_log05]
level=ERROR
propagate=1
channel=D
parent=log04
qualname=A.B.C.D
handlers=
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
stream=sys.stderr
args=(sys.stderr,)
[formatter_form01]
format=error.ini %(name)s %(levelname)s %(message)s
datefmt=
@@ -1,31 +0,0 @@
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 90</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 91</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 92</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 93</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 94</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 95</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 96</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 97</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 98</message>
</event>
<event name="root" level="20" filename="log_test9.py" lineno="66">
<message>Info index = 99</message>
</event>
@@ -1,158 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. Run all tests.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import os, sys, logging, threading, time
BANNER = "-- %-10s %-6s --------------------------------------------------------\n"
def banner(nm, typ):
sep = BANNER % (nm, typ)
sys.stdout.write(sep)
sys.stdout.flush()
sys.stderr.write(sep)
sys.stderr.flush()
def main():
oldout = sys.stdout
olderr = sys.stderr
sys.stdout = open("stdout.log", "w")
sys.stderr = open("stderr.log", "w")
logging.basicConfig()
root = logging.getLogger("")
hdlr0 = root.handlers[0]
#Set up servers
import logrecv
threads = []
tcpserver = logrecv.LogRecordSocketReceiver()
tcpserver.logname = ""
threads.append(threading.Thread(target=logrecv.runTCP, args=(tcpserver,)))
udpserver = logrecv.LogRecordDatagramReceiver()
udpserver.logname = ""
threads.append(threading.Thread(target=logrecv.runUDP, args=(udpserver,)))
httpserver = logrecv.LogRecordHTTPReceiver()
httpserver.logname = ""
threads.append(threading.Thread(target=logrecv.runHTTP, args=(httpserver,)))
soapserver = None
if logrecv.SOAPServer:
soapserver = logrecv.SOAPServer()
soapserver.modules = (sys.modules["logrecv"],)
soapserver.logname = ""
threads.append(threading.Thread(target=logrecv.runSOAP, args=(soapserver,)))
for thread in threads:
thread.start()
try:
import log_test0
banner("log_test0", "begin")
log_test0.main()
banner("log_test0", "end")
try:
import log_test1
banner("log_test1", "begin")
log_test1.main()
banner("log_test1", "end")
except ImportError:
pass
import log_test2
banner("log_test2", "begin")
log_test2.main()
banner("log_test2", "end")
time.sleep(3)
#Skip 3 as it tests fileConfig
banner("log_test4", "begin")
import log_test4
banner("log_test4", "end")
#Skip 5 as it tests SMTPHandler, can't easily check results automatically
#Skip 6 as it tests NTEventLogHandler, can't easily check results automatically
banner("log_test7", "begin")
root.removeHandler(hdlr0)
import log_test7
root.addHandler(hdlr0)
banner("log_test7", "end")
banner("log_test8", "begin")
import log_test8
root.removeHandler(hdlr0)
log_test8.main()
root.addHandler(hdlr0)
banner("log_test8", "end")
banner("log_test9", "begin")
import log_test9
root.removeHandler(hdlr0)
log_test9.main()
root.addHandler(hdlr0)
banner("log_test9", "end")
banner("log_test10", "begin")
import log_test10
log_test10.main()
banner("log_test10", "end")
#Skip 11 as it tests SMTPHandler, can't easily check results automatically
import log_test12
banner("log_test12", "begin")
log_test12.main()
banner("log_test12", "end")
import log_test13
banner("log_test13", "begin")
log_test13.main()
banner("log_test13", "end")
import log_test15
banner("log_test15", "begin")
log_test15.test(log_test15.FILTER)
banner("log_test15", "end")
time.sleep(3)
finally:
#shut down servers
olderr.write("Tidying up...")
tcpserver.abort = 1
udpserver.abort = 1
httpserver.abort = 1
if soapserver:
soapserver.abort = 1
for thread in threads:
thread.join()
sys.stdout.close()
sys.stdout = oldout
#don't close this, as hdlr0 references it. hdlr0 will be closed at application exit
#sys.stderr.close()
sys.stderr = olderr
print "Test run completed."
if __name__ == "__main__":
main()
@@ -1,118 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. A basic test of levels.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging
msgcount = 0
def nextmessage():
global msgcount
rv = "Message %d" % msgcount
msgcount = msgcount + 1
return rv
def main():
logging.basicConfig()
logging.getLogger("").setLevel(logging.DEBUG)
ERR = logging.getLogger("ERR")
ERR.setLevel(logging.ERROR)
INF = logging.getLogger("INF")
INF.setLevel(logging.INFO)
INF_ERR = logging.getLogger("INF.ERR")
INF_ERR.setLevel(logging.ERROR)
DEB = logging.getLogger("DEB")
DEB.setLevel(logging.DEBUG)
INF_UNDEF = logging.getLogger("INF.UNDEF")
INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF")
UNDEF = logging.getLogger("UNDEF")
GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF")
CHILD = logging.getLogger("INF.BADPARENT")
#These should log
ERR.log(logging.CRITICAL, nextmessage())
ERR.error(nextmessage())
INF.log(logging.CRITICAL, nextmessage())
INF.error(nextmessage())
INF.warning(nextmessage())
INF.info(nextmessage())
INF_UNDEF.log(logging.CRITICAL, nextmessage())
INF_UNDEF.error(nextmessage())
INF_UNDEF.warning(nextmessage())
INF_UNDEF.info(nextmessage())
INF_ERR.log(logging.CRITICAL, nextmessage())
INF_ERR.error(nextmessage())
INF_ERR_UNDEF.log(logging.CRITICAL, nextmessage())
INF_ERR_UNDEF.error(nextmessage())
DEB.log(logging.CRITICAL, nextmessage())
DEB.error(nextmessage())
DEB.warning(nextmessage())
DEB.info(nextmessage())
DEB.debug(nextmessage())
UNDEF.log(logging.CRITICAL, nextmessage())
UNDEF.error(nextmessage())
UNDEF.warning(nextmessage())
UNDEF.info(nextmessage())
GRANDCHILD.log(logging.CRITICAL, nextmessage())
CHILD.log(logging.CRITICAL, nextmessage())
#These should not log
ERR.warning(nextmessage())
ERR.info(nextmessage())
ERR.debug(nextmessage())
INF.debug(nextmessage())
INF_UNDEF.debug(nextmessage())
INF_ERR.warning(nextmessage())
INF_ERR.info(nextmessage())
INF_ERR.debug(nextmessage())
INF_ERR_UNDEF.warning(nextmessage())
INF_ERR_UNDEF.info(nextmessage())
INF_ERR_UNDEF.debug(nextmessage())
INF.info("Messages should bear numbers 0 through 24.")
if __name__ == "__main__":
import sys
#print sys.argv[0]
args = sys.argv[1:]
if "-profile" in args:
import profile, pstats
args.remove("-profile")
statf = "log_test0.pro"
profile.run("main()", statf)
stats = pstats.Stats(statf)
stats.strip_dirs().sort_stats('time').print_stats()
else:
main()
@@ -1,85 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. A test showing exception handling and use of SysLogHandler.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys, logging
import syslog
class SLHandler(logging.Handler):
def __init__(self, ident, logopt=0, facility=syslog.LOG_USER):
logging.Handler.__init__(self)
self.ident = ident
self.logopt = logopt
self.facility = facility
self.mappings = {
logging.DEBUG: syslog.LOG_DEBUG,
logging.INFO: syslog.LOG_INFO,
logging.WARNING: syslog.LOG_WARNING,
logging.ERROR: syslog.LOG_ERR,
logging.CRITICAL: syslog.LOG_CRIT,
}
def encodeLevel(self, level):
return self.mappings.get(level, syslog.LOG_INFO)
def emit(self, record):
syslog.openlog(self.ident, self.logopt, self.facility)
msg = self.format(record)
prio = self.encodeLevel(record.levelno)
syslog.syslog(prio, msg)
syslog.closelog()
def config():
logging.basicConfig()
logging.getLogger("").setLevel(logging.DEBUG)
if __name__ == "__main__":
fmt = logging.Formatter("%(asctime)s %(filename)s:%(lineno)d %(levelname)-5s - %(message)s")
hdlr = logging.FileHandler("tmp.tmp")
hdlr.setFormatter(fmt)
logging.getLogger("").addHandler(hdlr)
else:
fmt = None
hdlr = SLHandler("log_test1")
if fmt:
hdlr.setFormatter(fmt)
logging.getLogger("").addHandler(hdlr)
return hdlr
def run():
logging.info("Starting...")
try:
print "7" + 4
except Exception, e:
logging.error("Problem %s (%d)", "ERROR", logging.ERROR, exc_info=1)
logging.debug("Problem %s (%d)", "DEBUG", logging.DEBUG, exc_info=1)
logging.info("Done.")
def main():
hdlr = config()
run()
logging.getLogger("").removeHandler(hdlr)
if __name__ == "__main__":
main()
@@ -1,87 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. Shows use of a user-defined Logger subclass.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys
import locale
locale.setlocale(locale.LC_ALL, '')
from logging import *
LOG_FORMAT = "%(asctime)s %(levelname)-5s %(message)s"
DATE_FORMAT = "%x %X"
class MyLogger(Logger):
"""
A simple example of a logger extension.
"""
def debug(self, msg, *args, **kwargs):
"""
This overridden method passes exception information for DEBUG level calls
"""
if self.manager.disable >= DEBUG:
return
if DEBUG >= self.getEffectiveLevel():
exc_info = kwargs.get("exc_info", 0)
ei = None
if exc_info:
ei = sys.exc_info()
if not ei[1]:
ei = None
self._log(DEBUG, msg, args, ei)
del ei
class NotALogger:
pass
def config():
try:
setLoggerClass(NotALogger)
except Exception, e:
sys.stderr.write("%s\n" % e)
setLoggerClass(MyLogger)
if __name__ == "__main__":
basicConfig()
if __name__ == "__main__":
getLogger("").handlers[0].setFormatter(Formatter(LOG_FORMAT, DATE_FORMAT))
def run():
getLogger("").setLevel(DEBUG)
logger = getLogger("mylogger")
logger.info("Starting...")
logger.debug("Debug message not in exception handler (no traceback)")
logger.info("About to throw exception...")
try:
print "7" + 4
except Exception, e:
logger.debug("Debug message inside exception handler (traceback)",exc_info=1)
logger.info("Done.")
def main():
config()
run()
if __name__ == "__main__":
main()
@@ -1,72 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. Tests BufferingSMTPHandler, an alternative implementation
of SMTPHandler.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import string, logging, logging.handlers
MAILHOST = 'beta'
FROM = 'log_test11@red-dove.com'
TO = ['arkadi_renko']
SUBJECT = 'Test Logging email from Python logging module (buffering)'
class BufferingSMTPHandler(logging.handlers.BufferingHandler):
def __init__(self, mailhost, fromaddr, toaddrs, subject, capacity):
logging.handlers.BufferingHandler.__init__(self, capacity)
self.mailhost = mailhost
self.mailport = None
self.fromaddr = fromaddr
self.toaddrs = toaddrs
self.subject = subject
self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
def flush(self):
if len(self.buffer) > 0:
try:
import smtplib
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
smtp = smtplib.SMTP(self.mailhost, port)
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, string.join(self.toaddrs, ","), self.subject)
for record in self.buffer:
s = self.format(record)
print s
msg = msg + s + "\r\n"
smtp.sendmail(self.fromaddr, self.toaddrs, msg)
smtp.quit()
except:
self.handleError(None) # no particular record
self.buffer = []
def test():
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
logger.addHandler(BufferingSMTPHandler(MAILHOST, FROM, TO, SUBJECT, 10))
for i in xrange(102):
logger.info("Info index = %d", i)
logging.shutdown()
if __name__ == "__main__":
test()
@@ -1,47 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests HTTPHandler.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys, string, logging, logging.handlers
def main():
import pdb
host = "localhost:%d" % logging.handlers.DEFAULT_HTTP_LOGGING_PORT
gh = logging.handlers.HTTPHandler(host, '/log', 'GET')
ph = logging.handlers.HTTPHandler(host, '/log', 'POST')
logger = logging.getLogger("log_test12")
logger.propagate = 0
logger.addHandler(gh)
logger.addHandler(ph)
logging.getLogger("").setLevel(logging.DEBUG)
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
logger.debug("Pack my %s with twelve dozen %s", "box", "liquor jugs")
gh.close()
ph.close()
logger.removeHandler(gh)
logger.removeHandler(ph)
if __name__ == "__main__":
main()
@@ -1,106 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Implements a SOAPHandler class which
can be used to form the basis of extended SOAP functionality.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import string, logging, logging.handlers, types
SOAP_MESSAGE = """<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:logging="http://www.red-dove.com/logging"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
>
<SOAP-ENV:Body>
<logging:log>
%s
</logging:log>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
"""
class SOAPHandler(logging.Handler):
"""
A class which sends records to a SOAP server.
"""
def __init__(self, host, url):
"""
Initialize the instance with the host and the request URL
"""
logging.Handler.__init__(self)
self.host = host
self.url = url
def emit(self, record):
"""
Send the record to the Web server as a SOAP message
"""
try:
import httplib
h = httplib.HTTP(self.host)
h.putrequest("POST", self.url)
keys = record.__dict__.keys()
keys.sort()
args = ""
for key in keys:
v = record.__dict__[key]
if type(v) == types.StringType:
t = "string"
elif (type(v) == types.IntType) or (type(v) == types.LongType):
t = "integer"
elif type(v) == types.FloatType:
t = "float"
else:
t = "string"
args = args + "%12s<logging:%s xsi:type=\"xsd:%s\">%s</logging:%s>\n" % ("",
key, t, str(v), key)
data = SOAP_MESSAGE % args[:-1]
h.putheader("Content-type", "text/plain; charset=\"utf-8\"")
h.putheader("Content-length", str(len(data)))
h.endheaders()
#print data
h.send(data)
r = h.getreply() #can't do anything with the result
f = h.getfile()
if f:
#print f.read()
f.close()
except:
self.handleError(record)
def main():
sh = SOAPHandler('localhost:%d' % logging.handlers.DEFAULT_SOAP_LOGGING_PORT, '/log')
logger = logging.getLogger("log_test13")
logging.getLogger("").setLevel(logging.DEBUG)
logger.propagate = 0
logger.addHandler(sh)
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
logger.debug("Pack my %s with five dozen %s", "box", "liquor jugs")
logger.removeHandler(sh)
if __name__ == "__main__":
main()
@@ -1,108 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. An example handler - DBHandler -
which writes to an Python DB API 2.0 data source. You'll need to set this
source up before you run the test.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys, string, time, logging
class DBHandler(logging.Handler):
def __init__(self, dsn, uid='', pwd=''):
logging.Handler.__init__(self)
import mx.ODBC.Windows
self.dsn = dsn
self.uid = uid
self.pwd = pwd
self.conn = mx.ODBC.Windows.connect(self.dsn, self.uid, self.pwd)
self.SQL = """INSERT INTO Events (
Created,
RelativeCreated,
Name,
LogLevel,
LevelText,
Message,
Filename,
Pathname,
Lineno,
Milliseconds,
Exception,
Thread
)
VALUES (
%(dbtime)s,
%(relativeCreated)d,
'%(name)s',
%(levelno)d,
'%(levelname)s',
'%(message)s',
'%(filename)s',
'%(pathname)s',
%(lineno)d,
%(msecs)d,
'%(exc_text)s',
'%(thread)s'
);
"""
self.cursor = self.conn.cursor()
def formatDBTime(self, record):
record.dbtime = time.strftime("#%m/%d/%Y#", time.localtime(record.created))
def emit(self, record):
try:
#use default formatting
self.format(record)
#now set the database time up
self.formatDBTime(record)
if record.exc_info:
record.exc_text = logging._defaultFormatter.formatException(record.exc_info)
else:
record.exc_text = ""
sql = self.SQL % record.__dict__
self.cursor.execute(sql)
self.conn.commit()
except:
import traceback
ei = sys.exc_info()
traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
del ei
def close(self):
self.cursor.close()
self.conn.close()
logging.Handler.close(self)
dh = DBHandler('Logging')
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
logger.addHandler(dh)
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
logger.debug("Pack my %s with five dozen %s", "box", "liquor jugs")
try:
import math
math.exp(1000)
except:
logger.exception("Problem with %s", "math.exp")
logging.shutdown()
@@ -1,70 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests Filter.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys, logging
FILTER = "a.b"
def message(s):
sys.stderr.write("%s\n" % s)
def doLog():
logging.getLogger("a").info("Info 1")
logging.getLogger("a.b").info("Info 2")
logging.getLogger("a.c").info("Info 3")
logging.getLogger("a.b.c").info("Info 4")
logging.getLogger("a.b.c.d").info("Info 5")
logging.getLogger("a.bb.c").info("Info 6")
logging.getLogger("b").info("Info 7")
logging.getLogger("b.a").info("Info 8")
logging.getLogger("c.a.b").info("Info 9")
logging.getLogger("a.bb").info("Info 10")
def test(fs):
root = logging.getLogger()
root.setLevel(logging.DEBUG)
if __name__ == "__main__":
hand = logging.StreamHandler()
hand.setFormatter(logging.Formatter("%(name)-10s %(message)s"))
root.addHandler(hand)
else:
hand = root.handlers[0]
message("Unfiltered...")
doLog()
message("Filtered with '%s'..." % fs)
filt = logging.Filter(fs)
hand.addFilter(filt)
doLog()
hand.removeFilter(filt)
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
fs = sys.argv[1]
else:
fs = FILTER
test(fs)
@@ -1,73 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests thread safety.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.handlers, thread, threading, random
logging.raiseExceptions = 1
NUM_THREADS = 10
LOOP_COUNT = 10000
LOG_MESSAGES = [
(logging.DEBUG, "%3d This is a %s message", "debug"),
(logging.INFO, "%3d This is an %s message", "informational"),
(logging.WARNING, "%3d This is a %s message", "warning"),
(logging.ERROR, "%3d This is an %s message", "error"),
(logging.CRITICAL, "%3d This is a %s message", "critical"),
]
LOG_NAMES = ["A", "A.B", "A.B.C", "A.B.C.D"]
def doLog(num):
logger = logging.getLogger('')
logger.info("*** thread %s started (%d)", thread.get_ident(), num)
for i in xrange(LOOP_COUNT):
logger = logging.getLogger(random.choice(LOG_NAMES))
a = random.choice(LOG_MESSAGES)
args = a[0:2] + (num,) + a[2:]
apply(logger.log, args)
def test():
f = logging.Formatter("%(asctime)s %(levelname)-9s %(name)-8s %(thread)5s %(message)s")
root = logging.getLogger('')
root.setLevel(logging.DEBUG)
h = logging.FileHandler('thread.log', 'w')
root.addHandler(h)
h.setFormatter(f)
h = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
#h = logging.handlers.DatagramHandler('localhost', logging.handlers.DEFAULT_UDP_LOGGING_PORT)
root.addHandler(h)
threads = []
for i in xrange(NUM_THREADS):
threads.append(threading.Thread(target=doLog, args=(len(threads),)))
for t in threads:
t.start()
for t in threads:
t.join()
if __name__ == "__main__":
test()
@@ -1,111 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests thread safety.
To use as a server, run with no arguments in one process.
To use as a client, run with arguments "-client <filename>" where <filename>
is the name of a file containing a logging configuration.
The example files debug.ini, warn.ini, error.ini and critical.ini are
provided to use in the test. They each have a customized message format
(prefixed with their name) and the loggers have their levels set to the
value implied by their name.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys, logging, logging.config, thread, threading, random, time, struct
NUM_THREADS = 10
LOOP_COUNT = 10
CONFIG_PORT = 9077
logging.raiseExceptions = 1
LOG_MESSAGES = [
(logging.DEBUG, "%3d This is a %s message", "debug"),
(logging.INFO, "%3d This is an %s message", "informational"),
(logging.WARNING, "%3d This is a %s message", "warning"),
(logging.ERROR, "%3d This is an %s message", "error"),
(logging.CRITICAL, "%3d This is a %s message", "critical"),
]
LOG_NAMES = ["A", "A.B", "A.B.C", "A.B.C.D"]
def doLog(num):
logger = logging.getLogger('')
logger.setLevel(logging.DEBUG)
logger.info("*** thread %s started (%d)", thread.get_ident(), num)
for i in xrange(LOOP_COUNT):
logger = logging.getLogger(random.choice(LOG_NAMES))
a = random.choice(LOG_MESSAGES)
args = a[0:2] + (num,) + a[2:]
time.sleep(random.random() * 3)
apply(logger.log, args)
def runserver():
f = logging.Formatter("%(asctime)s %(levelname)-9s %(name)-8s %(thread)5s %(message)s")
root = logging.getLogger('')
h = logging.StreamHandler()
root.addHandler(h)
h.setFormatter(f)
threads = []
for i in xrange(NUM_THREADS):
threads.append(threading.Thread(target=doLog, args=(len(threads),)))
threads.append(logging.config.listen(CONFIG_PORT)) #don't use default port
for t in threads:
t.start()
for t in threads[:-1]:
t.join()
logging.config.stopListening()
threads[-1].join()
def runclient(fname):
import socket
print "configuring with '%s'" % fname
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', CONFIG_PORT))
f = open(fname, "r")
s = f.read()
f.close()
slen = struct.pack(">L", len(s))
s = slen + s
sentsofar = 0
left = len(s)
while left > 0:
sent = sock.send(s[sentsofar:])
sentsofar = sentsofar + sent
left = left - sent
sock.close()
if __name__ == "__main__":
if "-client" not in sys.argv:
runserver()
else:
sys.argv.remove("-client")
if len(sys.argv) > 1:
fname = sys.argv[1]
else:
fname = "warn.ini"
runclient(fname)
@@ -1,102 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests MatchFilter.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, types, string
class MatchFilter(logging.Filter):
def __init__(self, **kwargs):
self.dict = kwargs
def matchOne(self, key, value, record):
rv = getattr(record, key)
if key != "name":
if key not in ["message", "msg"]:
return rv == value
else:
return string.find(str(rv), value) >= 0
else:
if rv == value:
return 1
nlen = len(value)
if string.find(rv, value, 0, nlen) != 0:
return 0
if rv[nlen] == ".":
return 1
def matchValue(self, key, record):
vl = self.dict [key]
if type(vl) != types.ListType:
rv = self.matchOne(key, vl, record)
else:
for v in vl:
rv = self.matchOne(key, v, record)
if rv:
break
return rv
def filter(self, record):
rv = 1
for k in self.dict.keys():
if self.matchValue(k, record):
rv = 0
break
return rv
def doLog(logger, n):
logger.debug("Debug %d" % n)
logger.info("Info %d" % n)
logger.warning("Warning %d" % n)
logger.error("Error %d" % n)
logger.critical("Critical %d" % n)
def test():
fmt = logging.Formatter("%(name)-10s %(levelname)-9s %(message)s")
hand = logging.StreamHandler()
hand.setFormatter(fmt)
root = logging.getLogger("")
root.setLevel(logging.DEBUG)
root.addHandler(hand)
loggers = ['A',
'A.B',
'A.BB',
'A.C',
'AA.B',
'A.B.C',
'A.B.C.D',
'A.B.C.D.E',
'Z.A.B',
]
filt = MatchFilter(name = ['A.C', 'A.B.C'], #reject these loggers and their children
levelno = [logging.WARNING, logging.CRITICAL], #reject these levels,
msg = 'bug 2' #reject if this in message
)
hand.addFilter(filt)
for log in loggers:
doLog(logging.getLogger(log), loggers.index(log))
if __name__ == "__main__":
test()
@@ -1,57 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. A basic test of parents.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging
def main():
logging.basicConfig()
root = logging.getLogger("")
ab = logging.getLogger("a.b")
abc = logging.getLogger("a.b.c")
root.setLevel(logging.ERROR)
ab.setLevel(logging.INFO)
abc.info("Info")
abc.warning("Warning")
abc.error("Error")
print "abc = %s" % abc
print "abc.parent = %s" % abc.parent
print "ab = %s" % ab
print "ab.parent = %s" % ab.parent
print "root = %s" % root
if __name__ == "__main__":
import sys
print sys.argv[0]
args = sys.argv[1:]
if "-profile" in args:
import profile, pstats
args.remove("-profile")
statf = "log_test19.pro"
profile.run("main()", statf)
stats = pstats.Stats(statf)
stats.strip_dirs().sort_stats('time').print_stats()
else:
main()
@@ -1,119 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests logger levels and basic Formatter, and logging to
sockets.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.handlers, socket
msgcount = 0
def nextmessage():
global msgcount
rv = "Message %d" % msgcount
msgcount = msgcount + 1
return rv
def main():
logging.basicConfig()
logging.getLogger("").setLevel(logging.DEBUG)
hdlr = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
if __name__ == "__main__":
hdlr.setFormatter(logging.Formatter("%(asctime)s %(name)-19s %(levelname)-5s - %(message)s"))
logging.getLogger("").addHandler(hdlr)
ERR = logging.getLogger("ERR")
ERR.setLevel(logging.ERROR)
INF = logging.getLogger("INF")
INF.setLevel(logging.INFO)
INF_ERR = logging.getLogger("INF.ERR")
INF_ERR.setLevel(logging.ERROR)
DEB = logging.getLogger("DEB")
DEB.setLevel(logging.DEBUG)
INF_UNDEF = logging.getLogger("INF.UNDEF")
INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF")
UNDEF = logging.getLogger("UNDEF")
GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF")
CHILD = logging.getLogger("INF.BADPARENT")
#These should log
ERR.log(logging.CRITICAL, nextmessage())
ERR.error(nextmessage())
INF.log(logging.CRITICAL, nextmessage())
INF.error(nextmessage())
INF.warning(nextmessage())
INF.info(nextmessage())
INF_UNDEF.log(logging.CRITICAL, nextmessage())
INF_UNDEF.error(nextmessage())
INF_UNDEF.warning(nextmessage())
INF_UNDEF.info(nextmessage())
INF_ERR.log(logging.CRITICAL, nextmessage())
INF_ERR.error(nextmessage())
INF_ERR_UNDEF.log(logging.CRITICAL, nextmessage())
INF_ERR_UNDEF.error(nextmessage())
DEB.log(logging.CRITICAL, nextmessage())
DEB.error(nextmessage())
DEB.warning(nextmessage())
DEB.info(nextmessage())
DEB.debug(nextmessage())
UNDEF.log(logging.CRITICAL, nextmessage())
UNDEF.error(nextmessage())
UNDEF.warning(nextmessage())
UNDEF.info(nextmessage())
GRANDCHILD.log(logging.CRITICAL, nextmessage())
CHILD.log(logging.CRITICAL, nextmessage())
#These should not log
ERR.warning(nextmessage())
ERR.info(nextmessage())
ERR.debug(nextmessage())
INF.debug(nextmessage())
INF_UNDEF.debug(nextmessage())
INF_ERR.warning(nextmessage())
INF_ERR.info(nextmessage())
INF_ERR.debug(nextmessage())
INF_ERR_UNDEF.warning(nextmessage())
INF_ERR_UNDEF.info(nextmessage())
INF_ERR_UNDEF.debug(nextmessage())
INF.info("Messages should bear numbers 0 through 24.")
hdlr.close()
logging.getLogger("").removeHandler(hdlr)
if __name__ == "__main__":
try:
main()
except socket.error:
print "\nA socket error occurred. Ensure that logrecv.py is running to receive logging requests from this script."
@@ -1,84 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. Demonstrates the use of custom class
instances for messages and filtering based on classes.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging
class MyClass:
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
def __str__(self):
return "%s, %s" % (self.arg1, self.arg2)
class MyChildClass(MyClass):
pass
class ClassFilter(logging.Filter):
def __init__(self, klass):
self.klass = klass
def filter(self, record):
return isinstance(record.msg, self.klass)
class MyClassFilter(ClassFilter):
def __init__(self, arg):
ClassFilter.__init__(self, MyClass)
self.arg = arg
def filter(self, record):
return ClassFilter.filter(self, record) and (record.msg.arg2 == self.arg)
def main():
handler = logging.StreamHandler()
root = logging.getLogger("")
root.setLevel(logging.DEBUG)
root.addHandler(handler)
root.addFilter(MyClassFilter("world"))
#Not logged, as it's not a MyClass instance
root.info("%s, %s", "Hello", "world")
#Logged, as it's an appropriate instance which matches the filter criteria
root.info(MyClass("Hello", "world"))
#Not logged, as it's an appropriate class but doesn't match the filter criteria
root.info(MyClass("Hello", "world!"))
#Logged, as it's an appropriate instance which matches the filter criteria
root.info(MyClass("Goodbye", "world"))
#Logged, as it's an appropriate class which matches the filter criteria
root.info(MyChildClass("Hello again", "world"))
if __name__ == "__main__":
import sys
args = sys.argv[1:]
if "-profile" in args:
import profile, pstats
args.remove("-profile")
statf = "log_test20.pro"
profile.run("main()", statf)
stats = pstats.Stats(statf)
stats.strip_dirs().sort_stats('time').print_stats()
else:
main()
@@ -1,141 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. Demonstrates the use of a wildcard
name-space filter with and without custom message classes.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, re, string, types
class TaggedEvent:
def __init__(self, tag, msg):
self.tag = tag
self.msg = msg
def __str__(self):
return "%s: %s" % (self.tag, self.msg)
class WildcardFilter(logging.Filter):
def __init__(self, wildcards):
self.setWildcards(wildcards)
def setWildcard(self, wildcard):
arr = string.split(wildcard, ".")
for i in xrange(len(arr)):
s = arr[i]
if s == "*":
arr[i] = r'[\w.]*'
elif string.find(s, "*") > 0:
arr[i] = string.replace(s, "*", r'[\w]*')
s = "^%s$" % string.join(arr, r'\.')
self.patterns.append(re.compile(s))
def setWildcards(self, wildcards):
if type(wildcards) != types.ListType:
wildcards = [wildcards]
self.patterns = []
for wildcard in wildcards:
self.setWildcard(wildcard)
def filter(self, record):
rv = 0
for pat in self.patterns:
m = pat.match(record.name)
if m is not None:
rv = 1
break
return rv
class TagFilter(WildcardFilter):
def filter(self, record):
rv = 0
if isinstance(record.msg, TaggedEvent):
tag = record.msg.tag
else:
tag = record.name
for pat in self.patterns:
m = pat.match(tag)
if m is not None:
rv = 1
break
return rv
def main():
handler = logging.StreamHandler()
root = logging.getLogger("")
root.setLevel(logging.DEBUG)
ab = logging.getLogger("a.b")
abc = logging.getLogger("a.b.c")
root.addHandler(handler)
filter = WildcardFilter("*.b")
handler.addFilter(filter)
ab.info("#1 from a.b") #logged
abc.info("#1 from a.b.c") #not logged
filter.setWildcards("*.b.c")
ab.info("#2 from a.b") #not logged
abc.info("#2 from a.b.c") #logged
filter.setWildcards("*.b*")
ab.info("#3 from a.b") #logged
abc.info("#3 from a.b.c") #not logged
filter.setWildcards("*")
ab.info("#4 from a.b") #logged
abc.info("#4 from a.b.c") #logged
filter.setWildcards("a*")
ab.info("#5 from a.b") #not logged
abc.info("#5 from a.b.c") #not logged
filter.setWildcards("a.*")
ab.info("#6 from a.b") #logged
abc.info("#6 from a.b.c") #logged
filter.setWildcards("*.b.*")
ab.info("#7 from a.b") #not logged
abc.info("#7 from a.b.c") #logged
filter.setWildcards(["*.b", "*.b.*"])
ab.info("#8 from a.b") #logged
abc.info("#8 from a.b.c") #logged
filter.setWildcards(["a.*.c"])
ab.info("#9 from a.b") #not logged
abc.info("#9 from a.b.c") #logged
#Now test filtering with a tagged class
handler.removeFilter(filter)
tagfilter = TagFilter(["*.b", "*.b.*"])
root.addFilter(tagfilter)
root.info(TaggedEvent("a.b", "#10")) #logged
root.info(TaggedEvent("a.c", "#10")) #not logged
root.info(TaggedEvent("a.b.c", "#10")) #logged
root.info(TaggedEvent("a.b.d", "#10")) #logged
if __name__ == "__main__":
import sys
args = sys.argv[1:]
if "-profile" in args:
import profile, pstats
args.remove("-profile")
statf = "log_test21.pro"
profile.run("main()", statf)
stats = pstats.Stats(statf)
stats.strip_dirs().sort_stats('time').print_stats()
else:
main()
@@ -1,50 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""Test harness for the logging module. Demonstrates the use of different
converters for time(secs) -> time(tuple).
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, time
def main():
handler = logging.StreamHandler()
f1 = logging.Formatter("%(asctime)s %(message)s", "%m/%d %H:%M:%S")
f2 = logging.Formatter("%(asctime)s %(message)s", "%m/%d %H:%M:%S")
f2.converter = time.gmtime
handler.setFormatter(f1)
root = logging.getLogger("")
root.setLevel(logging.DEBUG)
root.addHandler(handler)
root.info("Something happened! [should be in local time]")
handler.setFormatter(f2)
root.info("Something else happened! [should be in GMT]")
handler.setFormatter(f1)
root.info("Something happened again! [should be in local time]")
logging.Formatter.converter = time.gmtime
root.info("Something else happened again! [should be in GMT]")
logging.Formatter.converter = time.localtime
root.info("Something else happened yet again! [should be in local time]")
if __name__ == "__main__":
main()
@@ -1,95 +0,0 @@
[loggers]
keys=root,area1,area11,area111,area1111,area11111,area111111
[handlers]
keys=console,file,socket,datagram,syslog,NT,SMTP
[formatters]
keys=short,medium,long
[logger_root]
handlers=console
level=DEBUG
[logger_area1]
level=DEBUG
qualname=log02
handlers=file
[logger_area11]
level=INFO
qualname=log02.log03
handlers=socket
[logger_area111]
level=WARN
propagate=0
qualname=log02.log03.log04
handlers=datagram
[logger_area1111]
level=ERROR
qualname=log02.log03.log04.log05
handlers=syslog
[logger_area11111]
level=CRITICAL
qualname=log02.log03.log04.log05.log06
handlers=NT
[logger_area111111]
level=WARN
qualname=log02.log03.log04.log05.log06.log07
handlers=SMTP
[handler_console]
class=StreamHandler
formatter=medium
stream=sys.stdout
args=(sys.stdout,)
[handler_file]
class=FileHandler
level=DEBUG
formatter=long
args=('python.log', 'w')
[handler_socket]
class=handlers.SocketHandler
level=INFO
formatter=medium
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
[handler_datagram]
class=handlers.DatagramHandler
level=WARN
formatter=medium
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
[handler_syslog]
class=handlers.SysLogHandler
level=ERROR
formatter=short
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
[handler_NT]
class=handlers.NTEventLogHandler
level=CRITICAL
formatter=medium
args=('Python Application', '', 'Application')
[handler_SMTP]
class=handlers.SMTPHandler
level=WARN
formatter=long
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
[formatter_short]
format=%(message)s
[formatter_long]
format=%(asctime)s %(pathname)s(%(lineno)d): %(levelname)s %(message)s
[formatter_medium]
format=%(asctime)s %(levelname)s %(message)s
datefmt=%m-%d-%Y
@@ -1,70 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests new fileConfig (not yet a complete test).
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.config
def doLog(logger):
logger.debug("Debug")
logger.info("Info")
logger.warning("Warning")
logger.error("Error")
logger.critical("Critical")
def main():
logging.config.fileConfig("log_test3.ini")
logger = logging.getLogger(None)
print "---------------------------------------------------"
print "-- Logging to root; messages appear on console only"
print "---------------------------------------------------"
doLog(logger)
print "----------------------------------------------------------------------"
print "-- Logging to log02; messages appear on console and in file python.log"
print "----------------------------------------------------------------------"
logger = logging.getLogger("log02")
doLog(logger)
print "--------------------------------------------------------------------------"
print "-- Logging to log02.log03; messages appear on console, in file python.log,"
print "-- and at logrecv.py tcp (if running. <= DEBUG messages will not appear)."
print "--------------------------------------------------------------------------"
logger = logging.getLogger("log02.log03")
doLog(logger)
print "-----------------------------------------------------------------------"
print "-- Logging to log02.log03.log04; messages appear only at logrecv.py udp"
print "-- (if running. <= INFO messages will not appear)."
print "-----------------------------------------------------------------------"
logger = logging.getLogger("log02.log03.log04")
doLog(logger)
print "--------------------------------------------------------------------"
print "-- Logging to log02.log03.log04.log05.log06; messages appear at"
print "-- logrecv.py udp (if running. < CRITICAL messages will not appear)."
print "--------------------------------------------------------------------"
logger = logging.getLogger("log02.log03.log04.log05.log06")
doLog(logger)
print "-- All done."
logging.shutdown()
if __name__ == "__main__":
main()
@@ -1,168 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests arbitrary logging levels, filtering, and
use of strftime formatting.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging
import locale, sys
locale.setlocale(locale.LC_ALL, '')
def message(s):
sys.stderr.write("%s\n" % s)
#
# First, we define our levels. There can be as many as you want - the only limitations are that
# they should be integers, the lowest should be > 0 and larger values mean less information being
# logged. If you need specific level values which do not fit into these limitations, you can use
# a mapping dictionary to convert between your application levels and the logging system.
#
SILENT = 10
TACITURN = 9
TERSE = 8
EFFUSIVE = 7
SOCIABLE = 6
VERBOSE = 5
TALKATIVE = 4
GARRULOUS = 3
CHATTERBOX = 2
BORING = 1
LEVEL_RANGE = range(BORING, SILENT + 1)
#
# Next, we define names for our levels. You don't need to do this - in which case the system will
# use "Level n" to denote the text for the level.
#
my_logging_levels = {
SILENT : 'Silent',
TACITURN : 'Taciturn',
TERSE : 'Terse',
EFFUSIVE : 'Effusive',
SOCIABLE : 'Sociable',
VERBOSE : 'Verbose',
TALKATIVE : 'Talkative',
GARRULOUS : 'Garrulous',
CHATTERBOX: 'Chatterbox',
BORING : 'Boring',
}
#
# Now, tell the logging system to associate names with our levels.
#
for lvl in my_logging_levels.keys():
logging.addLevelName(lvl, my_logging_levels[lvl])
#
# Now, define a test function which logs an event at each of our levels.
#
def doLog(log):
for lvl in LEVEL_RANGE:
log.log(lvl, "This should only be seen at the '%s' logging level (or lower)", logging.getLevelName(lvl))
#
# Get the root logger and add a console hander to it, when run as a script.
#
log = logging.getLogger("")
if __name__ == "__main__":
hdlr = logging.StreamHandler()
hdlr.setFormatter(logging.Formatter("%(asctime)s %(message)s", "%X")) #date format is as per the locale
log.addHandler(hdlr)
else:
hdlr = log.handlers[0]
#
# Set the logging level to each different value and call the utility function to log events.
# In the output, you should see that each time round the loop, the logging events actually output
# decreases.
#
for lvl in LEVEL_RANGE:
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
log.setLevel(lvl)
doLog(log)
#
# Now, we demonstrate level filtering at the handler level. Tell the handler defined above
# to filter at level 'SOCIABLE', and repeat the above loop. Compare the output from the two runs.
#
hdlr.setLevel(SOCIABLE)
message("-- Filtering at handler level to SOCIABLE --")
for lvl in LEVEL_RANGE:
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
log.setLevel(lvl)
doLog(log)
hdlr.setLevel(0) #turn off level filtering at the handler
#
# Now, let's demonstrate filtering. Suppose for some perverse reason we only want to print out
# all except GARRULOUS messages. Let's create a filter for this purpose...
#
class SpecificLevelFilter(logging.Filter):
def __init__(self, lvl):
self.level = lvl
def filter(self, record):
return self.level != record.levelno
class GarrulousFilter(SpecificLevelFilter):
def __init__(self):
SpecificLevelFilter.__init__(self, GARRULOUS)
garr = GarrulousFilter()
hdlr.addFilter(garr)
message("-- Filtering using GARRULOUS filter --")
for lvl in LEVEL_RANGE:
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
log.setLevel(lvl)
doLog(log)
#
# Now, let's demonstrate filtering at the logger. This time, use a filter which excludes SOCIABLE
# and TACITURN messages. Note that GARRULOUS events are still excluded.
#
class VerySpecificFilter(logging.Filter):
def filter(self, record):
return record.levelno not in [SOCIABLE, TACITURN]
spec = VerySpecificFilter()
log.addFilter(spec)
message("-- Filtering using specific filter for SOCIABLE, TACITURN --")
for lvl in LEVEL_RANGE:
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
log.setLevel(lvl)
doLog(log)
log.removeFilter(spec)
hdlr.removeFilter(garr)
#Undo the one level which clashes...for regression tests
logging.addLevelName(logging.DEBUG, "DEBUG")
#
# Er...that's it for now
#
if __name__ == "__main__":
print "All done."
logging.shutdown()
@@ -1,44 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests SMTPHandler.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.handlers
MAILHOST = 'beta'
FROM = 'log_test5@yourdomain.com'
TO = ['arkadi_renko']
SUBJECT = 'Test Logging email from Python logging module (non-buffering)'
def main():
log = logging.getLogger("")
log.setLevel(logging.DEBUG)
hdlr = logging.handlers.SMTPHandler(MAILHOST, FROM, TO, SUBJECT)
hdlr.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
log.addHandler(hdlr)
log.info("Test email contents")
log.removeHandler(hdlr)
if __name__ == "__main__":
main()
@@ -1,47 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests NTEventLogHandler.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.handlers
def main():
ntl = logging.handlers.NTEventLogHandler("Python Logging Test")
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
logger.addHandler(ntl)
logger.debug("This is a '%s' message", "Debug")
logger.info("This is a '%s' message", "Info")
logger.warning("This is a '%s' message", "Warning")
logger.error("This is a '%s' message", "Error")
logger.critical("This is a '%s' message", "Critical")
try:
x = 4 / 0
except:
logger.info("This is an %s (or should that be %s?)", "informational exception", "exceptional information", exc_info=1)
logger.exception("This is the same stuff, via a %s", "exception() call")
logger.removeHandler(ntl)
if __name__ == "__main__":
main()
@@ -1,48 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests MemoryHandler.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import sys, logging, logging.handlers
def message(s):
sys.stderr.write("%s\n" % s)
sh = logging.StreamHandler()
mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
logger.addHandler(mh)
message("-- logging at DEBUG, nothing should be seen yet --")
logger.debug("Debug message")
message("-- logging at INFO, nothing should be seen yet --")
logger.info("Info message")
message("-- logging at WARNING, 3 messages should be seen --")
logger.warning("Warning message")
for i in xrange(102):
message("-- logging %d at level INFO, messages should be seen every 10 events --" % i)
logger.info("Info index = %d", i)
sh.close()
mh.close()
logger.removeHandler(mh)
@@ -1,69 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests FileHandler rollover.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.handlers
import locale
locale.setlocale(locale.LC_ALL, '')
sequence = 0
def doLog(logger):
global sequence
sequence = sequence + 1
logger.debug("%6d This message should be at level %d - %s", sequence,\
logging.DEBUG, logging.getLevelName(logging.DEBUG))
sequence = sequence + 1
logger.info("%6d This message should be at level %d - %s", sequence,
logging.INFO, logging.getLevelName(logging.INFO))
sequence = sequence + 1
logger.warning("%6d This message should be at level %d - %s", sequence,\
logging.WARNING, logging.getLevelName(logging.WARNING))
sequence = sequence + 1
logger.error("%6d This message should be at level %d - %s", sequence,\
logging.ERROR, logging.getLevelName(logging.ERROR))
sequence = sequence + 1
logger.critical("%6d This message should be at level %d - %s", sequence,\
logging.CRITICAL, logging.getLevelName(logging.CRITICAL))
def main():
logger = logging.getLogger("") #root logger
logger.setLevel(logging.DEBUG)
if __name__ == "__main__":
logname = "rollover.log"
else:
logname = "log_test_rollover.log"
hdlr = logging.handlers.RotatingFileHandler(logname, "a", 5000, 3)
if __name__ == "__main__":
fmt = logging.Formatter("%(asctime)s %(levelname)-5s %(message)s", "%x %X")
hdlr.setFormatter(fmt)
logger.addHandler(hdlr)
for i in xrange(100):
doLog(logger)
logger.removeHandler(hdlr)
if __name__ == "__main__":
main()
@@ -1,71 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# This file is part of the Python logging distribution. See
# http://www.red-dove.com/python_logging.html
#
"""
A test harness for the logging module. Tests BufferingHandler, BufferingFormatter.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
import logging, logging.handlers
class XMLFormatter(logging.BufferingFormatter):
"""
A formatter which formats a set of records using XML, using an example DTD called "logging.dtd".
"""
def __init__(self):
fmtstr = """
<event name="%(name)s" level="%(levelno)d" filename="%(filename)s" lineno="%(lineno)d">
<message>%(message)s</message>
</event>"""
logging.BufferingFormatter.__init__(self, logging.Formatter(fmtstr))
# def formatHeader(self, records):
# return """
#<?xml version="1.0" ?><!DOCTYPE eventSet SYSTEM "logging.dtd">
#<eventSet xmlns="http://www.red-dove.com/logging">"""
#
# def formatFooter(self, records):
# return "</eventSet>"
class XMLHandler(logging.handlers.BufferingHandler):
def __init__(self, capacity):
logging.handlers.BufferingHandler.__init__(self, capacity)
self.setFormatter(XMLFormatter())
def flush(self):
if len(self.buffer) > 0:
file = open("events.xml","w")
file.write(self.formatter.format(self.buffer))
file.close()
self.buffer = []
def main():
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
xh = XMLHandler(10)
logger.addHandler(xh)
for i in xrange(100):
logger.info("Info index = %d", i)
xh.close()
logger.removeHandler(xh)
if __name__ == "__main__":
main()
@@ -1,180 +0,0 @@
[loggers]
keys=root,log02,log03,log04,log05,log06,log07
[handlers]
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09
[formatters]
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09
[logger_root]
level=NOTSET
propagate=1
channel=
parent=
qualname=(root)
handlers=hand01
[logger_log02]
level=DEBUG
propagate=1
channel=log02
parent=(root)
qualname=log02
handlers=hand02
[logger_log03]
level=INFO
propagate=1
channel=log03
parent=log02
qualname=log02.log03
handlers=hand03
[logger_log04]
level=WARN
propagate=0
channel=log04
parent=log03
qualname=log02.log03.log04
handlers=hand04
[logger_log05]
level=ERROR
propagate=1
channel=log05
parent=log04
qualname=log02.log03.log04.log05
handlers=hand05
[logger_log06]
level=CRITICAL
propagate=1
channel=log06
parent=log05
qualname=log02.log03.log04.log05.log06
handlers=hand06
[logger_log07]
level=WARN
propagate=1
channel=log07
parent=log06
qualname=log02.log03.log04.log05.log06.log07
handlers=hand07
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
stream=sys.stdout
args=(sys.stdout,)
[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form02
filename=python.log
mode=w
args=('python.log', 'w')
[handler_hand03]
class=handlers.SocketHandler
level=INFO
formatter=form03
host=localhost
port=handlers.DEFAULT_TCP_LOGGING_PORT
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
[handler_hand04]
class=handlers.DatagramHandler
level=WARN
formatter=form04
host=localhost
port=handlers.DEFAULT_UDP_LOGGING_PORT
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
[handler_hand05]
class=handlers.SysLogHandler
level=ERROR
formatter=form05
host=localhost
port=handlers.SYSLOG_UDP_PORT
facility=LOG_USER
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
[handler_hand06]
class=handlers.NTEventLogHandler
level=CRITICAL
formatter=form06
appname=Python Application
dllname=
logtype=Application
args=('Python Application', '', 'Application')
[handler_hand07]
class=handlers.SMTPHandler
level=WARN
formatter=form07
host=localhost
port=25
from=from@abc
to=user1@abc,user2@xyz
subject=Logger Subject
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
[handler_hand08]
class=handlers.MemoryHandler
level=NOTSET
formatter=form08
capacity=10
flushlevel=ERROR
target=
args=(10, ERROR)
[handler_hand09]
class=handlers.HTTPHandler
level=NOTSET
formatter=form09
host=localhost
port=9022
url=/log
method=GET
args=('localhost:9022', '/log', 'GET')
[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form02]
format=F2 %(asctime)s %(pathname)s(%(lineno)d): %(levelname)s %(message)s
datefmt=
[formatter_form03]
format=F3 %(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form04]
format=%(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form05]
format=F5 %(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form06]
format=F6 %(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form07]
format=F7 %(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form08]
format=F8 %(asctime)s %(levelname)s %(message)s
datefmt=
[formatter_form09]
format=F9 %(asctime)s %(levelname)s %(message)s
datefmt=
File diff suppressed because it is too large. Load diff
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Author: Vinay Sajip, Red Dove Consultants Ltd. http://www.red-dove.com/ -->
<!-- THIS IS ONLY A VERY SIMPLE EXAMPLE -->
<!ELEMENT logging:events (logging:event*)>
<!ELEMENT logging:event (logging:message)>
<!ATTLIST logging:event
name CDATA #REQUIRED
level CDATA #REQUIRED
created CDATA #IMPLIED
filename CDATA #IMPLIED
lineno CDATA #IMPLIED
>
<!ELEMENT logging:message (#PCDATA)>
@@ -1,5 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE events SYSTEM "logging.dtd" [<!ENTITY data SYSTEM "events.xml">]>
<events xmlns="http://www.red-dove.com/logging">
&data;
</events>
@@ -1,36 +0,0 @@
[loggers]
keys=root
[handlers]
keys=hand01,hand02
[formatters]
keys=form01
[logger_root]
level=NOTSET
propagate=1
channel=
parent=
qualname=(root)
handlers=hand01,hand02
[handler_hand01]
class=FileHandler
level=NOTSET
formatter=form01
filename=logrecv.log
mode=w
args=('logrecv.log', 'w')
[handler_hand02]
class=StreamHandler
level=NOTSET
formatter=form01
stream=sys.stderr
args=(sys.stderr,)
[formatter_form01]
format=%(asctime)s %(levelname)-9s %(name)-8s %(thread)5s %(message)s
datefmt=
@@ -1,443 +0,0 @@
#! /usr/bin/env python
#
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Vinay Sajip
# not be used in advertising or publicity pertaining to distribution
# of the software without specific, written prior permission.
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
"""
Simple socket-based logging event receiver for use with "logging.py" logging
module.
Should work under Python versions >= 1.5.2, except that source line information
is not available unless 'inspect' is.
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
"""
from select import select
import sys, string, struct, types, cPickle, socket
import logging, logging.handlers, logging.config
TIMEOUT = 10
if sys.platform == "win32":
RESET_ERROR = 10054
else:
RESET_ERROR = 0 #FIXME get correct value for Unix...
logging.raiseExceptions = 1
#
# TCP receiver
#
from SocketServer import ThreadingTCPServer, StreamRequestHandler
class LogRecordStreamHandler(StreamRequestHandler):
"""
Handler for a streaming logging request. It basically logs the record
using whatever logging policy is configured locally.
"""
def handle(self):
"""
Handle multiple requests - each expected to be a 4-byte length,
followed by the LogRecord in pickle format. Logs the record
according to whatever policy is configured locally.
"""
while 1:
try:
chunk = self.connection.recv(4)
if len(chunk) < 4:
break
slen = struct.unpack(">L", chunk)[0]
chunk = self.connection.recv(slen)
while len(chunk) < slen:
chunk = chunk + self.connection.recv(slen - len(chunk))
obj = self.unPickle(chunk)
record = logging.makeLogRecord(obj)
self.handleLogRecord(record)
except socket.error, e:
if type(e.args) != types.TupleType:
raise
else:
errcode = e.args[0]
if errcode != RESET_ERROR:
raise
break
def unPickle(self, data):
return cPickle.loads(data)
def handleLogRecord(self, record):
#if a name is specified, we use the named logger rather than the one
#implied by the record. This is so test harnesses don't get into
#endless loops (particularly log_test.py, which has this code and the
#client code in the same Python instance)
if self.server.logname is not None:
name = self.server.logname
else:
name = record.name
logger = logging.getLogger(name)
logger.handle(record)
class LogRecordSocketReceiver(ThreadingTCPServer):
"""
A simple-minded TCP socket-based logging receiver suitable for test
purposes.
"""
allow_reuse_address = 1
def __init__(self, host='localhost', port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
handler=LogRecordStreamHandler):
ThreadingTCPServer.__init__(self, (host, port), handler)
self.abort = 0
self.timeout = 1
self.logname = None
def serve_until_stopped(self):
import select
abort = 0
while not abort:
rd, wr, ex = select.select([self.socket.fileno()],
[], [],
self.timeout)
if rd:
self.handle_request()
abort = self.abort
#
# UDP receiver
#
from SocketServer import ThreadingUDPServer, DatagramRequestHandler
class LogRecordDatagramHandler(DatagramRequestHandler):
"""
Handler for a datagram logging request. It basically logs the record using
whatever logging policy is configured locally.
"""
def handle(self):
chunk = self.packet
slen = struct.unpack(">L", chunk[:4])[0]
chunk = chunk[4:]
assert len(chunk) == slen
obj = self.unPickle(chunk)
record = logging.LogRecord(None, None, "", 0, "", (), None)
record.__dict__.update(obj)
self.handleLogRecord(record)
def unPickle(self, data):
return cPickle.loads(data)
def handleLogRecord(self, record):
#if a name is specified, we use the named logger rather than the one
#implied by the record. This is so test harnesses don't get into
#endless loops (particularly log_test.py, which has this code and the
#client code in the same Python instance)
if self.server.logname is not None:
name = self.server.logname
else:
name = record.name
logger = logging.getLogger(name)
logger.handle(record)
def finish(self):
pass
class LogRecordDatagramReceiver(ThreadingUDPServer):
"""
A simple-minded UDP datagram-based logging receiver suitable for test
purposes.
"""
allow_reuse_address = 1
def __init__(self, host='localhost', port=logging.handlers.DEFAULT_UDP_LOGGING_PORT,
handler=LogRecordDatagramHandler):
ThreadingUDPServer.__init__(self, (host, port), handler)
self.abort = 0
self.timeout = 1
self.logname = None
def serve_until_stopped(self):
import select
abort = 0
while not abort:
rd, wr, ex = select.select([self.socket.fileno()],
[], [],
self.timeout)
if rd:
self.handle_request()
abort = self.abort
#
# HTTP receiver
#
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import cgi
class LogRecordHTTPHandler(BaseHTTPRequestHandler):
def makeDict(self, fs):
dict = {}
for mfs in fs.list:
dict[mfs.name] = mfs.value
for key in ["args", "exc_info", "exc_text", "lineno", "msecs", "created",
"thread", "levelno", "relativeCreated"]:
if dict.has_key(key):
dict[key] = eval(dict[key])
return dict
def do_GET(self):
"""Serve a GET request."""
sts = "OK"
env = { 'REQUEST_METHOD' : 'GET'}
try:
i = string.find(self.path, '?')
if i >= 0:
env['QUERY_STRING'] = self.path[i + 1:]
fs = cgi.FieldStorage(environ=env)
dict = self.makeDict(fs)
record = logging.LogRecord(None, None, "", 0, "", (), None)
record.__dict__.update(dict)
self.handleLogRecord(record)
except Exception, e:
sts = "ERROR"
raise
self.send_head()
self.wfile.write("GET %s" % sts)
def handleLogRecord(self, record):
#if a name is specified, we use the named logger rather than the one
#implied by the record. This is so test harnesses don't get into
#endless loops (particularly log_test.py, which has this code and the
#client code in the same Python instance)
if self.server.logname is not None:
name = self.server.logname
else:
name = record.name
logger = logging.getLogger(name)
logger.handle(record)
def do_HEAD(self):
"""Serve a HEAD request."""
self.send_head()
def do_POST(self):
"""Serve a POST request."""
sts = "OK"
env = { 'REQUEST_METHOD' : 'POST'}
try:
length = self.headers.getheader('content-length')
if length:
env['CONTENT_LENGTH'] = length
#print self.headers
i = string.find(self.path, '?')
if i >= 0:
env['QUERY_STRING'] = self.path[i + 1:]
fs = cgi.FieldStorage(fp=self.rfile, environ=env)
dict = self.makeDict(fs)
record = logging.LogRecord(None, None, "", 0, "", (), None)
record.__dict__.update(dict)
self.handleLogRecord(record)
except Exception, e:
print e
sys.stdout.flush()
sts = "ERROR"
raise
self.send_head()
self.wfile.write("POST %s" % sts)
def send_head(self):
"""Common code for GET and HEAD commands.
This sends the response code and MIME headers.
Return value is either a file object (which has to be copied
to the outputfile by the caller unless the command was HEAD,
and must be closed by the caller under all circumstances), or
None, in which case the caller has nothing further to do.
"""
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
def log_message(self, *args):
#comment out the following line if you don't want to show requests
#apply(BaseHTTPRequestHandler.log_message, (self,) + args)
pass
class LogRecordHTTPReceiver(HTTPServer):
def __init__(self, host='localhost', port=logging.handlers.DEFAULT_HTTP_LOGGING_PORT,
handler=LogRecordHTTPHandler):
HTTPServer.__init__(self, (host, port), handler)
self.abort = 0
self.timeout = 1
self.logname = None
def serve_until_stopped(self):
import select
abort = 0
while not abort:
rd, wr, ex = select.select([self.socket.fileno()],
[], [],
self.timeout)
if rd:
self.handle_request()
abort = self.abort
#
# SOAP receiver
#
try:
from ZSI import dispatch
logname = None
def log(args, created, exc_info, exc_text, filename, levelname, levelno, lineno, module, msecs, msg, name, pathname, process, relativeCreated, thread):
record = logging.LogRecord(None, None, "", 0, "", (), None)
record.args = eval(args)
record.exc_info = eval(exc_info)
record.exc_text = eval(exc_text)
record.created = created
record.filename = filename
record.module = module
record.levelname = levelname
record.lineno = lineno
record.levelno = levelno
record.msecs = msecs
record.msg = msg
record.name = name
record.pathname = pathname
record.process = process
record.relativeCreated = relativeCreated
record.thread = thread
#if a name is specified, we use the named logger rather than the one
#implied by the record. This is so test harnesses don't get into
#endless loops (particularly log_test.py, which has this code and the
#client code in the same Python instance)
if logname is not None:
lname = logname
else:
lname = name
logger = logging.getLogger(lname)
logger.handle(record)
class MySOAPRequestHandler(dispatch.SOAPRequestHandler):
def log_message(self, *args):
#comment out the following line if you don't want to show requests
#apply(BaseHTTPRequestHandler.log_message, (self,) + args)
pass
class SOAPServer(HTTPServer):
def __init__(self, port=logging.handlers.DEFAULT_SOAP_LOGGING_PORT):
address = ('', port)
HTTPServer.__init__(self, address, MySOAPRequestHandler)
self.abort = 0
self.timeout = 1
self.logname = None
self.docstyle = 0
self.nsdict = {}
self.typesmodule = None
self.rpc = 1
self.modules = (sys.modules["__main__"],)
def serve_until_stopped(self):
import select
abort = 0
while not abort:
rd, wr, ex = select.select([self.socket.fileno()],
[], [],
self.timeout)
if rd:
global logname
logname = self.logname
self.handle_request()
abort = self.abort
except ImportError:
"Import failed"
SOAPServer = None
def runTCP(tcpserver=None):
if not tcpserver:
tcpserver = LogRecordSocketReceiver()
print "About to start TCP server..."
tcpserver.serve_until_stopped()
def runUDP(udpserver=None):
if not udpserver:
udpserver = LogRecordDatagramReceiver()
print "About to start UDP server..."
udpserver.serve_until_stopped()
def runHTTP(httpserver=None):
if not httpserver:
httpserver = LogRecordHTTPReceiver()
print "About to start HTTP server..."
httpserver.serve_until_stopped()
def runSOAP(soapserver=None):
if not SOAPServer:
print "Sorry, ZSI is not available. Install PyXML-0.6.6 and ZSI first."
print "See README.txt and python_logging.html for more information."
else:
if not soapserver:
soapserver = SOAPServer()
print "About to start SOAP server..."
soapserver.serve_until_stopped()
FORMAT_STR = "%(asctime)s %(name)-19s %(levelname)-5s - %(message)s"
if __name__ == "__main__":
if (len(sys.argv) < 2) or not (string.lower(sys.argv[1]) in \
["udp", "tcp", "http", "soap"]):
print "usage: logrecv.py [UDP|TCP|HTTP|SOAP]"
else:
#logging.basicConfig()
logging.config.fileConfig("logrecv.ini")
# both = string.lower(sys.argv[1]) == "both"
# hdlr = logging.FileHandler("test.log")
# hdlr.setFormatter(logging.Formatter(FORMAT_STR))
# logging.getLogger("").addHandler(hdlr)
# if both:
# import threading
# tcpthread = threading.Thread(target=runTCP)
# udpthread = threading.Thread(target=runUDP)
# tcpthread.start()
# udpthread.start()
# tcpthread.join()
# udpthread.join()
# else:
# tcp = string.lower(sys.argv[1]) == "tcp"
# if tcp:
# runTCP()
# else:
# runUDP()
arg = string.lower(sys.argv[1])
if arg == "tcp":
runTCP()
elif arg == "udp":
runUDP()
elif arg == "http":
runHTTP()
elif arg == "soap":
runSOAP()
@@ -1,13 +0,0 @@
import logging, mymodule
logging.basicConfig()
log = logging.getLogger("MyApp")
log.setLevel(logging.DEBUG) #set verbosity to show all messages of severity >= DEBUG
log.info("Starting my app")
try:
mymodule.doIt()
except Exception, e:
log.exception("There was a problem.")
log.info("Ending my app")
@@ -1,8 +0,0 @@
import logging
log = logging.getLogger("MyModule")
def doIt():
log.debug("Doin' stuff...")
#do stuff...
raise TypeError, "Bogus type error for testing"
@@ -1,566 +0,0 @@
-- log_test0 begin --------------------------------------------------------
CRITICAL:ERR:Message 0
ERROR:ERR:Message 1
CRITICAL:INF:Message 2
ERROR:INF:Message 3
WARNING:INF:Message 4
INFO:INF:Message 5
CRITICAL:INF.UNDEF:Message 6
ERROR:INF.UNDEF:Message 7
WARNING:INF.UNDEF:Message 8
INFO:INF.UNDEF:Message 9
CRITICAL:INF.ERR:Message 10
ERROR:INF.ERR:Message 11
CRITICAL:INF.ERR.UNDEF:Message 12
ERROR:INF.ERR.UNDEF:Message 13
CRITICAL:DEB:Message 14
ERROR:DEB:Message 15
WARNING:DEB:Message 16
INFO:DEB:Message 17
DEBUG:DEB:Message 18
CRITICAL:UNDEF:Message 19
ERROR:UNDEF:Message 20
WARNING:UNDEF:Message 21
INFO:UNDEF:Message 22
CRITICAL:INF.BADPARENT.UNDEF:Message 23
CRITICAL:INF.BADPARENT:Message 24
INFO:INF:Messages should bear numbers 0 through 24.
-- log_test0 end --------------------------------------------------------
-- log_test2 begin --------------------------------------------------------
CRITICAL:ERR:Message 0
ERROR:ERR:Message 1
CRITICAL:INF:Message 2
ERROR:INF:Message 3
WARNING:INF:Message 4
INFO:INF:Message 5
CRITICAL:INF.UNDEF:Message 6
ERROR:INF.UNDEF:Message 7
WARNING:INF.UNDEF:Message 8
INFO:INF.UNDEF:Message 9
CRITICAL:INF.ERR:Message 10
ERROR:INF.ERR:Message 11
CRITICAL:INF.ERR.UNDEF:Message 12
ERROR:INF.ERR.UNDEF:Message 13
CRITICAL:DEB:Message 14
ERROR:DEB:Message 15
WARNING:DEB:Message 16
INFO:DEB:Message 17
DEBUG:DEB:Message 18
CRITICAL:UNDEF:Message 19
ERROR:UNDEF:Message 20
WARNING:UNDEF:Message 21
INFO:UNDEF:Message 22
CRITICAL:INF.BADPARENT.UNDEF:Message 23
CRITICAL:INF.BADPARENT:Message 24
INFO:INF:Messages should bear numbers 0 through 24.
-- log_test2 end --------------------------------------------------------
CRITICAL:ERR:Message 0
ERROR:ERR:Message 1
CRITICAL:INF:Message 2
ERROR:INF:Message 3
WARNING:INF:Message 4
INFO:INF:Message 5
CRITICAL:INF.UNDEF:Message 6
ERROR:INF.UNDEF:Message 7
WARNING:INF.UNDEF:Message 8
INFO:INF.UNDEF:Message 9
CRITICAL:INF.ERR:Message 10
ERROR:INF.ERR:Message 11
CRITICAL:INF.ERR.UNDEF:Message 12
ERROR:INF.ERR.UNDEF:Message 13
CRITICAL:DEB:Message 14
ERROR:DEB:Message 15
WARNING:DEB:Message 16
INFO:DEB:Message 17
DEBUG:DEB:Message 18
CRITICAL:UNDEF:Message 19
ERROR:UNDEF:Message 20
WARNING:UNDEF:Message 21
INFO:UNDEF:Message 22
CRITICAL:INF.BADPARENT.UNDEF:Message 23
CRITICAL:INF.BADPARENT:Message 24
INFO:INF:Messages should bear numbers 0 through 24.
-- log_test4 begin --------------------------------------------------------
-- setting logging level to 'Boring' -----
Boring:root:This should only be seen at the 'Boring' logging level (or lower)
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Chatterbox' -----
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Garrulous' -----
Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Talkative' -----
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Verbose' -----
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Sociable' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Effusive' -----
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Terse' -----
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Taciturn' -----
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Silent' -----
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- Filtering at handler level to SOCIABLE --
-- setting logging level to 'Boring' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Chatterbox' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Garrulous' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Talkative' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Verbose' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Sociable' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Effusive' -----
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Terse' -----
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Taciturn' -----
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Silent' -----
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- Filtering using GARRULOUS filter --
-- setting logging level to 'Boring' -----
Boring:root:This should only be seen at the 'Boring' logging level (or lower)
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Chatterbox' -----
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Garrulous' -----
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Talkative' -----
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Verbose' -----
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Sociable' -----
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Effusive' -----
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Terse' -----
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Taciturn' -----
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Silent' -----
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- Filtering using specific filter for SOCIABLE, TACITURN --
-- setting logging level to 'Boring' -----
Boring:root:This should only be seen at the 'Boring' logging level (or lower)
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Chatterbox' -----
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Garrulous' -----
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Talkative' -----
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Verbose' -----
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Sociable' -----
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Effusive' -----
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Terse' -----
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Taciturn' -----
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- setting logging level to 'Silent' -----
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- log_test4 end --------------------------------------------------------
-- log_test7 begin --------------------------------------------------------
-- logging at DEBUG, nothing should be seen yet --
-- logging at INFO, nothing should be seen yet --
-- logging at WARNING, 3 messages should be seen --
Debug message
Info message
Warning message
-- logging 0 at level INFO, messages should be seen every 10 events --
-- logging 1 at level INFO, messages should be seen every 10 events --
-- logging 2 at level INFO, messages should be seen every 10 events --
-- logging 3 at level INFO, messages should be seen every 10 events --
-- logging 4 at level INFO, messages should be seen every 10 events --
-- logging 5 at level INFO, messages should be seen every 10 events --
-- logging 6 at level INFO, messages should be seen every 10 events --
-- logging 7 at level INFO, messages should be seen every 10 events --
-- logging 8 at level INFO, messages should be seen every 10 events --
-- logging 9 at level INFO, messages should be seen every 10 events --
Info index = 0
Info index = 1
Info index = 2
Info index = 3
Info index = 4
Info index = 5
Info index = 6
Info index = 7
Info index = 8
Info index = 9
-- logging 10 at level INFO, messages should be seen every 10 events --
-- logging 11 at level INFO, messages should be seen every 10 events --
-- logging 12 at level INFO, messages should be seen every 10 events --
-- logging 13 at level INFO, messages should be seen every 10 events --
-- logging 14 at level INFO, messages should be seen every 10 events --
-- logging 15 at level INFO, messages should be seen every 10 events --
-- logging 16 at level INFO, messages should be seen every 10 events --
-- logging 17 at level INFO, messages should be seen every 10 events --
-- logging 18 at level INFO, messages should be seen every 10 events --
-- logging 19 at level INFO, messages should be seen every 10 events --
Info index = 10
Info index = 11
Info index = 12
Info index = 13
Info index = 14
Info index = 15
Info index = 16
Info index = 17
Info index = 18
Info index = 19
-- logging 20 at level INFO, messages should be seen every 10 events --
-- logging 21 at level INFO, messages should be seen every 10 events --
-- logging 22 at level INFO, messages should be seen every 10 events --
-- logging 23 at level INFO, messages should be seen every 10 events --
-- logging 24 at level INFO, messages should be seen every 10 events --
-- logging 25 at level INFO, messages should be seen every 10 events --
-- logging 26 at level INFO, messages should be seen every 10 events --
-- logging 27 at level INFO, messages should be seen every 10 events --
-- logging 28 at level INFO, messages should be seen every 10 events --
-- logging 29 at level INFO, messages should be seen every 10 events --
Info index = 20
Info index = 21
Info index = 22
Info index = 23
Info index = 24
Info index = 25
Info index = 26
Info index = 27
Info index = 28
Info index = 29
-- logging 30 at level INFO, messages should be seen every 10 events --
-- logging 31 at level INFO, messages should be seen every 10 events --
-- logging 32 at level INFO, messages should be seen every 10 events --
-- logging 33 at level INFO, messages should be seen every 10 events --
-- logging 34 at level INFO, messages should be seen every 10 events --
-- logging 35 at level INFO, messages should be seen every 10 events --
-- logging 36 at level INFO, messages should be seen every 10 events --
-- logging 37 at level INFO, messages should be seen every 10 events --
-- logging 38 at level INFO, messages should be seen every 10 events --
-- logging 39 at level INFO, messages should be seen every 10 events --
Info index = 30
Info index = 31
Info index = 32
Info index = 33
Info index = 34
Info index = 35
Info index = 36
Info index = 37
Info index = 38
Info index = 39
-- logging 40 at level INFO, messages should be seen every 10 events --
-- logging 41 at level INFO, messages should be seen every 10 events --
-- logging 42 at level INFO, messages should be seen every 10 events --
-- logging 43 at level INFO, messages should be seen every 10 events --
-- logging 44 at level INFO, messages should be seen every 10 events --
-- logging 45 at level INFO, messages should be seen every 10 events --
-- logging 46 at level INFO, messages should be seen every 10 events --
-- logging 47 at level INFO, messages should be seen every 10 events --
-- logging 48 at level INFO, messages should be seen every 10 events --
-- logging 49 at level INFO, messages should be seen every 10 events --
Info index = 40
Info index = 41
Info index = 42
Info index = 43
Info index = 44
Info index = 45
Info index = 46
Info index = 47
Info index = 48
Info index = 49
-- logging 50 at level INFO, messages should be seen every 10 events --
-- logging 51 at level INFO, messages should be seen every 10 events --
-- logging 52 at level INFO, messages should be seen every 10 events --
-- logging 53 at level INFO, messages should be seen every 10 events --
-- logging 54 at level INFO, messages should be seen every 10 events --
-- logging 55 at level INFO, messages should be seen every 10 events --
-- logging 56 at level INFO, messages should be seen every 10 events --
-- logging 57 at level INFO, messages should be seen every 10 events --
-- logging 58 at level INFO, messages should be seen every 10 events --
-- logging 59 at level INFO, messages should be seen every 10 events --
Info index = 50
Info index = 51
Info index = 52
Info index = 53
Info index = 54
Info index = 55
Info index = 56
Info index = 57
Info index = 58
Info index = 59
-- logging 60 at level INFO, messages should be seen every 10 events --
-- logging 61 at level INFO, messages should be seen every 10 events --
-- logging 62 at level INFO, messages should be seen every 10 events --
-- logging 63 at level INFO, messages should be seen every 10 events --
-- logging 64 at level INFO, messages should be seen every 10 events --
-- logging 65 at level INFO, messages should be seen every 10 events --
-- logging 66 at level INFO, messages should be seen every 10 events --
-- logging 67 at level INFO, messages should be seen every 10 events --
-- logging 68 at level INFO, messages should be seen every 10 events --
-- logging 69 at level INFO, messages should be seen every 10 events --
Info index = 60
Info index = 61
Info index = 62
Info index = 63
Info index = 64
Info index = 65
Info index = 66
Info index = 67
Info index = 68
Info index = 69
-- logging 70 at level INFO, messages should be seen every 10 events --
-- logging 71 at level INFO, messages should be seen every 10 events --
-- logging 72 at level INFO, messages should be seen every 10 events --
-- logging 73 at level INFO, messages should be seen every 10 events --
-- logging 74 at level INFO, messages should be seen every 10 events --
-- logging 75 at level INFO, messages should be seen every 10 events --
-- logging 76 at level INFO, messages should be seen every 10 events --
-- logging 77 at level INFO, messages should be seen every 10 events --
-- logging 78 at level INFO, messages should be seen every 10 events --
-- logging 79 at level INFO, messages should be seen every 10 events --
Info index = 70
Info index = 71
Info index = 72
Info index = 73
Info index = 74
Info index = 75
Info index = 76
Info index = 77
Info index = 78
Info index = 79
-- logging 80 at level INFO, messages should be seen every 10 events --
-- logging 81 at level INFO, messages should be seen every 10 events --
-- logging 82 at level INFO, messages should be seen every 10 events --
-- logging 83 at level INFO, messages should be seen every 10 events --
-- logging 84 at level INFO, messages should be seen every 10 events --
-- logging 85 at level INFO, messages should be seen every 10 events --
-- logging 86 at level INFO, messages should be seen every 10 events --
-- logging 87 at level INFO, messages should be seen every 10 events --
-- logging 88 at level INFO, messages should be seen every 10 events --
-- logging 89 at level INFO, messages should be seen every 10 events --
Info index = 80
Info index = 81
Info index = 82
Info index = 83
Info index = 84
Info index = 85
Info index = 86
Info index = 87
Info index = 88
Info index = 89
-- logging 90 at level INFO, messages should be seen every 10 events --
-- logging 91 at level INFO, messages should be seen every 10 events --
-- logging 92 at level INFO, messages should be seen every 10 events --
-- logging 93 at level INFO, messages should be seen every 10 events --
-- logging 94 at level INFO, messages should be seen every 10 events --
-- logging 95 at level INFO, messages should be seen every 10 events --
-- logging 96 at level INFO, messages should be seen every 10 events --
-- logging 97 at level INFO, messages should be seen every 10 events --
-- logging 98 at level INFO, messages should be seen every 10 events --
-- logging 99 at level INFO, messages should be seen every 10 events --
Info index = 90
Info index = 91
Info index = 92
Info index = 93
Info index = 94
Info index = 95
Info index = 96
Info index = 97
Info index = 98
Info index = 99
-- logging 100 at level INFO, messages should be seen every 10 events --
-- logging 101 at level INFO, messages should be seen every 10 events --
Info index = 100
Info index = 101
-- log_test7 end --------------------------------------------------------
-- log_test8 begin --------------------------------------------------------
-- log_test8 end --------------------------------------------------------
-- log_test9 begin --------------------------------------------------------
-- log_test9 end --------------------------------------------------------
-- log_test10 begin --------------------------------------------------------
logger not derived from logging.Logger: NotALogger
INFO:mylogger:Starting...
DEBUG:mylogger:Debug message not in exception handler (no traceback)
INFO:mylogger:About to throw exception...
DEBUG:mylogger:Debug message inside exception handler (traceback)
Traceback (most recent call last):
File "C:\Projects\RDC\Python\packages\logging\test\log_test10.py", line 77, in run
print "7" + 4
TypeError: cannot concatenate 'str' and 'int' objects
INFO:mylogger:Done.
-- log_test10 end --------------------------------------------------------
-- log_test12 begin --------------------------------------------------------
INFO:log_test12:Jackdaws love my big sphinx of quartz
INFO:log_test12:Jackdaws love my big sphinx of quartz
DEBUG:log_test12:Pack my box with twelve dozen liquor jugs
DEBUG:log_test12:Pack my box with twelve dozen liquor jugs
-- log_test12 end --------------------------------------------------------
-- log_test13 begin --------------------------------------------------------
INFO:log_test13:Jackdaws love my big sphinx of quartz
DEBUG:log_test13:Pack my box with five dozen liquor jugs
-- log_test13 end --------------------------------------------------------
-- log_test15 begin --------------------------------------------------------
Unfiltered...
INFO:a:Info 1
INFO:a.b:Info 2
INFO:a.c:Info 3
INFO:a.b.c:Info 4
INFO:a.b.c.d:Info 5
INFO:a.bb.c:Info 6
INFO:b:Info 7
INFO:b.a:Info 8
INFO:c.a.b:Info 9
INFO:a.bb:Info 10
Filtered with 'a.b'...
INFO:a.b:Info 2
INFO:a.b.c:Info 4
INFO:a.b.c.d:Info 5
-- log_test15 end --------------------------------------------------------
@@ -1,24 +0,0 @@
About to start TCP server...
About to start UDP server...
About to start HTTP server...
About to start SOAP server...
-- log_test0 begin --------------------------------------------------------
-- log_test0 end --------------------------------------------------------
-- log_test2 begin --------------------------------------------------------
-- log_test2 end --------------------------------------------------------
-- log_test4 begin --------------------------------------------------------
-- log_test4 end --------------------------------------------------------
-- log_test7 begin --------------------------------------------------------
-- log_test7 end --------------------------------------------------------
-- log_test8 begin --------------------------------------------------------
-- log_test8 end --------------------------------------------------------
-- log_test9 begin --------------------------------------------------------
-- log_test9 end --------------------------------------------------------
-- log_test10 begin --------------------------------------------------------
-- log_test10 end --------------------------------------------------------
-- log_test12 begin --------------------------------------------------------
-- log_test12 end --------------------------------------------------------
-- log_test13 begin --------------------------------------------------------
-- log_test13 end --------------------------------------------------------
-- log_test15 begin --------------------------------------------------------
-- log_test15 end --------------------------------------------------------
@@ -1,60 +0,0 @@
[loggers]
keys=root,log02,log03,log04,log05
[handlers]
keys=hand01
[formatters]
keys=form01
[logger_root]
level=WARN
propagate=1
channel=
parent=
qualname=(root)
handlers=hand01
[logger_log02]
level=WARN
propagate=1
channel=A
parent=(root)
qualname=A
handlers=
[logger_log03]
level=WARN
propagate=1
channel=B
parent=log02
qualname=A.B
handlers=
[logger_log04]
level=WARN
propagate=1
channel=C
parent=log03
qualname=A.B.C
handlers=
[logger_log05]
level=WARN
propagate=1
channel=D
parent=log04
qualname=A.B.C.D
handlers=
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
stream=sys.stderr
args=(sys.stderr,)
[formatter_form01]
format=warn.ini %(name)s %(levelname)s %(message)s
datefmt=
-11
View File
@@ -1,11 +0,0 @@
#============================================================================
# Install the logging package from python 2.3 if not present.
#============================================================================
import os
try:
import logging
except ImportError:
print 'logging package not found: installing'
os.chdir('logging-0.4.9.2')
execfile('setup.py')
-44
View File
@@ -1,44 +0,0 @@
/******************************************************************************
* ptsname.c
*
* A python extension to expose the POSIX ptsname() function.
*
* Copyright (C) 2007 XenSource Ltd
*/
#include <Python.h>
#include <stdlib.h>
/* Needed for Python versions earlier than 2.3. */
#ifndef PyMODINIT_FUNC
#define PyMODINIT_FUNC DL_EXPORT(void)
#endif
static PyObject *do_ptsname(PyObject *self, PyObject *args)
{
int fd;
char *path;
if (!PyArg_ParseTuple(args, "i", &fd))
return NULL;
path = ptsname(fd);
if (!path)
{
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
return PyString_FromString(path);
}
static PyMethodDef ptsname_methods[] = {
{ "ptsname", do_ptsname, METH_VARARGS },
{ NULL }
};
PyMODINIT_FUNC initptsname(void)
{
Py_InitModule("ptsname", ptsname_methods);
}
+2 -93
View File
@@ -27,58 +27,6 @@ xs = Extension("xs",
depends = [ PATH_XENSTORE + "/libxenstore.so" ],
sources = [ "xen/lowlevel/xs/xs.c" ])
scf = Extension("scf",
extra_compile_args = extra_compile_args,
include_dirs = [ "xen/lowlevel/scf" ],
library_dirs = [ ],
libraries = [ ],
depends = [ ],
sources = [ "xen/lowlevel/scf/scf.c" ])
process = Extension("process",
extra_compile_args = extra_compile_args,
include_dirs = [ "xen/lowlevel/process" ],
library_dirs = [ ],
libraries = [ "contract" ],
depends = [ ],
sources = [ "xen/lowlevel/process/process.c" ])
flask = Extension("flask",
extra_compile_args = extra_compile_args,
include_dirs = [ PATH_XEN, PATH_LIBXC, "xen/lowlevel/flask" ],
library_dirs = [ PATH_LIBXC ],
libraries = [ "xenctrl" ],
depends = [ PATH_LIBXC + "/libxenctrl.so" ],
sources = [ "xen/lowlevel/flask/flask.c" ])
ptsname = Extension("ptsname",
extra_compile_args = extra_compile_args,
include_dirs = [ "ptsname" ],
library_dirs = [ ],
libraries = [ ],
depends = [ ],
sources = [ "ptsname/ptsname.c" ])
checkpoint = Extension("checkpoint",
extra_compile_args = extra_compile_args,
include_dirs = [ PATH_XEN, PATH_LIBXC, PATH_XENSTORE ],
library_dirs = [ PATH_LIBXC, PATH_XENSTORE ],
libraries = [ "xenctrl", "xenguest", "xenstore", "rt" ],
depends = [ PATH_LIBXC + "/libxenctrl.so",
PATH_LIBXC + "/libxenguest.so",
PATH_XENSTORE + "/libxenstore.so" ],
sources = [ "xen/lowlevel/checkpoint/checkpoint.c",
"xen/lowlevel/checkpoint/libcheckpoint.c"])
netlink = Extension("netlink",
extra_compile_args = extra_compile_args,
include_dirs = [ ],
library_dirs = [ ],
libraries = [ ],
depends = [ ],
sources = [ "xen/lowlevel/netlink/netlink.c",
"xen/lowlevel/netlink/libnetlink.c"])
xl = Extension("xl",
extra_compile_args = extra_compile_args,
include_dirs = [ PATH_XEN, PATH_LIBXL, PATH_LIBXC, "xen/lowlevel/xl" ],
@@ -88,54 +36,15 @@ xl = Extension("xl",
sources = [ "xen/lowlevel/xl/xl.c", "xen/lowlevel/xl/_pyxl_types.c" ])
plat = os.uname()[0]
modules = [ xc, xs, ptsname, flask ]
modules = [ xc, xs ]
#modules.extend([ xl ])
if plat == 'SunOS':
modules.extend([ scf, process ])
if plat == 'Linux':
modules.extend([ checkpoint, netlink ])
enable_xend = True
new_argv = []
for arg in sys.argv:
if arg == "--xend=y":
enable_xend = True
elif arg == "--xend=n":
enable_xend = False
else:
new_argv.append(arg)
sys.argv = new_argv
if enable_xend:
xend_packages = [
'xen.util',
'xen.util.xsm',
'xen.util.xsm.dummy',
'xen.util.xsm.flask',
'xen.util.xsm.acm',
'xen.xend',
'xen.xend.server',
'xen.xend.xenstore',
'xen.xm',
'xen.web',
'xen.remus',
'xen.xend.tests',
'xen.xend.server.tests',
'xen.xend.xenstore.tests',
'xen.xm.tests'
]
else:
xend_packages = []
setup(name = 'xen',
version = '3.0',
description = 'Xen',
packages = ['xen',
'xen.lowlevel',
] + xend_packages,
],
ext_package = "xen.lowlevel",
ext_modules = modules
)
os.chdir('logging')
execfile('setup.py')
@@ -1,371 +0,0 @@
/* python bridge to checkpointing API */
#include <Python.h>
#include <xenstore.h>
#include <xenctrl.h>
#include "checkpoint.h"
#define PKG "xen.lowlevel.checkpoint"
static PyObject* CheckpointError;
typedef struct {
PyObject_HEAD
checkpoint_state cps;
/* milliseconds between checkpoints */
unsigned int interval;
int armed;
PyObject* suspend_cb;
PyObject* postcopy_cb;
PyObject* checkpoint_cb;
PyThreadState* threadstate;
} CheckpointObject;
static int suspend_trampoline(void* data);
static int postcopy_trampoline(void* data);
static int checkpoint_trampoline(void* data);
static PyObject* Checkpoint_new(PyTypeObject* type, PyObject* args,
PyObject* kwargs)
{
CheckpointObject* self = (CheckpointObject*)type->tp_alloc(type, 0);
if (!self)
return NULL;
checkpoint_init(&self->cps);
self->suspend_cb = NULL;
self->armed = 0;
return (PyObject*)self;
}
static int Checkpoint_init(PyObject* obj, PyObject* args, PyObject* kwargs)
{
return 0;
}
static void Checkpoint_dealloc(CheckpointObject* self)
{
checkpoint_close(&self->cps);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject* pycheckpoint_open(PyObject* obj, PyObject* args)
{
CheckpointObject* self = (CheckpointObject*)obj;
checkpoint_state* cps = &self->cps;
unsigned int domid;
if (!PyArg_ParseTuple(args, "I", &domid))
return NULL;
if (checkpoint_open(cps, domid) < 0) {
PyErr_SetString(CheckpointError, checkpoint_error(cps));
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* pycheckpoint_close(PyObject* obj, PyObject* args)
{
CheckpointObject* self = (CheckpointObject*)obj;
if (checkpoint_resume(&self->cps) < 0)
fprintf(stderr, "%s\n", checkpoint_error(&self->cps));
checkpoint_close(&self->cps);
Py_XDECREF(self->suspend_cb);
self->suspend_cb = NULL;
Py_XDECREF(self->postcopy_cb);
self->postcopy_cb = NULL;
Py_XDECREF(self->checkpoint_cb);
self->checkpoint_cb = NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* pycheckpoint_start(PyObject* obj, PyObject* args) {
CheckpointObject* self = (CheckpointObject*)obj;
PyObject* iofile;
PyObject* suspend_cb = NULL;
PyObject* postcopy_cb = NULL;
PyObject* checkpoint_cb = NULL;
unsigned int interval = 0;
unsigned int flags = 0;
int fd;
struct save_callbacks callbacks;
int rc;
if (!PyArg_ParseTuple(args, "O|OOOII", &iofile, &suspend_cb, &postcopy_cb,
&checkpoint_cb, &interval, &flags))
return NULL;
self->interval = interval;
Py_INCREF(iofile);
Py_XINCREF(suspend_cb);
Py_XINCREF(postcopy_cb);
Py_XINCREF(checkpoint_cb);
fd = PyObject_AsFileDescriptor(iofile);
Py_DECREF(iofile);
if (fd < 0) {
PyErr_SetString(PyExc_TypeError, "invalid file handle");
return NULL;
}
if (suspend_cb && suspend_cb != Py_None) {
if (!PyCallable_Check(suspend_cb)) {
PyErr_SetString(PyExc_TypeError, "suspend callback not callable");
goto err;
}
self->suspend_cb = suspend_cb;
} else
self->suspend_cb = NULL;
if (postcopy_cb && postcopy_cb != Py_None) {
if (!PyCallable_Check(postcopy_cb)) {
PyErr_SetString(PyExc_TypeError, "postcopy callback not callable");
return NULL;
}
self->postcopy_cb = postcopy_cb;
} else
self->postcopy_cb = NULL;
if (checkpoint_cb && checkpoint_cb != Py_None) {
if (!PyCallable_Check(checkpoint_cb)) {
PyErr_SetString(PyExc_TypeError, "checkpoint callback not callable");
return NULL;
}
self->checkpoint_cb = checkpoint_cb;
} else
self->checkpoint_cb = NULL;
memset(&callbacks, 0, sizeof(callbacks));
callbacks.suspend = suspend_trampoline;
callbacks.postcopy = postcopy_trampoline;
callbacks.checkpoint = checkpoint_trampoline;
callbacks.data = self;
self->threadstate = PyEval_SaveThread();
rc = checkpoint_start(&self->cps, fd, &callbacks, flags);
PyEval_RestoreThread(self->threadstate);
if (rc < 0) {
PyErr_SetString(CheckpointError, checkpoint_error(&self->cps));
goto err;
}
Py_INCREF(Py_None);
return Py_None;
err:
self->suspend_cb = NULL;
Py_XDECREF(suspend_cb);
self->postcopy_cb = NULL;
Py_XDECREF(postcopy_cb);
self->checkpoint_cb = NULL;
Py_XDECREF(checkpoint_cb);
return NULL;
}
static PyMethodDef Checkpoint_methods[] = {
{ "open", pycheckpoint_open, METH_VARARGS,
"open connection to xen" },
{ "close", pycheckpoint_close, METH_NOARGS,
"close connection to xen" },
{ "start", pycheckpoint_start, METH_VARARGS | METH_KEYWORDS,
"begin a checkpoint" },
{ NULL, NULL, 0, NULL }
};
static PyTypeObject CheckpointType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
PKG ".checkpointer", /* tp_name */
sizeof(CheckpointObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Checkpoint_dealloc, /* tp_dealloc */
NULL, /* tp_print */
NULL, /* 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 */
NULL, /* tp_call */
NULL, /* tp_str */
NULL, /* tp_getattro */
NULL, /* tp_setattro */
NULL, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"Checkpoint object", /* tp_doc */
NULL, /* tp_traverse */
NULL, /* tp_clear */
NULL, /* tp_richcompare */
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
Checkpoint_methods, /* tp_methods */
NULL, /* tp_members */
NULL, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
NULL, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Checkpoint_init, /* tp_init */
NULL, /* tp_alloc */
Checkpoint_new, /* tp_new */
};
static PyMethodDef methods[] = {
{ NULL }
};
static char doc[] = "checkpoint API";
PyMODINIT_FUNC initcheckpoint(void) {
PyObject *m;
if (PyType_Ready(&CheckpointType) < 0)
return;
m = Py_InitModule3(PKG, methods, doc);
if (!m)
return;
Py_INCREF(&CheckpointType);
PyModule_AddObject(m, "checkpointer", (PyObject*)&CheckpointType);
CheckpointError = PyErr_NewException(PKG ".error", NULL, NULL);
Py_INCREF(CheckpointError);
PyModule_AddObject(m, "error", CheckpointError);
block_timer();
}
/* private functions */
/* bounce C suspend call into python equivalent.
* returns 1 on success or 0 on failure */
static int suspend_trampoline(void* data)
{
CheckpointObject* self = (CheckpointObject*)data;
PyObject* result;
/* call default suspend function, then python hook if available */
if (self->armed) {
if (checkpoint_wait(&self->cps) < 0) {
fprintf(stderr, "%s\n", checkpoint_error(&self->cps));
return 0;
}
} else {
if (self->interval) {
self->armed = 1;
checkpoint_settimer(&self->cps, self->interval);
}
if (!checkpoint_suspend(&self->cps)) {
fprintf(stderr, "%s\n", checkpoint_error(&self->cps));
return 0;
}
}
if (!self->suspend_cb)
return 1;
PyEval_RestoreThread(self->threadstate);
result = PyObject_CallFunction(self->suspend_cb, NULL);
self->threadstate = PyEval_SaveThread();
if (!result)
return 0;
if (result == Py_None || PyObject_IsTrue(result)) {
Py_DECREF(result);
return 1;
}
Py_DECREF(result);
return 0;
}
static int postcopy_trampoline(void* data)
{
CheckpointObject* self = (CheckpointObject*)data;
PyObject* result;
int rc = 0;
if (!self->postcopy_cb)
goto resume;
PyEval_RestoreThread(self->threadstate);
result = PyObject_CallFunction(self->postcopy_cb, NULL);
if (result && (result == Py_None || PyObject_IsTrue(result)))
rc = 1;
Py_XDECREF(result);
self->threadstate = PyEval_SaveThread();
resume:
if (checkpoint_resume(&self->cps) < 0) {
fprintf(stderr, "%s\n", checkpoint_error(&self->cps));
return 0;
}
return rc;
}
static int checkpoint_trampoline(void* data)
{
CheckpointObject* self = (CheckpointObject*)data;
PyObject* result;
if (checkpoint_postflush(&self->cps) < 0) {
fprintf(stderr, "%s\n", checkpoint_error(&self->cps));
return -1;
}
if (!self->checkpoint_cb)
return 0;
PyEval_RestoreThread(self->threadstate);
result = PyObject_CallFunction(self->checkpoint_cb, NULL);
self->threadstate = PyEval_SaveThread();
if (!result)
return 0;
if (result == Py_None || PyObject_IsTrue(result)) {
Py_DECREF(result);
return 1;
}
Py_DECREF(result);
return 0;
}
@@ -1,61 +0,0 @@
/* API for checkpointing */
#ifndef _CHECKPOINT_H_
#define _CHECKPOINT_H_ 1
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <xenguest.h>
#include <xenstore.h>
typedef enum {
dt_unknown,
dt_pv,
dt_hvm,
dt_pvhvm /* HVM with PV drivers */
} checkpoint_domtype;
typedef struct {
xc_interface *xch;
xc_evtchn *xce; /* event channel handle */
struct xs_handle* xsh; /* xenstore handle */
int watching_shutdown; /* state of watch on @releaseDomain */
unsigned int domid;
checkpoint_domtype domtype;
int fd;
int suspend_evtchn, suspend_lockfd;
char* errstr;
/* suspend deadline thread support */
volatile int suspended;
volatile int done;
pthread_t suspend_thr;
sem_t suspended_sem;
sem_t resumed_sem;
timer_t timer;
} checkpoint_state;
#define CHECKPOINT_FLAGS_COMPRESSION 1
char* checkpoint_error(checkpoint_state* s);
void checkpoint_init(checkpoint_state* s);
int checkpoint_open(checkpoint_state* s, unsigned int domid);
void checkpoint_close(checkpoint_state* s);
int checkpoint_start(checkpoint_state* s, int fd,
struct save_callbacks* callbacks,
unsigned int remus_flags);
int checkpoint_suspend(checkpoint_state* s);
int checkpoint_resume(checkpoint_state* s);
int checkpoint_postflush(checkpoint_state* s);
int checkpoint_settimer(checkpoint_state* s, int millis);
int checkpoint_wait(checkpoint_state* s);
void block_timer(void);
void unblock_timer(void);
#endif
@@ -1,850 +0,0 @@
/* API for checkpointing */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include <xenctrl.h>
#include <xenguest.h>
#include <xenstore.h>
#include "checkpoint.h"
static char errbuf[256];
static int setup_suspend_evtchn(checkpoint_state* s);
static void release_suspend_evtchn(checkpoint_state *s);
static int setup_shutdown_watch(checkpoint_state* s);
static int check_shutdown(checkpoint_state* s);
static void release_shutdown_watch(checkpoint_state* s);
static int evtchn_suspend(checkpoint_state* s);
static int compat_suspend(checkpoint_state* s);
static int pollfd(checkpoint_state* s, int fd);
static int switch_qemu_logdirty(checkpoint_state* s, int enable);
static int suspend_hvm(checkpoint_state* s);
static int suspend_qemu(checkpoint_state* s);
static int resume_qemu(checkpoint_state* s);
static int send_qemu(checkpoint_state* s);
static int create_suspend_timer(checkpoint_state* s);
static int delete_suspend_timer(checkpoint_state* s);
static int create_suspend_thread(checkpoint_state* s);
static void stop_suspend_thread(checkpoint_state* s);
/* Returns a string describing the most recent error returned by
* a checkpoint function. Static -- do not free. */
char* checkpoint_error(checkpoint_state* s)
{
return s->errstr;
}
void checkpoint_init(checkpoint_state* s)
{
s->xch = NULL;
s->xce = NULL;
s->xsh = NULL;
s->watching_shutdown = 0;
s->domid = 0;
s->domtype = dt_unknown;
s->fd = -1;
s->suspend_evtchn = -1;
s->suspend_lockfd = -1;
s->errstr = NULL;
s->suspended = 0;
s->done = 0;
s->suspend_thr = 0;
s->timer = 0;
}
/* open a checkpoint session to guest domid */
int checkpoint_open(checkpoint_state* s, unsigned int domid)
{
xc_dominfo_t dominfo;
unsigned long pvirq;
s->domid = domid;
s->xch = xc_interface_open(0,0,0);
if (!s->xch) {
s->errstr = "could not open control interface (are you root?)";
return -1;
}
s->xsh = xs_daemon_open();
if (!s->xsh) {
checkpoint_close(s);
s->errstr = "could not open xenstore handle";
return -1;
}
s->xce = xc_evtchn_open(NULL, 0);
if (s->xce == NULL) {
checkpoint_close(s);
s->errstr = "could not open event channel handle";
return -1;
}
if (xc_domain_getinfo(s->xch, s->domid, 1, &dominfo) < 0) {
checkpoint_close(s);
s->errstr = "could not get domain info";
return -1;
}
if (dominfo.hvm) {
if (xc_get_hvm_param(s->xch, s->domid, HVM_PARAM_CALLBACK_IRQ, &pvirq)) {
checkpoint_close(s);
s->errstr = "could not get HVM callback IRQ";
return -1;
}
s->domtype = pvirq ? dt_pvhvm : dt_hvm;
} else
s->domtype = dt_pv;
if (setup_shutdown_watch(s) < 0) {
checkpoint_close(s);
return -1;
}
if (s->domtype == dt_pv) {
if (setup_suspend_evtchn(s) < 0) {
fprintf(stderr, "WARNING: suspend event channel unavailable, "
"falling back to slow xenstore signalling\n");
}
} else if (s->domtype == dt_pvhvm) {
checkpoint_close(s);
s->errstr = "PV-on-HVM is unsupported";
return -1;
}
return 0;
}
void checkpoint_close(checkpoint_state* s)
{
if (s->timer)
delete_suspend_timer(s);
if (s->suspend_thr)
stop_suspend_thread(s);
release_shutdown_watch(s);
release_suspend_evtchn(s);
if (s->xch) {
xc_interface_close(s->xch);
s->xch = NULL;
}
if (s->xce != NULL) {
xc_evtchn_close(s->xce);
s->xce = NULL;
}
if (s->xsh) {
xs_daemon_close(s->xsh);
s->xsh = NULL;
}
s->domid = 0;
s->fd = -1;
}
/* we toggle logdirty ourselves around the xc_domain_save call --
* it avoids having to pass around checkpoint_state */
static int noop_switch_logdirty(int domid, unsigned enable, void *data)
{
return 0;
}
int checkpoint_start(checkpoint_state* s, int fd,
struct save_callbacks* callbacks,
unsigned int remus_flags)
{
int hvm, rc;
int flags = XCFLAGS_LIVE;
unsigned long vm_generationid_addr;
if (!s->domid) {
s->errstr = "checkpoint state not opened";
return -1;
}
s->fd = fd;
hvm = s->domtype > dt_pv;
if (hvm) {
char path[128];
char *addr;
sprintf(path, "/local/domain/%u/hvmloader/generation-id-address", s->domid);
addr = xs_read(s->xsh, XBT_NULL, path, NULL);
vm_generationid_addr = (addr) ? strtoul(addr, NULL, 0) : 0;
free(addr);
flags |= XCFLAGS_HVM;
if (switch_qemu_logdirty(s, 1))
return -1;
} else {
vm_generationid_addr = 0;
}
if (remus_flags & CHECKPOINT_FLAGS_COMPRESSION)
flags |= XCFLAGS_CHECKPOINT_COMPRESS;
callbacks->switch_qemu_logdirty = noop_switch_logdirty;
rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm,
vm_generationid_addr);
if (hvm)
switch_qemu_logdirty(s, 0);
return rc;
}
/* suspend the domain. Returns 0 on failure, 1 on success */
int checkpoint_suspend(checkpoint_state* s)
{
struct timeval tv;
int rc;
gettimeofday(&tv, NULL);
fprintf(stderr, "PROF: suspending at %lu.%06lu\n", (unsigned long)tv.tv_sec,
(unsigned long)tv.tv_usec);
if (s->suspend_evtchn >= 0)
rc = evtchn_suspend(s);
else if (s->domtype == dt_hvm)
rc = suspend_hvm(s);
else
rc = compat_suspend(s);
return rc < 0 ? 0 : 1;
}
/* wait for a suspend to be triggered by another thread */
int checkpoint_wait(checkpoint_state* s)
{
int rc;
if (!s->suspend_thr) {
s->errstr = "checkpoint timer is not active\n";
return -1;
}
do {
rc = sem_wait(&s->suspended_sem);
if (rc < 0 && errno != EINTR) {
snprintf(errbuf, sizeof(errbuf),
"error waiting for suspend semaphore: %d %d\n", rc, errno);
s->errstr = errbuf;
return -1;
}
} while (rc < 0);
if (!s->suspended) {
snprintf(errbuf, sizeof(errbuf), "domain not suspended?\n");
s->errstr = errbuf;
return -1;
}
return 0;
}
/* let guest execution resume */
int checkpoint_resume(checkpoint_state* s)
{
struct timeval tv;
int rc;
if (xc_domain_resume(s->xch, s->domid, 1)) {
snprintf(errbuf, sizeof(errbuf), "error resuming domain: %d", errno);
s->errstr = errbuf;
return -1;
}
gettimeofday(&tv, NULL);
fprintf(stderr, "PROF: resumed at %lu.%06lu\n", (unsigned long)tv.tv_sec,
(unsigned long)tv.tv_usec);
if (s->domtype > dt_pv && resume_qemu(s) < 0)
return -1;
/* restore watchability in xenstore */
if (xs_resume_domain(s->xsh, s->domid) < 0)
fprintf(stderr, "error resuming domain in xenstore\n");
s->suspended = 0;
if (s->suspend_thr) {
if ((rc = sem_post(&s->resumed_sem)))
fprintf(stderr, "error posting resume semaphore\n");
}
return 0;
}
/* called after xc_domain_save has flushed its buffer */
int checkpoint_postflush(checkpoint_state *s)
{
if (s->domtype > dt_pv && send_qemu(s) < 0)
return -1;
return 0;
}
/* force suspend within millis ms if copy hasn't completed yet */
int checkpoint_settimer(checkpoint_state* s, int millis)
{
struct itimerspec t;
int err;
if (!s->suspend_thr) {
if (create_suspend_timer(s) < 0)
return -1;
if (create_suspend_thread(s) < 0) {
delete_suspend_timer(s);
return -1;
}
}
t.it_value.tv_sec = millis / 1000;
t.it_value.tv_nsec = (millis % 1000) * 1000000L;
t.it_interval.tv_sec = t.it_value.tv_sec;
t.it_interval.tv_nsec = t.it_value.tv_nsec;
if ((err = timer_settime(s->timer, 0, &t, NULL))) {
fprintf(stderr, "Error arming timer: %d\n", err);
return -1;
}
return 0;
}
int delete_suspend_timer(checkpoint_state* s)
{
int rc = 0;
if (s->timer) {
if ((rc = timer_delete(s->timer)))
fprintf(stderr, "Error deleting timer: %s\n", strerror(errno));
s->timer = 0;
}
return rc;
}
/* Set up event channel used to signal a guest to suspend itself */
static int setup_suspend_evtchn(checkpoint_state* s)
{
int port;
port = xs_suspend_evtchn_port(s->domid);
if (port < 0) {
s->errstr = "failed to read suspend event channel";
return -1;
}
s->suspend_evtchn = xc_suspend_evtchn_init_exclusive(s->xch, s->xce,
s->domid, port, &s->suspend_lockfd);
if (s->suspend_evtchn < 0) {
s->errstr = "failed to bind suspend event channel";
return -1;
}
fprintf(stderr, "bound to suspend event channel %u:%d as %d\n", s->domid, port,
s->suspend_evtchn);
return 0;
}
/* release suspend event channels bound to guest */
static void release_suspend_evtchn(checkpoint_state *s)
{
/* TODO: teach xen to clean up if port is unbound */
if (s->xce != NULL && s->suspend_evtchn >= 0) {
xc_suspend_evtchn_release(s->xch, s->xce, s->domid,
s->suspend_evtchn, &s->suspend_lockfd);
s->suspend_evtchn = -1;
}
}
static int setup_shutdown_watch(checkpoint_state* s)
{
char buf[16];
/* write domain ID to watch so we can ignore other domain shutdowns */
snprintf(buf, sizeof(buf), "%u", s->domid);
if ( !xs_watch(s->xsh, "@releaseDomain", buf) ) {
fprintf(stderr, "Could not bind to shutdown watch\n");
return -1;
}
/* watch fires once on registration */
s->watching_shutdown = 1;
check_shutdown(s);
return 0;
}
/* returns -1 on error or death, 0 if domain is running, 1 if suspended */
static int check_shutdown(checkpoint_state* s) {
unsigned int count;
int xsfd;
char **vec;
char buf[16];
xc_dominfo_t info;
xsfd = xs_fileno(s->xsh);
/* loop on watch if it fires for another domain */
while (1) {
if (pollfd(s, xsfd) < 0)
return -1;
vec = xs_read_watch(s->xsh, &count);
if (s->watching_shutdown == 1) {
s->watching_shutdown = 2;
return 0;
}
if (!vec) {
fprintf(stderr, "empty watch fired\n");
continue;
}
snprintf(buf, sizeof(buf), "%d", s->domid);
if (!strcmp(vec[XS_WATCH_TOKEN], buf))
break;
}
if (xc_domain_getinfo(s->xch, s->domid, 1, &info) != 1
|| info.domid != s->domid) {
snprintf(errbuf, sizeof(errbuf),
"error getting info for domain %u", s->domid);
s->errstr = errbuf;
return -1;
}
if (!info.shutdown) {
snprintf(errbuf, sizeof(errbuf),
"domain %u not shut down", s->domid);
s->errstr = errbuf;
return 0;
}
if (info.shutdown_reason != SHUTDOWN_suspend)
return -1;
return 1;
}
static void release_shutdown_watch(checkpoint_state* s) {
char buf[16];
if (!s->xsh)
return;
if (!s->watching_shutdown)
return;
snprintf(buf, sizeof(buf), "%u", s->domid);
if (!xs_unwatch(s->xsh, "@releaseDomain", buf))
fprintf(stderr, "Could not release shutdown watch\n");
s->watching_shutdown = 0;
}
static int evtchn_suspend(checkpoint_state* s)
{
int rc;
rc = xc_evtchn_notify(s->xce, s->suspend_evtchn);
if (rc < 0) {
snprintf(errbuf, sizeof(errbuf),
"failed to notify suspend event channel: %d", rc);
s->errstr = errbuf;
return -1;
}
do
if (!(rc = pollfd(s, xc_evtchn_fd(s->xce))))
rc = xc_evtchn_pending(s->xce);
while (rc >= 0 && rc != s->suspend_evtchn);
if (rc <= 0)
return -1;
if (xc_evtchn_unmask(s->xce, s->suspend_evtchn) < 0) {
snprintf(errbuf, sizeof(errbuf),
"failed to unmask suspend notification channel: %d", rc);
s->errstr = errbuf;
return -1;
}
return 0;
}
/* suspend through xenstore if suspend event channel is unavailable */
static int compat_suspend(checkpoint_state* s)
{
char path[128];
sprintf(path, "/local/domain/%u/control/shutdown", s->domid);
if (!xs_write(s->xsh, XBT_NULL, path, "suspend", 7)) {
s->errstr = "error signalling qemu logdirty";
return -1;
}
if (check_shutdown(s) != 1)
return -1;
return 0;
}
/* returns -1 if fd does not become readable within timeout */
static int pollfd(checkpoint_state* s, int fd)
{
fd_set rfds;
struct timeval tv;
int rc;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 500000;
rc = select(fd + 1, &rfds, NULL, NULL, &tv);
if (rc < 0) {
snprintf(errbuf, sizeof(errbuf),
"error polling fd: %s", strerror(errno));
s->errstr = errbuf;
} else if (!rc) {
snprintf(errbuf, sizeof(errbuf), "timeout polling fd");
s->errstr = errbuf;
} else if (! FD_ISSET(fd, &rfds)) {
snprintf(errbuf, sizeof(errbuf), "unknown error polling fd");
s->errstr = errbuf;
} else
return 0;
return -1;
}
/* adapted from the eponymous function in xc_save */
static int switch_qemu_logdirty(checkpoint_state *s, int enable)
{
char path[128];
char *tail, *cmd, *response;
char **vec;
unsigned int len;
sprintf(path, "/local/domain/0/device-model/%u/logdirty/", s->domid);
tail = path + strlen(path);
strcpy(tail, "ret");
if (!xs_watch(s->xsh, path, "qemu-logdirty-ret")) {
s->errstr = "error watching qemu logdirty return";
return 1;
}
/* null fire. XXX unify with shutdown watch! */
vec = xs_read_watch(s->xsh, &len);
free(vec);
strcpy(tail, "cmd");
cmd = enable ? "enable" : "disable";
if (!xs_write(s->xsh, XBT_NULL, path, cmd, strlen(cmd))) {
s->errstr = "error signalling qemu logdirty";
return 1;
}
vec = xs_read_watch(s->xsh, &len);
free(vec);
strcpy(tail, "ret");
xs_unwatch(s->xsh, path, "qemu-logdirty-ret");
response = xs_read(s->xsh, XBT_NULL, path, &len);
if (!len || strcmp(response, cmd)) {
if (len)
free(response);
s->errstr = "qemu logdirty command failed";
return 1;
}
free(response);
fprintf(stderr, "qemu logdirty mode: %s\n", cmd);
return 0;
}
static int suspend_hvm(checkpoint_state *s)
{
int rc = -1;
fprintf(stderr, "issuing HVM suspend hypercall\n");
rc = xc_domain_shutdown(s->xch, s->domid, SHUTDOWN_suspend);
if (rc < 0) {
s->errstr = "shutdown hypercall failed";
return -1;
}
fprintf(stderr, "suspend hypercall returned %d\n", rc);
if (check_shutdown(s) != 1)
return -1;
rc = suspend_qemu(s);
return rc;
}
static int suspend_qemu(checkpoint_state *s)
{
char path[128];
fprintf(stderr, "pausing QEMU\n");
sprintf(path, "/local/domain/0/device-model/%d/command", s->domid);
if (!xs_write(s->xsh, XBT_NULL, path, "save", 4)) {
fprintf(stderr, "error signalling QEMU to save\n");
return -1;
}
sprintf(path, "/local/domain/0/device-model/%d/state", s->domid);
do {
char* state;
unsigned int len;
state = xs_read(s->xsh, XBT_NULL, path, &len);
if (!state) {
s->errstr = "error reading QEMU state";
return -1;
}
if (!strcmp(state, "paused")) {
free(state);
return 0;
}
free(state);
usleep(1000);
} while(1);
return -1;
}
static int resume_qemu(checkpoint_state *s)
{
char path[128];
fprintf(stderr, "resuming QEMU\n");
sprintf(path, "/local/domain/0/device-model/%d/command", s->domid);
if (!xs_write(s->xsh, XBT_NULL, path, "continue", 8)) {
fprintf(stderr, "error signalling QEMU to resume\n");
return -1;
}
return 0;
}
static int send_qemu(checkpoint_state *s)
{
char buf[8192];
char path[128];
struct stat sb;
uint32_t qlen = 0;
int qfd;
int rc;
if (s->fd < 0)
return -1;
sprintf(path, "/var/lib/xen/qemu-save.%d", s->domid);
if (stat(path, &sb) < 0) {
snprintf(errbuf, sizeof(errbuf),
"error getting QEMU state file status: %s", strerror(errno));
s->errstr = errbuf;
return -1;
}
qlen = sb.st_size;
qfd = open(path, O_RDONLY);
if (qfd < 0) {
snprintf(errbuf, sizeof(errbuf), "error opening QEMU state file: %s",
strerror(errno));
s->errstr = errbuf;
return -1;
}
fprintf(stderr, "Sending %u bytes of QEMU state\n", qlen);
if (write(s->fd, "RemusDeviceModelState", 21) != 21) {
s->errstr = "error writing QEMU header";
close(qfd);
return -1;
}
if (write(s->fd, &qlen, sizeof(qlen)) != sizeof(qlen)) {
s->errstr = "error writing QEMU size";
close(qfd);
return -1;
}
while ((rc = read(qfd, buf, qlen > sizeof(buf) ? sizeof(buf) : qlen)) > 0) {
qlen -= rc;
if (write(s->fd, buf, rc) != rc) {
rc = -1;
break;
}
}
if (rc < 0) {
snprintf(errbuf, sizeof(errbuf), "error writing QEMU state: %s",
strerror(errno));
s->errstr = errbuf;
}
close(qfd);
return rc;
}
/*thread responsible to suspend the domain early if necessary*/
static void *suspend_thread(void *arg)
{
checkpoint_state* s = (checkpoint_state*)arg;
sigset_t tss;
int rc;
int sig;
fprintf(stderr, "Suspend thread started\n");
sigemptyset(&tss);
sigaddset(&tss, SIGRTMIN);
while (1) {
/* wait for checkpoint thread to signal resume */
if ((rc = sem_wait(&s->resumed_sem)))
fprintf(stderr, "Error waiting on resume semaphore\n");
if ((rc = sigwait(&tss, &sig))) {
fprintf(stderr, "sigwait failed: %d %d\n", rc, errno);
break;
}
if (sig != SIGRTMIN)
fprintf(stderr, "received unexpected signal %d\n", sig);
if (s->done)
break;
if (s->suspended) {
fprintf(stderr, "domain already suspended?\n");
} else {
rc = checkpoint_suspend(s);
if (rc)
s->suspended = 1;
else
fprintf(stderr, "checkpoint_suspend failed\n");
}
if ((rc = sem_post(&s->suspended_sem)))
fprintf(stderr, "Error posting suspend semaphore\n");
}
fprintf(stderr, "Suspend thread exiting\n");
return NULL;
}
static int create_suspend_timer(checkpoint_state* s)
{
struct sigevent event;
int err;
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGRTMIN;
event.sigev_value.sival_int = 0;
if ((err = timer_create(CLOCK_REALTIME, &event, &s->timer))) {
snprintf(errbuf, sizeof(errbuf), "Error creating timer: %d\n", err);
s->errstr = errbuf;
return -1;
}
return 0;
}
void block_timer(void)
{
sigset_t tss;
sigemptyset(&tss);
sigaddset(&tss, SIGRTMIN);
pthread_sigmask(SIG_BLOCK, &tss, NULL);
}
void unblock_timer(void)
{
sigset_t tss;
sigemptyset(&tss);
sigaddset(&tss, SIGRTMIN);
pthread_sigmask(SIG_UNBLOCK, &tss, NULL);
}
static int create_suspend_thread(checkpoint_state* s)
{
int err;
if ((err = sem_init(&s->suspended_sem, 0, 0))) {
snprintf(errbuf, sizeof(errbuf),
"Error initializing suspend semaphore: %d\n", err);
s->errstr = errbuf;
return -1;
}
if ((err = sem_init(&s->resumed_sem, 0, 0))) {
snprintf(errbuf, sizeof(errbuf),
"Error initializing resume semaphore: %d\n", err);
s->errstr = errbuf;
return -1;
}
/* signal mask should be inherited */
block_timer();
if ((err = pthread_create(&s->suspend_thr, NULL, suspend_thread, s))) {
snprintf(errbuf, sizeof(errbuf), "Error creating suspend thread: %d\n", err);
s->errstr = errbuf;
return -1;
}
return 0;
}
static void stop_suspend_thread(checkpoint_state* s)
{
int err;
s->done = 1;
err = sem_post(&s->resumed_sem);
err = pthread_join(s->suspend_thr, NULL);
s->suspend_thr = 0;
}
-292
View File
@@ -1,292 +0,0 @@
/******************************************************************************
* flask.c
*
* Authors: George Coker, <gscoker@alpha.ncsc.mil>
* Michael LeMay, <mdlemay@epoch.ncsc.mil>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*/
#include <Python.h>
#include <xenctrl.h>
#define PKG "xen.lowlevel.flask"
#define CLS "flask"
#define CTX_LEN 1024
static PyObject *xc_error_obj;
typedef struct {
PyObject_HEAD;
xc_interface *xc_handle;
} XcObject;
static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
PyObject *kwds)
{
xc_interface *xc_handle;
char *ctx;
char *buf;
uint32_t len;
uint32_t sid;
int ret;
static char *kwd_list[] = { "context", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list,
&ctx) )
return NULL;
len = strlen(ctx);
buf = malloc(len);
if (!buf) {
errno = -ENOMEM;
PyErr_SetFromErrno(xc_error_obj);
}
memcpy(buf, ctx, len);
xc_handle = xc_interface_open(0,0,0);
if (!xc_handle) {
free(buf);
return PyErr_SetFromErrno(xc_error_obj);
}
ret = xc_flask_context_to_sid(xc_handle, buf, len, &sid);
xc_interface_close(xc_handle);
free(buf);
if ( ret != 0 ) {
errno = -ret;
return PyErr_SetFromErrno(xc_error_obj);
}
return PyInt_FromLong(sid);
}
static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args,
PyObject *kwds)
{
xc_interface *xc_handle;
uint32_t sid;
char ctx[CTX_LEN];
uint32_t ctx_len = CTX_LEN;
int ret;
static char *kwd_list[] = { "sid", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list,
&sid) )
return NULL;
xc_handle = xc_interface_open(0,0,0);
if (!xc_handle) {
return PyErr_SetFromErrno(xc_error_obj);
}
ret = xc_flask_sid_to_context(xc_handle, sid, ctx, ctx_len);
xc_interface_close(xc_handle);
if ( ret != 0 ) {
errno = -ret;
return PyErr_SetFromErrno(xc_error_obj);
}
return Py_BuildValue("s", ctx, ctx_len);
}
static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds)
{
xc_interface *xc_handle;
char *policy;
uint32_t len;
int ret;
static char *kwd_list[] = { "policy", NULL };
if( !PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwd_list, &policy, &len) )
return NULL;
xc_handle = xc_interface_open(0,0,0);
if (!xc_handle) {
return PyErr_SetFromErrno(xc_error_obj);
}
ret = xc_flask_load(xc_handle, policy, len);
xc_interface_close(xc_handle);
if ( ret != 0 ) {
errno = -ret;
return PyErr_SetFromErrno(xc_error_obj);
}
return Py_BuildValue("i", ret);
}
static PyObject *pyflask_getenforce(PyObject *self)
{
xc_interface *xc_handle;
int ret;
xc_handle = xc_interface_open(0,0,0);
if (!xc_handle) {
return PyErr_SetFromErrno(xc_error_obj);
}
ret = xc_flask_getenforce(xc_handle);
xc_interface_close(xc_handle);
if ( ret < 0 ) {
errno = -ret;
return PyErr_SetFromErrno(xc_error_obj);
}
return Py_BuildValue("i", ret);
}
static PyObject *pyflask_setenforce(PyObject *self, PyObject *args,
PyObject *kwds)
{
xc_interface *xc_handle;
int mode;
int ret;
static char *kwd_list[] = { "mode", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list,
&mode) )
return NULL;
xc_handle = xc_interface_open(0,0,0);
if (!xc_handle) {
return PyErr_SetFromErrno(xc_error_obj);
}
ret = xc_flask_setenforce(xc_handle, mode);
xc_interface_close(xc_handle);
if ( ret != 0 ) {
errno = -ret;
return PyErr_SetFromErrno(xc_error_obj);
}
return Py_BuildValue("i", ret);
}
static PyObject *pyflask_access(PyObject *self, PyObject *args,
PyObject *kwds)
{
xc_interface *xc_handle;
char *tcon, *scon;
uint16_t tclass;
uint32_t req, allowed, decided, auditallow, auditdeny, seqno;
int ret;
static char *kwd_list[] = { "src_context", "tar_context",
"tar_class", "req_permissions",
"decided", "auditallow","auditdeny",
"seqno", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ssil|llll", kwd_list,
&scon, &tcon, &tclass, &req, &decided,
&auditallow, &auditdeny, &seqno) )
return NULL;
xc_handle = xc_interface_open(0,0,0);
if (!xc_handle) {
return PyErr_SetFromErrno(xc_error_obj);
}
ret = xc_flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided,
&auditallow, &auditdeny, &seqno);
xc_interface_close(xc_handle);
if ( ret != 0 ) {
errno = -ret;
return PyErr_SetFromErrno(xc_error_obj);
}
return Py_BuildValue("i",ret);
}
static PyMethodDef pyflask_methods[] = {
{ "flask_context_to_sid",
(PyCFunction)pyflask_context_to_sid,
METH_KEYWORDS, "\n"
"Convert a context string to a dynamic SID.\n"
" context [str]: String specifying context to be converted\n"
"Returns: [int]: Numeric SID on success; -1 on error.\n" },
{ "flask_sid_to_context",
(PyCFunction)pyflask_sid_to_context,
METH_KEYWORDS, "\n"
"Convert a dynamic SID to context string.\n"
" context [int]: SID to be converted\n"
"Returns: [str]: Numeric SID on success; -1 on error.\n" },
{ "flask_load",
(PyCFunction)pyflask_load,
METH_KEYWORDS, "\n"
"Loads a policy into the hypervisor.\n"
" policy [str]: policy to be load\n"
"Returns: [int]: 0 on success; -1 on failure.\n" },
{ "flask_getenforce",
(PyCFunction)pyflask_getenforce,
METH_NOARGS, "\n"
"Returns the current mode of the Flask XSM module.\n"
"Returns: [int]: 0 for permissive; 1 for enforcing; -1 on failure.\n" },
{ "flask_setenforce",
(PyCFunction)pyflask_setenforce,
METH_KEYWORDS, "\n"
"Modifies the current mode for the Flask XSM module.\n"
" mode [int]: mode to change to\n"
"Returns: [int]: 0 on success; -1 on failure.\n" },
{ "flask_access",
(PyCFunction)pyflask_access,
METH_KEYWORDS, "\n"
"Returns whether a source context has access to target context based on \
class and permissions requested.\n"
" scon [str]: source context\n"
" tcon [str]: target context\n"
" tclass [int]: target security class\n"
" req [int] requested permissions\n"
" allowed [int] permissions allow for the target class between the source \
and target context\n"
" decided [int] the permissions that were returned in the allowed \
parameter\n"
" auditallow [int] permissions set to audit on allow\n"
" auditdeny [int] permissions set to audit on deny\n"
" seqno [int] not used\n"
"Returns: [int]: 0 on all permission granted; -1 if any permissions are \
denied\n" },
{ NULL, NULL, 0, NULL }
};
PyMODINIT_FUNC initflask(void)
{
Py_InitModule("flask", pyflask_methods);
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/
@@ -1,585 +0,0 @@
/*
* libnetlink.c RTnetlink service routines.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <net/if_arp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/uio.h>
#include "libnetlink.h"
void rtnl_close(struct rtnl_handle *rth)
{
close(rth->fd);
}
int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions,
int protocol)
{
socklen_t addr_len;
int sndbuf = 32768;
int rcvbuf = 32768;
memset(rth, 0, sizeof(*rth));
rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
if (rth->fd < 0) {
perror("Cannot open netlink socket");
return -1;
}
if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) {
perror("SO_SNDBUF");
return -1;
}
if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf)) < 0) {
perror("SO_RCVBUF");
return -1;
}
memset(&rth->local, 0, sizeof(rth->local));
rth->local.nl_family = AF_NETLINK;
rth->local.nl_groups = subscriptions;
if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) {
perror("Cannot bind netlink socket");
return -1;
}
addr_len = sizeof(rth->local);
if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) {
perror("Cannot getsockname");
return -1;
}
if (addr_len != sizeof(rth->local)) {
fprintf(stderr, "Wrong address length %d\n", addr_len);
return -1;
}
if (rth->local.nl_family != AF_NETLINK) {
fprintf(stderr, "Wrong address family %d\n", rth->local.nl_family);
return -1;
}
rth->seq = time(NULL);
return 0;
}
int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
{
return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
}
int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
{
struct {
struct nlmsghdr nlh;
struct rtgenmsg g;
} req;
struct sockaddr_nl nladdr;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
memset(&req, 0, sizeof(req));
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_type = type;
req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
req.nlh.nlmsg_pid = 0;
req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
req.g.rtgen_family = family;
return sendto(rth->fd, (void*)&req, sizeof(req), 0,
(struct sockaddr*)&nladdr, sizeof(nladdr));
}
int rtnl_send(struct rtnl_handle *rth, const char *buf, int len)
{
struct sockaddr_nl nladdr;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
}
int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
{
struct nlmsghdr nlh;
struct sockaddr_nl nladdr;
struct iovec iov[2] = {
{ .iov_base = &nlh, .iov_len = sizeof(nlh) },
{ .iov_base = req, .iov_len = len }
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = iov,
.msg_iovlen = 2,
};
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nlh.nlmsg_len = NLMSG_LENGTH(len);
nlh.nlmsg_type = type;
nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
nlh.nlmsg_pid = 0;
nlh.nlmsg_seq = rth->dump = ++rth->seq;
return sendmsg(rth->fd, &msg, 0);
}
int rtnl_dump_filter(struct rtnl_handle *rth,
rtnl_filter_t filter,
void *arg1,
rtnl_filter_t junk,
void *arg2)
{
struct sockaddr_nl nladdr;
struct iovec iov;
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
char buf[16384];
iov.iov_base = buf;
while (1) {
int status;
struct nlmsghdr *h;
iov.iov_len = sizeof(buf);
status = recvmsg(rth->fd, &msg, 0);
if (status < 0) {
if (errno == EINTR)
continue;
perror("OVERRUN");
continue;
}
if (status == 0) {
fprintf(stderr, "EOF on netlink\n");
return -1;
}
h = (struct nlmsghdr*)buf;
while (NLMSG_OK(h, status)) {
int err;
if (nladdr.nl_pid != 0 ||
h->nlmsg_pid != rth->local.nl_pid ||
h->nlmsg_seq != rth->dump) {
if (junk) {
err = junk(&nladdr, h, arg2);
if (err < 0)
return err;
}
goto skip_it;
}
if (h->nlmsg_type == NLMSG_DONE)
return 0;
if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
fprintf(stderr, "ERROR truncated\n");
} else {
errno = -err->error;
perror("RTNETLINK answers");
}
return -1;
}
err = filter(&nladdr, h, arg1);
if (err < 0)
return err;
skip_it:
h = NLMSG_NEXT(h, status);
}
if (msg.msg_flags & MSG_TRUNC) {
fprintf(stderr, "Message truncated\n");
continue;
}
if (status) {
fprintf(stderr, "!!!Remnant of size %d\n", status);
exit(1);
}
}
}
int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
unsigned groups, struct nlmsghdr *answer,
rtnl_filter_t junk,
void *jarg)
{
int status;
unsigned seq;
struct nlmsghdr *h;
struct sockaddr_nl nladdr;
struct iovec iov = {
.iov_base = (void*) n,
.iov_len = n->nlmsg_len
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
char buf[16384];
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = peer;
nladdr.nl_groups = groups;
n->nlmsg_seq = seq = ++rtnl->seq;
if (answer == NULL)
n->nlmsg_flags |= NLM_F_ACK;
status = sendmsg(rtnl->fd, &msg, 0);
if (status < 0) {
perror("Cannot talk to rtnetlink");
return -1;
}
memset(buf,0,sizeof(buf));
iov.iov_base = buf;
while (1) {
iov.iov_len = sizeof(buf);
status = recvmsg(rtnl->fd, &msg, 0);
if (status < 0) {
if (errno == EINTR)
continue;
perror("OVERRUN");
continue;
}
if (status == 0) {
fprintf(stderr, "EOF on netlink\n");
return -1;
}
if (msg.msg_namelen != sizeof(nladdr)) {
fprintf(stderr, "sender address length == %d\n", msg.msg_namelen);
exit(1);
}
for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
int err;
int len = h->nlmsg_len;
int l = len - sizeof(*h);
if (l<0 || len>status) {
if (msg.msg_flags & MSG_TRUNC) {
fprintf(stderr, "Truncated message\n");
return -1;
}
fprintf(stderr, "!!!malformed message: len=%d\n", len);
exit(1);
}
if (nladdr.nl_pid != peer ||
h->nlmsg_pid != rtnl->local.nl_pid ||
h->nlmsg_seq != seq) {
if (junk) {
err = junk(&nladdr, h, jarg);
if (err < 0)
return err;
}
continue;
}
if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
if (l < sizeof(struct nlmsgerr)) {
fprintf(stderr, "ERROR truncated\n");
} else {
errno = -err->error;
if (errno == 0) {
if (answer)
memcpy(answer, h, h->nlmsg_len);
return 0;
}
perror("RTNETLINK answers");
}
return -1;
}
if (answer) {
memcpy(answer, h, h->nlmsg_len);
return 0;
}
fprintf(stderr, "Unexpected reply!!!\n");
status -= NLMSG_ALIGN(len);
h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
}
if (msg.msg_flags & MSG_TRUNC) {
fprintf(stderr, "Message truncated\n");
continue;
}
if (status) {
fprintf(stderr, "!!!Remnant of size %d\n", status);
exit(1);
}
}
}
int rtnl_listen(struct rtnl_handle *rtnl,
rtnl_filter_t handler,
void *jarg)
{
int status;
struct nlmsghdr *h;
struct sockaddr_nl nladdr;
struct iovec iov;
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
char buf[8192];
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0;
nladdr.nl_groups = 0;
iov.iov_base = buf;
while (1) {
iov.iov_len = sizeof(buf);
status = recvmsg(rtnl->fd, &msg, 0);
if (status < 0) {
if (errno == EINTR)
continue;
perror("OVERRUN");
continue;
}
if (status == 0) {
fprintf(stderr, "EOF on netlink\n");
return -1;
}
if (msg.msg_namelen != sizeof(nladdr)) {
fprintf(stderr, "Sender address length == %d\n", msg.msg_namelen);
exit(1);
}
for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
int err;
int len = h->nlmsg_len;
int l = len - sizeof(*h);
if (l<0 || len>status) {
if (msg.msg_flags & MSG_TRUNC) {
fprintf(stderr, "Truncated message\n");
return -1;
}
fprintf(stderr, "!!!malformed message: len=%d\n", len);
exit(1);
}
err = handler(&nladdr, h, jarg);
if (err < 0)
return err;
status -= NLMSG_ALIGN(len);
h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
}
if (msg.msg_flags & MSG_TRUNC) {
fprintf(stderr, "Message truncated\n");
continue;
}
if (status) {
fprintf(stderr, "!!!Remnant of size %d\n", status);
exit(1);
}
}
}
int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler,
void *jarg)
{
int status;
struct sockaddr_nl nladdr;
char buf[8192];
struct nlmsghdr *h = (void*)buf;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0;
nladdr.nl_groups = 0;
while (1) {
int err, len, type;
int l;
status = fread(&buf, 1, sizeof(*h), rtnl);
if (status < 0) {
if (errno == EINTR)
continue;
perror("rtnl_from_file: fread");
return -1;
}
if (status == 0)
return 0;
len = h->nlmsg_len;
type= h->nlmsg_type;
l = len - sizeof(*h);
if (l<0 || len>sizeof(buf)) {
fprintf(stderr, "!!!malformed message: len=%d @%lu\n",
len, ftell(rtnl));
return -1;
}
status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl);
if (status < 0) {
perror("rtnl_from_file: fread");
return -1;
}
if (status < l) {
fprintf(stderr, "rtnl-from_file: truncated message\n");
return -1;
}
err = handler(&nladdr, h, jarg);
if (err < 0)
return err;
}
}
int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
{
int len = RTA_LENGTH(4);
struct rtattr *rta;
if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
fprintf(stderr,"addattr32: Error! max allowed bound %d exceeded\n",maxlen);
return -1;
}
rta = NLMSG_TAIL(n);
rta->rta_type = type;
rta->rta_len = len;
memcpy(RTA_DATA(rta), &data, 4);
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
return 0;
}
int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
int alen)
{
int len = RTA_LENGTH(alen);
struct rtattr *rta;
if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
return -1;
}
rta = NLMSG_TAIL(n);
rta->rta_type = type;
rta->rta_len = len;
memcpy(RTA_DATA(rta), data, alen);
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
return 0;
}
int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len)
{
if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) {
fprintf(stderr, "addraw_l ERROR: message exceeded bound of %d\n",maxlen);
return -1;
}
memcpy(NLMSG_TAIL(n), data, len);
memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len);
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len);
return 0;
}
int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
{
int len = RTA_LENGTH(4);
struct rtattr *subrta;
if (RTA_ALIGN(rta->rta_len) + len > maxlen) {
fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen);
return -1;
}
subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
subrta->rta_type = type;
subrta->rta_len = len;
memcpy(RTA_DATA(subrta), &data, 4);
rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len;
return 0;
}
int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
const void *data, int alen)
{
struct rtattr *subrta;
int len = RTA_LENGTH(alen);
if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) {
fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen);
return -1;
}
subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
subrta->rta_type = type;
subrta->rta_len = len;
memcpy(RTA_DATA(subrta), data, alen);
rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len);
return 0;
}
int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
while (RTA_OK(rta, len)) {
if (rta->rta_type <= max)
tb[rta->rta_type] = rta;
rta = RTA_NEXT(rta,len);
}
if (len)
fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
return 0;
}
int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
int i = 0;
memset(tb, 0, sizeof(struct rtattr *) * max);
while (RTA_OK(rta, len)) {
if (rta->rta_type <= max && i < max)
tb[i++] = rta;
rta = RTA_NEXT(rta,len);
}
if (len)
fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
return i;
}
@@ -1,58 +0,0 @@
#ifndef __LIBNETLINK_H__
#define __LIBNETLINK_H__ 1
#include <netinet/in.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
struct rtnl_handle
{
int fd;
struct sockaddr_nl local;
struct sockaddr_nl peer;
__u32 seq;
__u32 dump;
};
extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);
extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol);
extern void rtnl_close(struct rtnl_handle *rth);
extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
typedef int (*rtnl_filter_t)(const struct sockaddr_nl *,
struct nlmsghdr *n, void *);
extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter,
void *arg1,
rtnl_filter_t junk,
void *arg2);
extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
unsigned groups, struct nlmsghdr *answer,
rtnl_filter_t junk,
void *jarg);
extern int rtnl_send(struct rtnl_handle *rth, const char *buf, int);
extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data);
extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen);
extern int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len);
extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen);
extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len);
#define parse_rtattr_nested(tb, max, rta) \
(parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
extern int rtnl_listen(struct rtnl_handle *, rtnl_filter_t handler,
void *jarg);
extern int rtnl_from_file(FILE *, rtnl_filter_t handler,
void *jarg);
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
#endif /* __LIBNETLINK_H__ */
-215
View File
@@ -1,215 +0,0 @@
/* python binding to libnetlink */
#include <Python.h>
#include "libnetlink.h"
#define PKG "xen.lowlevel.netlink"
typedef struct {
PyObject_HEAD
int opened;
struct rtnl_handle rth;
} PyRtnlObject;
/* todo: subscriptions? */
static PyObject* PyRtnl_new(PyTypeObject* type, PyObject* args,
PyObject* kwargs)
{
return type->tp_alloc(type, 0);
}
static int PyRtnl_init(PyObject* obj, PyObject* args, PyObject* kwargs)
{
PyRtnlObject* self = (PyRtnlObject*)obj;
if (rtnl_open(&self->rth, 0) < 0) {
PyErr_SetString(PyExc_IOError, "could not open rtnl handle");
return -1;
}
return 0;
}
static void PyRtnl_dealloc(PyRtnlObject* obj)
{
PyRtnlObject* self = (PyRtnlObject*)obj;
rtnl_close(&self->rth);
}
static PyObject* pyrtnl_talk(PyObject* obj, PyObject* args)
{
PyRtnlObject* self = (PyRtnlObject*)obj;
char* msg;
int len;
int peer = 0;
int groups = 0;
if (!PyArg_ParseTuple(args, "s#|ii", &msg, &len, &peer, &groups))
return NULL;
if (rtnl_talk(&self->rth, (struct nlmsghdr*)msg, peer, groups, NULL, NULL,
NULL) < 0)
{
PyErr_SetString(PyExc_IOError, "error sending message");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* pyrtnl_wilddump_request(PyObject* obj, PyObject* args)
{
PyRtnlObject* self = (PyRtnlObject*)obj;
int family, type;
if (!PyArg_ParseTuple(args, "ii", &family, &type))
return NULL;
if (rtnl_wilddump_request(&self->rth, family, type) < 0) {
PyErr_SetString(PyExc_IOError, "could not send dump request");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* pyrtnl_dump_request(PyObject* obj, PyObject* args)
{
PyRtnlObject* self = (PyRtnlObject*)obj;
int type;
char* req;
int len;
if (!PyArg_ParseTuple(args, "is#", &type, &req, &len))
return NULL;
if (rtnl_dump_request(&self->rth, type, req, len) < 0) {
PyErr_SetString(PyExc_IOError, "could not send dump request");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
/* translate args to python and call python callback */
static int dump_filter_helper(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
{
PyObject* filter = arg;
PyObject* args;
PyObject* result;
args = Py_BuildValue("s#s#", who, sizeof(*who), n, n->nlmsg_len);
result = PyObject_CallObject(filter, args);
Py_DECREF(args);
if (!result)
return -1;
/* result is ignored as long as an exception isn't raised */
Py_DECREF(result);
return 0;
}
static PyObject* pyrtnl_dump_filter(PyObject* obj, PyObject* args)
{
PyRtnlObject* self = (PyRtnlObject*)obj;
PyObject *filter;
if (!PyArg_ParseTuple(args, "O:dump_filter", &filter))
return NULL;
if (!PyCallable_Check(filter)) {
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return NULL;
}
Py_INCREF(filter);
if (rtnl_dump_filter(&self->rth, dump_filter_helper, filter, NULL,
NULL) < 0)
{
Py_DECREF(filter);
return NULL;
}
Py_DECREF(filter);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef PyRtnl_methods[] = {
{ "talk", pyrtnl_talk, METH_VARARGS,
"send a message to rtnetlink and receive a response.\n" },
{ "wilddump_request", pyrtnl_wilddump_request, METH_VARARGS,
"dump objects.\n" },
{ "dump_request", pyrtnl_dump_request, METH_VARARGS,
"start a dump of a particular netlink type.\n" },
{ "dump_filter", pyrtnl_dump_filter, METH_VARARGS,
"iterate over an rtnl dump.\n" },
{ NULL }
};
static PyTypeObject PyRtnlType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
PKG ".rtnl", /* tp_name */
sizeof(PyRtnlObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)PyRtnl_dealloc, /* tp_dealloc */
NULL, /* tp_print */
NULL, /* 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 */
NULL, /* tp_call */
NULL, /* tp_str */
NULL, /* tp_getattro */
NULL, /* tp_setattro */
NULL, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"rtnetlink handle", /* tp_doc */
NULL, /* tp_traverse */
NULL, /* tp_clear */
NULL, /* tp_richcompare */
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
PyRtnl_methods, /* tp_methods */
NULL, /* tp_members */
NULL, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
NULL, /* tp_descr_set */
0, /* tp_dictoffset */
PyRtnl_init, /* tp_init */
NULL, /* tp_alloc */
PyRtnl_new, /* tp_new */
};
static PyMethodDef methods[] = {
{ NULL }
};
static char doc[] = "libnetlink wrapper";
PyMODINIT_FUNC initnetlink(void)
{
PyObject *mod;
if (PyType_Ready(&PyRtnlType) == -1)
return;
if (!(mod = Py_InitModule3(PKG, methods, doc)))
return;
Py_INCREF(&PyRtnlType);
PyModule_AddObject(mod, "rtnl", (PyObject *)&PyRtnlType);
}
-164
View File
@@ -1,164 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <Python.h>
#include <libcontract.h>
#include <sys/contract/process.h>
#include <fcntl.h>
#include <stdio.h>
/*
* On Solaris, xend runs under a contract as an smf(5) service. As a
* result, when spawning long-running children such as a domain's
* qemu-dm instantiation, we have to make sure it's in a separate
* contract. Before we fork, we must activate a separate process
* contract template to place the child processes in a new contract.
*/
static PyObject *
pyprocess_activate(PyObject *o, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "name", NULL };
char *name = NULL;
int flags;
int cfd;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &name))
return (NULL);
cfd = open64("/system/contract/process/template", O_RDWR);
if (cfd == -1)
goto err;
if ((flags = fcntl(cfd, F_GETFD, 0)) == -1)
goto err;
if (fcntl(cfd, F_SETFD, flags | FD_CLOEXEC) == -1)
goto err;
if (name != NULL)
ct_pr_tmpl_set_svc_aux(cfd, name);
if (ct_tmpl_activate(cfd))
goto err;
return (PyInt_FromLong((long)cfd));
err:
if (cfd != -1)
close(cfd);
PyErr_SetFromErrno(PyExc_OSError);
return (NULL);
}
static PyObject *
pyprocess_clear(PyObject *o, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "contract", NULL };
int cfd;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &cfd))
return (NULL);
if (ct_tmpl_clear(cfd) != 0) {
PyErr_SetFromErrno(PyExc_OSError);
return (NULL);
}
close(cfd);
Py_INCREF(Py_None);
return (Py_None);
}
static PyObject *
pyprocess_abandon_latest(PyObject *o, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { NULL };
static char path[PATH_MAX];
ct_stathdl_t st;
ctid_t latest;
int cfd;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist))
return (NULL);
cfd = open64("/system/contract/process/latest", O_RDONLY);
if (cfd == -1)
goto err;
ct_status_read(cfd, CTD_COMMON, &st);
latest = ct_status_get_id(st);
ct_status_free(st);
close(cfd);
snprintf(path, PATH_MAX, "/system/contract/process/%ld/ctl",
(long)latest);
if ((cfd = open64(path, O_WRONLY)) < 0)
goto err;
if (ct_ctl_abandon(cfd))
goto err;
close(cfd);
Py_INCREF(Py_None);
return (Py_None);
err:
PyErr_SetFromErrno(PyExc_OSError);
return (NULL);
}
PyDoc_STRVAR(pyprocess_activate__doc__,
"activate(name)\n"
"\n"
"Activate a new process contract template. If name is given,\n"
"it is used as the template's auxiliary value.\n"
"Returns the new contract template.\n");
PyDoc_STRVAR(pyprocess_clear__doc__,
"clear(contract)\n"
"\n"
"Clear and close the given contract template.\n");
PyDoc_STRVAR(pyprocess_abandon_latest__doc__,
"abandon_latest()\n"
"\n"
"Abandon the latest contract created by this thread.\n");
static struct PyMethodDef pyprocess_module_methods[] = {
{ "activate", (PyCFunction) pyprocess_activate,
METH_VARARGS|METH_KEYWORDS, pyprocess_activate__doc__ },
{ "clear", (PyCFunction) pyprocess_clear,
METH_VARARGS|METH_KEYWORDS, pyprocess_clear__doc__ },
{ "abandon_latest", (PyCFunction) pyprocess_abandon_latest,
METH_VARARGS|METH_KEYWORDS, pyprocess_abandon_latest__doc__ },
{ NULL, NULL, 0, NULL }
};
PyMODINIT_FUNC
initprocess(void)
{
Py_InitModule("process", pyprocess_module_methods);
}
-156
View File
@@ -1,156 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <Python.h>
#include <libscf.h>
#include <stdio.h>
#define XEND_FMRI "svc:/system/xvm/xend:default"
#define XEND_PG "config"
static PyObject *scf_exc;
static void *
scf_exception(const char *err, const char *value)
{
int scferr = scf_error();
const char *scfstrerr = scf_strerror(scferr);
PyObject *obj = Py_BuildValue("(isss)", scferr, err, scfstrerr, value);
PyErr_SetObject(scf_exc, obj);
return (NULL);
}
static PyObject *
pyscf_get_bool(PyObject *o, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "name", NULL };
scf_simple_prop_t *prop;
uint8_t *val;
char *name;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name))
return (NULL);
prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name);
if (prop == NULL)
return (scf_exception("scf_simple_prop_get() failed", name));
if ((val = scf_simple_prop_next_boolean(prop)) == NULL)
return (scf_exception("scf_simple_prop_next_boolean() failed",
name));
if (*val) {
scf_simple_prop_free(prop);
Py_INCREF(Py_True);
return (Py_True);
}
scf_simple_prop_free(prop);
Py_INCREF(Py_False);
return (Py_False);
}
static PyObject *
pyscf_get_int(PyObject *o, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "name", NULL };
scf_simple_prop_t *prop;
PyObject *obj;
int64_t *val;
char *name;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name))
return (NULL);
prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name);
if (prop == NULL)
return (scf_exception("scf_simple_prop_get() failed", name));
if ((val = scf_simple_prop_next_integer(prop)) == NULL)
return (scf_exception("scf_simple_prop_next_integer() failed",
name));
obj = PyInt_FromLong((long)*val);
scf_simple_prop_free(prop);
return (obj);
}
static PyObject *
pyscf_get_string(PyObject *o, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "name", NULL };
scf_simple_prop_t *prop;
PyObject *obj;
char *name;
char *str;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name))
return (NULL);
prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name);
if (prop == NULL)
return (scf_exception("scf_simple_prop_get() failed", name));
if ((str = scf_simple_prop_next_astring(prop)) == NULL) {
scf_simple_prop_free(prop);
return (scf_exception("scf_simple_prop_next_astring() failed",
name));
}
obj = PyString_FromString(str);
scf_simple_prop_free(prop);
return (obj);
}
PyDoc_STRVAR(pyscf_get_bool__doc__,
"get_bool(name) - get the value of the named boolean property");
PyDoc_STRVAR(pyscf_get_int__doc__,
"get_int(name) - get the value of the named integer property");
PyDoc_STRVAR(pyscf_get_string__doc__,
"get_string(name) - get the value of the named string property");
static struct PyMethodDef pyscf_module_methods[] = {
{ "get_bool", (PyCFunction) pyscf_get_bool,
METH_VARARGS|METH_KEYWORDS, pyscf_get_bool__doc__ },
{ "get_int", (PyCFunction) pyscf_get_int,
METH_VARARGS|METH_KEYWORDS, pyscf_get_int__doc__ },
{ "get_string", (PyCFunction) pyscf_get_string,
METH_VARARGS|METH_KEYWORDS, pyscf_get_string__doc__ },
{ NULL, NULL, 0, NULL }
};
PyMODINIT_FUNC
initscf(void)
{
PyObject *m;
m = Py_InitModule("scf", pyscf_module_methods);
scf_exc = PyErr_NewException("scf.error", NULL, NULL);
Py_INCREF(scf_exc);
PyModule_AddObject(m, "error", scf_exc);
PyModule_AddIntConstant(m, "SCF_ERROR_NOT_FOUND", SCF_ERROR_NOT_FOUND);
}
View File
Whitespace-only changes.
-31
View File
@@ -1,31 +0,0 @@
handlers = []
class BlkDevException(Exception): pass
class BlkDev(object):
"Object representing a VM block device"
def __init__(self, **props):
self.uname = ''
if 'dev' not in props:
raise BlkDevException('no device')
#if 'uname' not in props:
#raise BlkDevException('no uname')
if 'mode' not in props:
raise BlkDevException('no mode')
self.__dict__.update(props)
self.dev = props['dev'].rstrip(':disk')
def __str__(self):
return '%s,%s,%s' % (self.uname, self.dev, self.mode)
def register(handler):
"register a block device class with parser"
if handler not in handlers:
handlers.insert(0, handler)
def parse(props):
"turn a vm device dictionary into a blkdev object"
for handler in handlers:
if handler.handles(**props):
return handler(**props)
return BlkDev(**props)
-397
View File
@@ -1,397 +0,0 @@
# Remus device interface
#
# Coordinates with devices at suspend, resume, and commit hooks
import os, re, fcntl
import netlink, qdisc, util
class ReplicatedDiskException(Exception): pass
class BufferedNICException(Exception): pass
class CheckpointedDevice(object):
'Base class for buffered devices'
def postsuspend(self):
'called after guest has suspended'
pass
def preresume(self):
'called before guest resumes'
pass
def commit(self):
'called when backup has acknowledged checkpoint reception'
pass
class ReplicatedDisk(CheckpointedDevice):
"""
Send a checkpoint message to a replicated disk while the domain
is paused between epochs.
"""
FIFODIR = '/var/run/tap'
SEND_CHECKPOINT = 20
WAIT_CHECKPOINT_ACK = 30
def __init__(self, disk):
# look up disk, make sure it is tap:buffer, and set up socket
# to request commits.
self.ctlfd = None
self.msgfd = None
self.is_drbd = False
self.ackwait = False
if disk.uname.startswith('tap:remus:') or disk.uname.startswith('tap:tapdisk:remus:'):
fifo = re.match("tap:.*(remus.*)\|", disk.uname).group(1).replace(':', '_')
absfifo = os.path.join(self.FIFODIR, fifo)
absmsgfifo = absfifo + '.msg'
self.installed = False
self.ctlfd = open(absfifo, 'w+b')
self.msgfd = open(absmsgfifo, 'r+b')
elif disk.uname.startswith('drbd:'):
#get the drbd device associated with this resource
drbdres = re.match("drbd:(.*)", disk.uname).group(1)
drbddev = util.runcmd("drbdadm sh-dev %s" % drbdres).rstrip()
#check for remus supported drbd installation
rconf = util.runcmd("drbdsetup %s show" % drbddev)
if rconf.find('protocol D;') == -1:
raise ReplicatedDiskException('Remus support for DRBD disks requires the '
'resources to operate in protocol D. Please make '
'sure that you have installed the remus supported DRBD '
'version from git://aramis.nss.cs.ubc.ca/drbd-8.3-remus '
'and enabled protocol D in the resource config')
#check if resource is in connected state
cstate = util.runcmd("drbdadm cstate %s" % drbdres).rstrip()
if cstate != 'Connected':
raise ReplicatedDiskException('DRBD resource %s is not in connected state!'
% drbdres)
#open a handle to the resource so that we could issue chkpt ioctls
self.ctlfd = open(drbddev, 'r')
self.is_drbd = True
else:
raise ReplicatedDiskException('Disk is not replicated: %s' %
str(disk))
def __del__(self):
self.uninstall()
def uninstall(self):
if self.ctlfd:
self.ctlfd.close()
self.ctlfd = None
def postsuspend(self):
if not self.is_drbd:
os.write(self.ctlfd.fileno(), 'flush')
elif not self.ackwait:
if (fcntl.ioctl(self.ctlfd.fileno(), self.SEND_CHECKPOINT, 0) > 0):
self.ackwait = False
else:
self.ackwait = True
def preresume(self):
if self.is_drbd and self.ackwait:
fcntl.ioctl(self.ctlfd.fileno(), self.WAIT_CHECKPOINT_ACK, 0)
self.ackwait = False
def commit(self):
if not self.is_drbd:
msg = os.read(self.msgfd.fileno(), 4)
if msg != 'done':
print 'Unknown message: %s' % msg
### Network
# shared rtnl handle
_rth = None
def getrth():
global _rth
if not _rth:
_rth = netlink.rtnl()
return _rth
class Netbuf(object):
"Proxy for netdev with a queueing discipline"
@staticmethod
def devclass():
"returns the name of this device class"
return 'unknown'
@classmethod
def available(cls):
"returns True if this module can proxy the device"
return cls._hasdev(cls.devclass())
def __init__(self, devname):
self.devname = devname
self.vif = None
# override in subclasses
def install(self, vif):
"set up proxy on device"
raise BufferedNICException('unimplemented')
def uninstall(self):
"remove proxy on device"
raise BufferedNICException('unimplemented')
# protected
@staticmethod
def _hasdev(devclass):
"""check for existence of device, attempting to load kernel
module if not present"""
devname = '%s0' % devclass
rth = getrth()
if rth.getlink(devname):
return True
if util.modprobe(devclass) and rth.getlink(devname):
return True
return False
class IFBBuffer(Netbuf):
"""Capture packets arriving on a VIF using an ingress filter and tc
mirred action to forward them to an IFB device.
"""
@staticmethod
def devclass():
return 'ifb'
def install(self, vif):
self.vif = vif
# voodoo from http://www.linuxfoundation.org/collaborate/workgroups/networking/ifb#Typical_Usage
util.runcmd('ip link set %s up' % self.devname)
try:
util.runcmd('tc qdisc add dev %s ingress' % vif.dev)
except util.PipeException, e:
# check if error indicates that ingress qdisc
# already exists on the vif. If so, ignore it.
ignoreme = 'RTNETLINK answers: File exists'
if ignoreme in str(e):
pass
else:
raise e
util.runcmd('tc filter add dev %s parent ffff: proto ip pref 10 '
'u32 match u32 0 0 action mirred egress redirect '
'dev %s' % (vif.dev, self.devname))
def uninstall(self):
try:
util.runcmd('tc qdisc del dev %s ingress' % self.vif.dev)
except util.PipeException, e:
pass
util.runcmd('ip link set %s down' % self.devname)
class IMQBuffer(Netbuf):
"""Redirect packets coming in on vif to an IMQ device."""
imqebt = '/usr/lib/xen/bin/imqebt'
@staticmethod
def devclass():
return 'imq'
def install(self, vif):
# stopgap hack to set up IMQ for an interface. Wrong in many ways.
self.vif = vif
for mod in ['imq', 'ebt_imq']:
util.runcmd(['modprobe', mod])
util.runcmd("ip link set %s up" % self.devname)
util.runcmd("%s -F FORWARD" % self.imqebt)
util.runcmd("%s -A FORWARD -i %s -j imq --todev %s" % (self.imqebt, vif.dev, self.devname))
def uninstall(self):
util.runcmd("%s -F FORWARD" % self.imqebt)
util.runcmd('ip link set %s down' % self.devname)
# in order of desirability
netbuftypes = [IFBBuffer, IMQBuffer]
def selectnetbuf():
"Find the best available buffer type"
for driver in netbuftypes:
if driver.available():
return driver
raise BufferedNICException('no net buffer available')
class Netbufpool(object):
"""Allocates/releases proxy netdevs (IMQ/IFB)
A file contains a list of entries of the form <pid>:<device>\n
To allocate a device, lock the file, then claim a new device if
one is free. If there are no free devices, check each PID for liveness
and take a device if the PID is dead, otherwise return failure.
Add an entry to the file before releasing the lock.
"""
def __init__(self, netbufclass):
"Create a pool of Device"
self.netbufclass = netbufclass
self.path = '/var/run/remus/' + self.netbufclass.devclass()
self.devices = self.getdevs()
pooldir = os.path.dirname(self.path)
if not os.path.exists(pooldir):
os.makedirs(pooldir, 0755)
def get(self):
"allocate a free device"
def getfreedev(table):
for dev in self.devices:
if dev not in table or not util.checkpid(table[dev]):
return dev
return None
lock = util.Lock(self.path)
table = self.load()
dev = getfreedev(table)
if not dev:
lock.unlock()
raise BufferedNICException('no free devices')
dev = self.netbufclass(dev)
table[dev.devname] = os.getpid()
self.save(table)
lock.unlock()
return dev
def put(self, dev):
"release claim on device"
lock = util.Lock(self.path)
table = self.load()
del table[dev.devname]
self.save(table)
lock.unlock()
# private
def load(self):
"""load and parse allocation table"""
table = {}
if not os.path.exists(self.path):
return table
fd = open(self.path)
for line in fd.readlines():
iface, pid = line.strip().split()
table[iface] = int(pid)
fd.close()
return table
def save(self, table):
"""write table to disk"""
lines = ['%s %d\n' % (iface, table[iface]) for iface in sorted(table)]
fd = open(self.path, 'w')
fd.writelines(lines)
fd.close()
def getdevs(self):
"""find all available devices of our device type"""
ifaces = []
for line in util.runcmd('ifconfig -a -s').splitlines():
iface = line.split()[0]
if iface.startswith(self.netbufclass.devclass()):
ifaces.append(iface)
return ifaces
class BufferedNIC(CheckpointedDevice):
"""
Buffer a protected domain's network output between rounds so that
nothing is issued that a failover might not know about.
"""
def __init__(self, vif):
self.installed = False
self.vif = vif
self.pool = Netbufpool(selectnetbuf())
self.rth = getrth()
self.setup()
def __del__(self):
self.uninstall()
def postsuspend(self):
if not self.installed:
self.install()
self._sendqmsg(qdisc.TC_PLUG_BUFFER)
def commit(self):
'''Called when checkpoint has been acknowledged by
the backup'''
self._sendqmsg(qdisc.TC_PLUG_RELEASE_ONE)
# private
def _sendqmsg(self, action):
self.q.action = action
req = qdisc.changerequest(self.bufdevno, self.handle, self.q)
self.rth.talk(req.pack())
return True
def setup(self):
"""install Remus plug on VIF outbound traffic"""
self.bufdev = self.pool.get()
devname = self.bufdev.devname
bufdev = self.rth.getlink(devname)
if not bufdev:
raise BufferedNICException('could not find device %s' % devname)
self.bufdev.install(self.vif)
self.bufdevno = bufdev['index']
self.handle = qdisc.TC_H_ROOT
self.q = qdisc.PlugQdisc()
if not util.modprobe('sch_plug'):
raise BufferedNICException('could not load sch_plug module')
def install(self):
devname = self.bufdev.devname
q = self.rth.getqdisc(self.bufdevno)
if q:
if q['kind'] == 'plug':
self.installed = True
return
if q['kind'] not in ('ingress', 'pfifo_fast', 'mq'):
raise BufferedNICException('there is already a queueing '
'discipline %s on %s' % (q['kind'], devname))
print ('installing buffer on %s... ' % devname),
req = qdisc.addrequest(self.bufdevno, self.handle, self.q)
self.rth.talk(req.pack())
self.installed = True
print 'done.'
def uninstall(self):
if self.installed:
try:
req = qdisc.delrequest(self.bufdevno, self.handle)
self.rth.talk(req.pack())
except IOError, e:
pass
self.installed = False
try:
self.bufdev.uninstall()
except util.PipeException, e:
pass
self.pool.put(self.bufdev)
-227
View File
@@ -1,227 +0,0 @@
# VM image file manipulation
import logging, struct
import vm
SIGNATURE = 'LinuxGuestRecord'
LONGLEN = struct.calcsize('L')
INTLEN = struct.calcsize('i')
PAGE_SIZE = 4096
# ~0L
P2M_EXT_SIG = 4294967295L
# frames per page
FPP = 1024
LTAB_MASK = 0xf << 28
BATCH_SIZE = 1024
IDXLEN = INTLEN + BATCH_SIZE * LONGLEN
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger()
class VMParseException(Exception): pass
class VMImage(object):
def __init__(self, img=None):
"""img may be a path or a file object.
If compact is True, apply checkpoints to base image instead
of simply concatenating them.
"""
self.img = img
self.dom = None
self.fd = None
self.header = None
self.nr_pfns = 0
# p2m extension header (unparsed)
self.p2mext = None
if self.img:
self.open(self.img)
def open(self, img):
if isinstance(img, str):
self.fd = file(img, 'rb')
else:
self.fd = img
self.readheader()
def readheader(self):
sig = self.fd.read(len(SIGNATURE))
if sig != SIGNATURE:
raise VMParseException("Bad signature in image")
hlen = self.fd.read(INTLEN)
hlen, = struct.unpack('!i', hlen)
self.header = self.fd.read(hlen)
self.dom = parseheader(self.header)
def readp2mfl(self):
"read the P2M frame list"
pfnlen = self.fd.read(LONGLEN)
self.nr_pfns, = struct.unpack('L', pfnlen)
p2m0 = self.fd.read(LONGLEN)
p2mhdr = p2m0
p2m0, = struct.unpack('L', p2m0)
if p2m0 == P2M_EXT_SIG:
elen = self.fd.read(INTLEN)
elen, = struct.unpack('I', elen)
self.p2mext = self.fd.read(elen)
p2m0 = self.fd.read(LONGLEN)
p2m0, = struct.unpack('L', p2m0)
p2mfl = [p2m0]
p2mfle = (self.nr_pfns + FPP - 1)/FPP - 1
p2ms = self.fd.read(LONGLEN * p2mfle)
p2mfl.extend(struct.unpack('%dL' % p2mfle, p2ms))
self.p2mfl = p2mfl
def flush(self):
self.ofd.write(self.tail)
class Writer(object):
"""compress a stream of checkpoints into a single image of the
last checkpoint"""
def __init__(self, fd, compact=False):
self.fd = fd
self.compact = compact
self.vm = None
self.tail = None
# offset to first batch of pages
self.imgstart = 0
# PFN mappings
self.pfns = []
def __del__(self):
self.close()
def writeheader(self):
hlen = struct.pack('!i', len(self.vm.header))
header = ''.join([SIGNATURE, hlen, self.vm.header])
self.fd.write(header)
def writep2mfl(self):
p2m = [struct.pack('L', self.vm.nr_pfns)]
if self.vm.p2mext:
p2m.extend([struct.pack('L', P2M_EXT_SIG), self.vm.p2mext])
p2m.append(struct.pack('%dL' % len(self.vm.p2mfl), *self.vm.p2mfl))
self.fd.write(''.join(p2m))
def writebatch(self, batch):
def offset(pfn):
isz = (pfn / BATCH_SIZE + 1) * IDXLEN
return self.imgstart + isz + pfn * PAGE_SIZE
if not self.compact:
return self.fd.write(batch)
batch = parsebatch(batch)
# sort pages for better disk seek behaviour
batch.sort(lambda x, y: cmp(x[0] & ~LTAB_MASK, y[0] & ~LTAB_MASK))
for pfndesc, page in batch:
pfn = pfndesc & ~LTAB_MASK
if pfn > self.vm.nr_pfns:
log.error('INVALID PFN: %d' % pfn)
if len(self.pfns) <= pfn:
self.pfns.extend([0] * (pfn - len(self.pfns) + 1))
self.pfns[pfn] = pfndesc
self.fd.seek(offset(pfn))
self.fd.write(page)
#print "max offset: %d, %d" % (len(self.pfns), offset(self.pfns[-1]))
def writeindex(self):
"Write batch header in front of each page"
hdrlen = INTLEN + BATCH_SIZE * LONGLEN
batches = (len(self.pfns) + BATCH_SIZE - 1) / BATCH_SIZE
for i in xrange(batches):
offset = self.imgstart + i * (hdrlen + (PAGE_SIZE * BATCH_SIZE))
pfnoff = i * BATCH_SIZE
# python auto-clamps overreads
pfns = self.pfns[pfnoff:pfnoff + BATCH_SIZE]
self.fd.seek(offset)
self.fd.write(struct.pack('i', len(pfns)))
self.fd.write(struct.pack('%dL' % len(pfns), *pfns))
def slurp(self, ifd):
"""Apply an incremental checkpoint to a loaded image.
accepts a path or a file object."""
if isinstance(ifd, str):
ifd = file(ifd, 'rb')
if not self.vm:
self.vm = VMImage(ifd)
self.writeheader()
self.vm.readp2mfl()
self.writep2mfl()
self.imgstart = self.fd.tell()
while True:
l, batch = readbatch(ifd)
if l <= 0:
break
self.writebatch(batch)
self.tail = batch + ifd.read()
def flush(self):
if self.tail:
self.fd.seek(0, 2)
self.fd.write(self.tail)
if self.compact:
self.writeindex()
self.tail = None
def close(self):
self.flush()
def parseheader(header):
"parses a header sexpression"
return vm.parsedominfo(vm.strtosxpr(header))
def makeheader(dominfo):
"create an image header from a VM dominfo sxpr"
items = [SIGNATURE]
sxpr = vm.sxprtostr(dominfo)
items.append(struct.pack('!i', len(sxpr)))
items.append(sxpr)
return ''.join(items)
def readbatch(fd):
batch = []
batchlen = fd.read(INTLEN)
batch.append(batchlen)
batchlen, = struct.unpack('i', batchlen)
log.info("batch length: %d" % batchlen)
if batchlen <= 0:
return (batchlen, batch[0])
batchfns = fd.read(LONGLEN * batchlen)
batch.append(batchfns)
pages = fd.read(PAGE_SIZE * batchlen)
if len(pages) != PAGE_SIZE * batchlen:
log.error('SHORT READ: %d' % len(pages))
batch.append(pages)
return (batchlen, ''.join(batch))
def parsebatch(batch):
"parse a batch string into pages"
batchlen, batch = batch[:INTLEN], batch[INTLEN:]
batchlen, = struct.unpack('i', batchlen)
#print 'batch length: %d' % batchlen
pfnlen = batchlen * LONGLEN
pfns = struct.unpack('%dL' % batchlen, batch[:pfnlen])
pagebuf = batch[pfnlen:]
pages = [pagebuf[i*PAGE_SIZE:(i+1)*PAGE_SIZE] for i in xrange(batchlen)]
return zip(pfns, pages)
-318
View File
@@ -1,318 +0,0 @@
# netlink wrappers
# See include/linux/netlink.h and rtnetlink.h
import socket, struct
import xen.lowlevel.netlink
NETLINK_ROUTE = 0
NLM_F_REQUEST = 1 # It is request message.
NLM_F_MULTI = 2 # Multipart message, terminated by NLMSG_DONE
NLM_F_ACK = 4 # Reply with ack, with zero or error code
NLM_F_ECHO = 8 # Echo this request
# Modifiers to GET request
NLM_F_ROOT = 0x100 # specify tree root
NLM_F_MATCH = 0x200 # return all matching
NLM_F_ATOMIC = 0x400 # atomic GET
NLM_F_DUMP = NLM_F_ROOT|NLM_F_MATCH
# Modifiers to NEW request
NLM_F_REPLACE = 0x100 # Override existing
NLM_F_EXCL = 0x200 # Do not touch, if it exists
NLM_F_CREATE = 0x400 # Create, if it does not exist
NLM_F_APPEND = 0x800 # Add to end of list
RTM_NEWLINK = 16
RTM_GETLINK = 18
RTM_NEWQDISC = 36
RTM_DELQDISC = 37
RTM_GETQDISC = 38
IFLA_UNSPEC = 0
IFLA_ADDRESS = 1
IFLA_BROADCAST = 2
IFLA_IFNAME = 3
IFLA_MTU = 4
IFLA_LINK = 5
IFLA_QDISC = 6
IFLA_STATS = 7
IFLA_COST = 8
IFLA_PRIORITY = 9
IFLA_MASTER = 10
IFLA_WIRELESS = 11
IFLA_PROTINFO = 12
IFLA_TXQLEN = 13
IFLA_MAP = 14
IFLA_WEIGHT = 15
TCA_UNSPEC = 0
TCA_KIND = 1
TCA_OPTIONS = 2
TCA_STATS = 3
TCA_XSTATS = 4
TCA_RATE = 5
TCA_FCNT = 6
TCA_STATS2 = 7
class RTNLException(Exception): pass
def align(l, alignto=4):
return (l + alignto - 1) & ~(alignto - 1)
class rtattr(object):
"rtattribute"
fmt = "HH"
fmtlen = struct.calcsize(fmt)
def __init__(self, msg=None):
if msg:
self.unpack(msg)
else:
self.rta_len = 0
self.rta_type = 0
self.body = ''
def __len__(self):
return align(self.rta_len)
def pack(self):
self.rta_len = self.fmtlen + len(self.body)
s = struct.pack(self.fmt, self.rta_len, self.rta_type) + self.body
pad = align(self.rta_len) - len(s)
if pad:
s += '\0' * pad
return s
def unpack(self, msg):
args = struct.unpack(self.fmt, msg[:self.fmtlen])
self.rta_len, self.rta_type = args
self.body = msg[self.fmtlen:self.rta_len]
class rtattrlist(object):
def __init__(self, msg):
self.start = msg
def __iter__(self):
body = self.start
while len(body) > rtattr.fmtlen:
rta = rtattr(body)
yield rta
body = body[len(rta):]
class nlmsg(object):
"netlink message header"
fmt = "IHHII"
fmtlen = struct.calcsize(fmt)
def __init__(self, msg=None):
if msg:
self.unpack(msg)
else:
self.nlmsg_len = 0
self.nlmsg_type = 0
self.nlmsg_flags = 0
self.nlmsg_seq = 0
self.nlmsg_pid = 0
self.rta = ''
self.body = ''
def __len__(self):
return align(self.fmtlen + len(self.body) + len(self.rta))
def addattr(self, type, data):
attr = rtattr()
attr.rta_type = type
attr.body = data
self.rta += attr.pack()
self.nlmsg_len = len(self)
def settype(self, cmd):
self.nlmsg_type = cmd
def pack(self):
s = struct.pack(self.fmt, len(self), self.nlmsg_type,
self.nlmsg_flags, self.nlmsg_seq,
self.nlmsg_pid) + self.body + self.rta
return s
def unpack(self, msg):
args = struct.unpack(self.fmt, msg[:self.fmtlen])
self.nlmsg_len, self.nlmsg_type, self.nlmsg_flags = args[:3]
self.nlmsg_seq, self.nlmsg_pid = args[3:]
self.body = msg[align(self.fmtlen):]
self.rta = ''
def __str__(self):
return '<netlink message, len %d, type %d>' % \
(self.nlmsg_len, self.nlmsg_type)
class ifinfomsg(object):
"interface info message"
fmt = "BxHiII"
fmtlen = struct.calcsize(fmt)
def __init__(self, msg=None):
if msg:
self.unpack(msg)
else:
self.ifi_family = 0
self.ifi_type = 0
self.ifi_index = 0
self.ifi_flags = 0
self.ifi_change = 0
self.body = ''
def unpack(self, msg):
args = struct.unpack(self.fmt, msg[:self.fmtlen])
self.ifi_family, self.ifi_type, self.ifi_index= args[:3]
self.ifi_flags, self.ifi_change = args[3:]
self.body = msg[align(self.fmtlen):]
def __str__(self):
return '<ifinfo message, family %d, type %d, index %d>' % \
(self.ifi_family, self.ifi_type, self.ifi_index)
class tcmsg(object):
"TC message"
fmt = "BxxxiIII"
fmtlen = struct.calcsize(fmt)
def __init__(self, msg=None):
if msg:
self.unpack(msg)
else:
self.tcm_family = socket.AF_UNSPEC
self.tcm_ifindex = 0
self.tcm_handle = 0
self.tcm_parent = 0
self.tcm_info = 0
self.rta = ''
def unpack(self, msg):
args = struct.unpack(self.fmt, msg[:self.fmtlen])
self.tcm_family, self.tcm_ifindex, self.tcm_handle = args[:3]
self.tcm_parent, self.tcm_info = args[3:]
self.rta = msg[align(self.fmtlen):]
def pack(self):
return struct.pack(self.fmt, self.tcm_family, self.tcm_ifindex,
self.tcm_handle, self.tcm_parent, self.tcm_info)
def __str__(self):
return '<tc message, family %d, index %d>' % \
(self.tcm_family, self.tcm_ifindex)
class newlinkmsg(object):
def __init__(self, nlmsg):
if nlmsg.nlmsg_type != RTM_NEWLINK:
raise RTNLException("wrong message type")
self.nlmsg = nlmsg
self.ifi = ifinfomsg(self.nlmsg.body)
self.rtattrs = {}
for rta in rtattrlist(self.ifi.body):
self.rtattrs[rta.rta_type] = rta.body
class newqdiscmsg(object):
def __init__(self, nlmsg):
if nlmsg.nlmsg_type != RTM_NEWQDISC:
raise RTNLException("wrong message type")
self.nlmsg = nlmsg
self.t = tcmsg(self.nlmsg.body)
self.rtattrs = {}
for rta in rtattrlist(self.t.rta):
self.rtattrs[rta.rta_type] = rta.body
class rtnl(object):
def __init__(self):
self._rth = xen.lowlevel.netlink.rtnl()
self._linkcache = None
def getlink(self, key, cached=False):
"""returns the interface object corresponding to the key, which
may be an index number or device name."""
if not cached:
self._linkcache = None
if self._linkcache is None:
self._linkcache = self.getlinks()
if isinstance(key, int):
return self._linkcache.get(key)
for k, v in self._linkcache.iteritems():
if v['name'] == key:
return v
return None
def getlinks(self):
"""returns a dictionary of interfaces keyed by kernel
interface index"""
links = {}
def dumpfilter(addr, msgstr):
msg = newlinkmsg(nlmsg(msgstr))
idx = msg.ifi.ifi_index
ifname = msg.rtattrs[IFLA_IFNAME].strip('\0')
address = msg.rtattrs.get(IFLA_ADDRESS)
link = {'index': idx,
'type': msg.ifi.ifi_type,
'name': ifname,
'address': address}
links[idx] = link
self._rth.wilddump_request(socket.AF_UNSPEC, RTM_GETLINK)
self._rth.dump_filter(dumpfilter)
return links
def getqdisc(self, dev):
"""returns the queueing discipline on device dev, which may be
specified by kernel index or device name"""
qdiscs = self.getqdiscs(dev)
if qdiscs:
return qdiscs.values()[0]
return None
def getqdiscs(self, dev=None):
"""returns a dictionary of queueing disciplines keyed by kernel
interface index"""
qdiscs = {}
def dumpfilter(addr, msgstr):
msg = newqdiscmsg(nlmsg(msgstr))
idx = msg.t.tcm_ifindex
handle = msg.t.tcm_handle
kind = msg.rtattrs[TCA_KIND].strip('\0')
opts = msg.rtattrs.get(TCA_OPTIONS)
qdisc = {'index': idx,
'handle': handle,
'kind': kind,
'options': opts}
qdiscs[idx] = qdisc
tcm = tcmsg()
if dev:
link = self.getlink(dev)
if not link:
raise QdiscException('device %s not found' % dev)
tcm.tcm_ifindex = link['index']
msg = tcm.pack()
self._rth.dump_request(RTM_GETQDISC, msg)
self._rth.dump_filter(dumpfilter)
return qdiscs
def talk(self, req):
self._rth.talk(req)
-56
View File
@@ -1,56 +0,0 @@
"""Simple profiling module
"""
import time
class ProfileBlock(object):
"""A section of code to be profiled"""
def __init__(self, name):
self.name = name
def enter(self):
print "PROF: entered %s at %f" % (self.name, time.time())
def exit(self):
print "PROF: exited %s at %f" % (self.name, time.time())
class NullProfiler(object):
def enter(self, name):
pass
def exit(self, name=None):
pass
class Profiler(object):
def __init__(self):
self.blocks = {}
self.running = []
def enter(self, name):
try:
block = self.blocks[name]
except KeyError:
block = ProfileBlock(name)
self.blocks[name] = block
block.enter()
self.running.append(block)
def exit(self, name=None):
if name is not None:
block = None
while self.running:
tmp = self.running.pop()
if tmp.name == name:
block = tmp
break
tmp.exit()
if not block:
raise KeyError('block %s not running' % name)
else:
try:
block = self.running.pop()
except IndexError:
raise KeyError('no block running')
block.exit()
-189
View File
@@ -1,189 +0,0 @@
import socket, struct
import netlink
import platform
kernelversion = platform.platform(terse=True).split("-")[1].split(".")
qdisc_kinds = {}
TC_H_ROOT = 0xFFFFFFFF
class QdiscException(Exception): pass
class request(object):
"qdisc request message"
def __init__(self, cmd, flags=0, dev=None, handle=0):
self.n = netlink.nlmsg()
self.t = netlink.tcmsg()
self.n.nlmsg_flags = netlink.NLM_F_REQUEST|flags
self.n.nlmsg_type = cmd
self.t.tcm_family = socket.AF_UNSPEC
if not handle:
handle = TC_H_ROOT
self.t.tcm_parent = handle
if dev:
self.t.tcm_ifindex = dev
def pack(self):
t = self.t.pack()
self.n.body = t
return self.n.pack()
class addrequest(request):
def __init__(self, dev, handle, qdisc):
flags = netlink.NLM_F_EXCL|netlink.NLM_F_CREATE
super(addrequest, self).__init__(netlink.RTM_NEWQDISC, flags=flags,
dev=dev, handle=handle)
self.n.addattr(netlink.TCA_KIND, qdisc.kind + '\0')
opts = qdisc.pack()
if opts:
self.n.addattr(netlink.TCA_OPTIONS, opts)
class delrequest(request):
def __init__(self, dev, handle):
super(delrequest, self).__init__(netlink.RTM_DELQDISC, dev=dev,
handle=handle)
class changerequest(request):
def __init__(self, dev, handle, qdisc):
super(changerequest, self).__init__(netlink.RTM_NEWQDISC,
dev=dev, handle=handle)
self.n.addattr(netlink.TCA_KIND, qdisc.kind + '\0')
opts = qdisc.pack()
if opts:
self.n.addattr(netlink.TCA_OPTIONS, opts)
class Qdisc(object):
def __new__(cls, qdict=None, *args, **opts):
if qdict:
kind = qdict.get('kind')
cls = qdisc_kinds.get(kind, cls)
obj = super(Qdisc, cls).__new__(cls)
return obj
def __init__(self, qdict):
self._qdict = qdict
self.kind = qdict['kind']
self.handle = qdict['handle'] >> 16
def parse(self, opts):
if opts:
raise QdiscException('cannot parse qdisc parameters')
def optstr(self):
if self.qdict['options']:
return '[cannot parse qdisc parameters]'
else:
return ''
def pack(self):
return ''
TC_PRIO_MAX = 15
class PrioQdisc(Qdisc):
fmt = 'i%sB' % (TC_PRIO_MAX + 1)
def __init__(self, qdict):
super(PrioQdisc, self).__init__(qdict)
if qdict.get('options'):
self.unpack(qdict['options'])
else:
self.bands = 3
self.priomap = [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
def pack(self):
#return struct.pack(self.fmt, self.bands, *self.priomap)
return ''
def unpack(self, opts):
args = struct.unpack(self.fmt, opts)
self.bands = args[0]
self.priomap = args[1:]
def optstr(self):
mapstr = ' '.join([str(p) for p in self.priomap])
return 'bands %d priomap %s' % (self.bands, mapstr)
qdisc_kinds['prio'] = PrioQdisc
qdisc_kinds['pfifo_fast'] = PrioQdisc
class CfifoQdisc(Qdisc):
fmt = 'II'
def __init__(self, qdict):
super(CfifoQdisc, self).__init__(qdict)
if qdict.get('options'):
self.unpack(qdict['options'])
else:
self.epoch = 0
self.vmid = 0
def pack(self):
return struct.pack(self.fmt, self.epoch, self.vmid)
def unpack(self, opts):
self.epoch, self.vmid = struct.unpack(self.fmt, opts)
def parse(self, opts):
args = list(opts)
try:
while args:
arg = args.pop(0)
if arg == 'epoch':
self.epoch = int(args.pop(0))
continue
if arg.lower() == 'vmid':
self.vmid = int(args.pop(0))
continue
except Exception, inst:
raise QdiscException(str(inst))
def optstr(self):
return 'epoch %d vmID %d' % (self.epoch, self.vmid)
qdisc_kinds['cfifo'] = CfifoQdisc
TC_PLUG_BUFFER = 0
TC_PLUG_RELEASE_ONE = 1
class PlugQdisc(Qdisc):
def __init__(self, qdict=None):
if int(kernelversion[0]) >= 3 and int(kernelversion[1]) >= 4:
self.fmt = 'iI'
self.limit = 10000
else:
self.fmt = 'I'
if not qdict:
qdict = {'kind': 'plug',
'handle': TC_H_ROOT}
super(PlugQdisc, self).__init__(qdict)
self.action = 0
def pack(self):
if int(kernelversion[0]) >= 3 and int(kernelversion[1]) >= 4:
return struct.pack(self.fmt, self.action, self.limit)
else:
return struct.pack(self.fmt, self.action)
def parse(self, args):
if not args:
raise QdiscException('no action given')
arg = args[0]
if arg == 'checkpoint':
self.action = TC_PLUG_BUFFER
elif arg == 'release':
self.action = TC_PLUG_RELEASE_ONE
else:
raise QdiscException('unknown action')
qdisc_kinds['plug'] = PlugQdisc
-186
View File
@@ -1,186 +0,0 @@
#!/usr/bin/env python
import os, select, socket, threading, time, signal, xmlrpclib
from xen.xend.XendClient import server
from xen.xend.xenstore.xswatch import xswatch
import xen.lowlevel.xc
from xen.xend.xenstore import xsutil
xc = xen.lowlevel.xc.xc()
import xen.lowlevel.checkpoint
import vm, image
XCFLAGS_LIVE = 1
xcsave = '/usr/lib/xen/bin/xc_save'
class _proxy(object):
"proxy simulates an object without inheritance"
def __init__(self, obj):
self._obj = obj
def __getattr__(self, name):
return getattr(self._obj, name)
def proxy(self, obj):
self._obj = obj
class CheckpointError(Exception): pass
class CheckpointingFile(_proxy):
"""Tee writes into separate file objects for each round.
This is necessary because xc_save gets a single file descriptor
for the duration of checkpointing.
"""
def __init__(self, path):
self.path = path
self.round = 0
self.rfd, self.wfd = os.pipe()
self.fd = file(path, 'wb')
# this pipe is used to notify the writer thread of checkpoints
self.cprfd, self.cpwfd = os.pipe()
super(CheckpointingFile, self).__init__(self.fd)
wt = threading.Thread(target=self._wrthread, name='disk-write-thread')
wt.setDaemon(True)
wt.start()
self.wt = wt
def fileno(self):
return self.wfd
def close(self):
os.close(self.wfd)
# closing wfd should signal writer to stop
self.wt.join()
os.close(self.rfd)
os.close(self.cprfd)
os.close(self.cpwfd)
self.fd.close()
self.wt = None
def checkpoint(self):
os.write(self.cpwfd, '1')
def _wrthread(self):
while True:
r, o, e = select.select((self.rfd, self.cprfd), (), ())
if self.rfd in r:
data = os.read(self.rfd, 256 * 1024)
if not data:
break
self.fd.write(data)
if self.cprfd in r:
junk = os.read(self.cprfd, 1)
self.round += 1
self.fd = file('%s.%d' % (self.path, self.round), 'wb')
self.proxy(self.fd)
class MigrationSocket(_proxy):
def __init__(self, address):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(address)
sock.send("receive\n")
sock.recv(80)
fd = os.fdopen(sock.fileno(), 'w+')
self.sock = sock
super(MigrationSocket, self).__init__(fd)
class NullSocket(_proxy):
def __init__(self, address):
filedesc = os.open('/dev/null', 0666)
fd = os.fdopen(filedesc, 'w+')
super(NullSocket, self).__init__(fd)
class Keepalive(object):
"Call a keepalive method at intervals"
def __init__(self, method, interval=0.1):
self.keepalive = method
self.interval = interval
self.thread = None
self.running = False
def start(self):
if not self.interval:
return
self.thread = threading.Thread(target=self.run, name='keepalive-thread')
self.thread.setDaemon(True)
self.running = True
self.thread.start()
def stop(self):
if not self.thread:
return
self.running = False
self.thread.join()
self.thread = None
def run(self):
while self.running:
self.keepalive()
time.sleep(self.interval)
self.keepalive(stop=True)
class Saver(object):
def __init__(self, domid, fd, suspendcb=None, resumecb=None,
checkpointcb=None, interval=0, flags=0):
"""Create a Saver object for taking guest checkpoints.
domid: name, number or UUID of a running domain
fd: a stream to which checkpoint data will be written.
suspendcb: callback invoked after guest is suspended
resumecb: callback invoked before guest resumes
checkpointcb: callback invoked when a checkpoint is complete. Return
True to take another checkpoint, or False to stop.
flags: Remus flags to be passed to xc_domain_save
"""
self.fd = fd
self.suspendcb = suspendcb
self.resumecb = resumecb
self.checkpointcb = checkpointcb
self.interval = interval
self.flags = flags
self.vm = vm.VM(domid)
self.checkpointer = None
def start(self):
vm.getshadowmem(self.vm)
hdr = image.makeheader(self.vm.dominfo)
self.fd.write(hdr)
self.fd.flush()
self.checkpointer = xen.lowlevel.checkpoint.checkpointer()
try:
try:
self.checkpointer.open(self.vm.domid)
self.checkpointer.start(self.fd, self.suspendcb, self.resumecb,
self.checkpointcb, self.interval,
self.flags)
except xen.lowlevel.checkpoint.error, e:
raise CheckpointError(e)
finally:
try: #errors in checkpoint close are not critical atm.
self.checkpointer.close()
except:
pass
def _resume(self):
"""low-overhead version of XendDomainInfo.resumeDomain"""
# TODO: currently assumes SUSPEND_CANCEL is available
if True:
xc.domain_resume(self.vm.domid, 1)
xsutil.ResumeDomain(self.vm.domid)
else:
server.xend.domain.resumeDomain(self.vm.domid)
-4
View File
@@ -1,4 +0,0 @@
import blkdev
class TapDisk(BlkDev):
pass
Loaded 100 of 503 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.