Systemtap 1.2 <sys/sdt.h> tried to expand STAP_PROBE3 into an
initialization:
volatile __typeof__(arg) foo = arg;
but that fails if arg was declared as 'char arg[100]'.
Rather than make all callers to PROBE deal with the stupidity
of <sys/sdt.h>, we instead make PROBE cast away the problem.
Some of this preprocessor abuse copies ideas in src/libvirt.c.
* daemon/libvirtd.h (PROBE): Add casts to all arguments, using...
(VIR_ADD_CASTS, VIR_ADD_CAST, VIR_ADD_CAST2, VIR_ADD_CAST3)
(VIR_ADD_CAST_EXPAND, VIR_ADD_CAST_PASTE, VIR_COUNT_ARGS)
(VIR_ARG5, PROBE_EXPAND): New macros.
Reported by Wen Congyang.
This guts the libvirtd daemon, removing all its networking and
RPC handling code. Instead it calls out to the new virServerPtr
APIs for all its RPC & networking work
As a fallout all libvirtd daemon error reporting now takes place
via the normal internal error reporting APIs. There is no need
to call separate error reporting APIs in RPC code, nor should
code use VIR_WARN/VIR_ERROR for reporting fatal problems anymore.
* daemon/qemu_dispatch_*.h, daemon/remote_dispatch_*.h: Remove
old generated dispatcher code
* daemon/qemu_dispatch.h, daemon/remote_dispatch.h: New dispatch
code
* daemon/dispatch.c, daemon/dispatch.h: Remove obsoleted code
* daemon/remote.c, daemon/remote.h: Rewrite for new dispatch
APIs
* daemon/libvirtd.c, daemon/libvirtd.h: Remove all networking
code
* daemon/stream.c, daemon/stream.h: Update for new APIs
* daemon/Makefile.am: Link to libvirt-net-rpc-server.la
<sys/syslimits.h> is not standardized, so portable programs should
not need to rely on it. If there really is something that we need
where <sys/syslimits.h> provided the limit but <limits.h> did not,
then that would be a candidate for fixing in gnulib. But this patch
did not turn up any compilation failures on Linux.
* src/internal.h (includes): Drop unused header.
* daemon/libvirtd.h (includes): Likewise.
* configure.ac (AC_CHECK_HEADERS): Likewise.
Based on a report by Matthias Bolte.
Done mechanically with:
$ git grep -l '\bDEBUG0\? *(' | xargs -L1 sed -i 's/\bDEBUG0\? *(/VIR_&/'
followed by manual deletion of qemudDebug in daemon/libvirtd.c, along
with a single 'make syntax-check' fallout in the same file, and the
actual deletion in src/util/logging.h.
* src/util/logging.h (DEBUG, DEBUG0): Delete.
* daemon/libvirtd.h (qemudDebug): Likewise.
* global: Change remaining clients over to VIR_DEBUG counterpart.
* daemon/libvirtd.h (qemud_server): Change types of members
tracking array sizes, and add allocation trackers.
* daemon/event.c (virEventLoop): Likewise.
(virEventAddHandleImpl, virEventAddTimeoutImpl)
(virEventCleanupTimeouts, virEventCleanupHandles): Use
VIR_RESIZE_N instead of VIR_REALLOC_N. Tweak debug messages to
match type changes.
* daemon/libvirtd.c (qemudDispatchServer, qemudRunLoop): Likewise.
It is useful to know where the client is connecting from,
so include the socket address in probe data.
* daemon/libvirtd.h: Use virSocketAddr for storing client
address and keep printable address handy for logging
* daemon/libvirtd.c: Include socket address in client
connect/disconnect probes
* daemon/probes.d: Add socket address to probes
* examples/systemtap/client.stp: Print socket address
* src/util/network.h: Add sockaddr_un to virSocketAddr union
Adds initial support for dtrace static probes in libvirtd
daemon, assuming use of systemtap dtrace compat shim on
Linux. The probes are inserted for network client connect,
disconnect, TLS handshake states and authentication protocol
states.
This can be tested by running the xample program and then
attempting to connect with any libvirt client (virsh,
virt-manager, etc).
# stap examples/systemtap/client.stp
Client fd=44 connected readonly=0
Client fd=44 auth polkit deny pid:24997,uid:500
Client fd=44 disconnected
Client fd=46 connected readonly=1
Client fd=46 auth sasl allow test
Client fd=46 disconnected
The libvirtd.stp file should also really not be required,
since it is duplicated info that is already available in
the main probes.d definition file. A script to autogenerate
the .stp file is needed, either in libvirtd tree, or better
as part of systemtap itself.
* Makefile.am: Add examples/systemtap subdir
* autobuild.sh: Disable dtrace for mingw32
* configure.ac: Add check for dtrace
* daemon/.gitignore: Ignore generated dtrace probe file
* daemon/Makefile.am: Build dtrace probe header & object
files
* daemon/libvirtd.stp: SystemTAP convenience probeset
* daemon/libvirtd.c: Add connect/disconnect & TLS probes
* daemon/remote.c: Add SASL and PolicyKit auth probes
* daemon/probes.d: Master probe definition
* daemon/libvirtd.h: Add convenience macro for probes
so that compilation is a no-op when dtrace is not available
* examples/systemtap/Makefile.am, examples/systemtap/client.stp
Example systemtap script using dtrace probe markers
* libvirt.spec.in: Enable dtrace on F13/RHEL6
* mingw32-libvirt.spec.in: Force disable dtrace
Since we are adding a new "per-hypervisor" protocol, we
make it so that the qemu remote protocol uses a new
PROTOCOL and PROGRAM number. This allows us to easily
distinguish it from the normal REMOTE protocol.
This necessitates changing the proc in remote_message_header
from a "remote_procedure" to an "unsigned", which should
be the same size (and thus preserve the on-wire protocol).
Changes since v1:
- Fixed up a couple of script problems in remote_generate_stubs.pl
- Switch an int flag to a bool in dispatch.c
Changes since v2:
- None
Changes since v3:
- Change unsigned proc to signed proc, to conform to spec
Signed-off-by: Chris Lalancette <clalance@redhat.com>
When libvirtd exits it is leaving UNIX domain sockets on
the filesystem. These need to be removed.
The qemudInitPaths() method has signficant code churn to
switch from using a pre-allocated buffer on the stack, to
dynamically allocating on the heap.
* daemon/libvirtd.c, daemon/libvirtd.h: Store a reference
to the UNIX domain socket path and unlink it on shutdown
This wires up the remote driver to handle the new events APIs.
The public API allows an application to request a callback filters
events to a specific domain object, and register multiple callbacks
for the same event type. On the wire there are two strategies for
this
- Register multiple callbacks with the remote daemon, each
with filtering as needed
- Register only one callback per event type, with no filtering
Both approaches have potential inefficiency. In the first scheme,
the same event gets sent over the wire many times if multiple
callbacks are registered. With the second scheme, unneccessary
events get sent over the wire if a per-domain filter is set on
the client. The second scheme is far easier to implement though,
so this patch takes that approach.
* daemon/dispatch.h: Don't export remoteRelayDomainEvent since it
is no longer needed for unregistering callbacks, instead the
unique callback ID is used
* daemon/libvirtd.c, daemon/libvirtd.h: Track and unregister
callbacks based on callback ID, instead of function pointer
* daemon/remote.c: Switch over to using virConnectDomainEventRegisterAny
instead of legacy virConnectDomainEventRegister function. Refactor
remoteDispatchDomainEventSend() to cope with arbitrary event types
* src/driver.h, src/driver.c: Move verify() call into source file
instead of header, to avoid polluting the global namespace with
the verify function name
* src/remote/remote_driver.c: Implement new APIs for event
registration. Refactor processCallDispatchMessage() to cope
with arbitrary incoming event types. Merge remoteDomainQueueEvent()
into processCallDispatchMessage() to avoid duplication of code.
Rename remoteDomainReadEvent() to remoteDomainReadEventLifecycle()
* src/remote/remote_protocol.x: Define wire format for the new
virConnectDomainEventRegisterAny and virConnectDomainEventDeregisterAny
functions
The 'int virInterfaceIsActive()' method was directly returning the
value of the 'int active:1' bitfield in virIntefaceDefPtr. A bitfield
with a signed integer, will hold the values 0 and -1, not 0 and +1
as might be expected. This meant that virInterfaceIsActive() was
always returning -1 when the interface was active, not +1 & thus all
callers thought an error had occurred. To protect against this kind
of mistake again, change all bitfields to be unsigned ints
* daemon/libvirtd.h, src/conf/domain_conf.h, src/conf/interface_conf.h,
src/conf/network_conf.h: Change bitfields to unsigned int.
The daemon will attempt to unregister domain events on client disconnect,
even if no events were ever registered. This raises an unneeded error.
Track in the qemu_client structure if events have been registered, and
check this when performing cleanup.
The virStateInitialize() call for starting up stateful drivers
may require that the event loop is running already. This it is
neccessary to start the event loop before this call. At the
same time, network clients must not be processed until afte
virStateInitialize has completed.
The qemudListenUnix() and remoteListenTCP() methods must
therefore not register file handle watches, merely open the
network sockets & listen() on them. This means clients can
connected and are queued, pending completion of initialization
The qemudRunLoop() method is moved into a background thread
that is started early to allow access to the event loop during
driver initialization. The main process thread leader pretty
much does nothing once the daemon is running, merely waits
for the event loop thread to quit
* daemon/libvirtd.c, daemon/libvirtd.h: Move event loop into
a background thread
* daemon/THREADING.txt: Rewrite docs to better reflect reality
* daemon/libvirtd.c: Introduce a daemonSetupSignals() method
and put all signal handling code there
* daemon/libvirtd.h: Add sigread/sigwrite to qemud_server type
* daemon/dispatch.c: Set streamTX flag on outgoing data packets
* daemon/qemud.h: Add streamTX flag to track outgoing data
* daemon/qemud.c: Re-enable further TX when outgoing data packet
has been fully sent.
* daemon/stream.h, daemon/stream.c: Add method for enabling TX.
Support reading from streams and transmitting data out to client
Defines the extensions to the remote protocol for generic
data streams. Adds a bunch of helper code to the libvirtd
daemon for working with data streams.
* daemon/Makefile.am: Add stream.c/stream.h to build
* daemon/stream.c, qemud/stream.h: Generic helper functions for
creating new streams, associating streams with clients, finding
existing streams for a client and removing/deleting streams.
* src/remote/remote_protocol.x: Add a new 'REMOTE_STREAM' constant
for the 'enum remote_message_type' for encoding stream data
in wire messages. Add a new 'REMOTE_CONTINUE' constant to
'enum remote_message_status' to indicate further data stream
messsages are expected to follow. Document how the
remote_message_header is used to encode data streams
* src/remote/remote_protocol.h: Regenerate
* daemon/dispatch.c: Remove assumption that a error message
sent to client is always type=REMOTE_REPLY. It may now
also be type=REMOTE_STREAM. Add convenient method for
sending outgoing stream data packets. Log and ignore
non-filtered incoming stream packets. Add a method for
serializing a stream error message
* daemon/dispatch.h: Add API for serializing stream errors
and sending stream data packets
* daemon/qemud.h: Add struct qemud_client_stream for tracking
active data streams for clients. Tweak filter function
operation so that it accepts a client object too.
* daemon/qemud.c: Refactor code for free'ing message objects
which have been fully transmitted into separate method.
Release all active streams when client shuts down. Change
filter function to be responsible for queueing the message