2007-06-11 15:47:01 +04:00
/*
2009-07-10 15:20:03 +04:00
* remote . c : handlers for RPC method calls
2007-06-11 15:47:01 +04:00
*
2011-02-08 01:04:17 +03:00
* Copyright ( C ) 2007 - 2011 Red Hat , Inc .
2007-06-11 15:47:01 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* 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
*
* Author : Richard W . M . Jones < rjones @ redhat . com >
*/
# include <config.h>
2009-02-05 19:28:30 +03:00
# include "virterror_internal.h"
2007-06-11 15:47:01 +04:00
2009-08-06 16:54:08 +04:00
# if HAVE_POLKIT0
2010-03-09 21:22:22 +03:00
# include <polkit / polkit.h>
# include <polkit-dbus / polkit-dbus.h>
2007-12-05 21:21:27 +03:00
# endif
2009-07-10 15:20:03 +04:00
# include "remote.h"
2011-05-16 21:13:11 +04:00
# include "libvirtd.h"
2008-11-05 02:22:06 +03:00
# include "libvirt_internal.h"
# include "datatypes.h"
2008-06-06 14:52:01 +04:00
# include "memory.h"
2011-05-16 21:13:11 +04:00
# include "logging.h"
2009-05-19 17:15:50 +04:00
# include "util.h"
2009-09-30 14:51:54 +04:00
# include "stream.h"
2010-10-12 15:22:03 +04:00
# include "uuid.h"
2010-10-20 20:29:56 +04:00
# include "network.h"
2010-04-17 06:09:25 +04:00
# include "libvirt/libvirt-qemu.h"
2011-03-22 20:55:45 +03:00
# include "command.h"
2011-06-24 22:16:05 +04:00
# include "intprops.h"
2011-05-16 21:13:11 +04:00
# include "virnetserverservice.h"
2011-07-08 01:12:26 +04:00
# include "virnetserver.h"
2011-05-16 21:13:11 +04:00
# include "remote_protocol.h"
# include "qemu_protocol.h"
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
# define VIR_FROM_THIS VIR_FROM_RPC
2007-12-05 18:24:15 +03:00
2011-04-13 19:21:35 +04:00
# define virNetError(code, ...) \
virReportErrorHelper ( VIR_FROM_THIS , code , __FILE__ , \
__FUNCTION__ , __LINE__ , __VA_ARGS__ )
2011-05-30 14:58:57 +04:00
# if SIZEOF_LONG < 8
# define HYPER_TO_TYPE(_type, _to, _from) \
do { \
if ( ( _from ) ! = ( _type ) ( _from ) ) { \
virNetError ( VIR_ERR_INTERNAL_ERROR , \
_ ( " conversion from hyper to %s overflowed " ) , # _type ) ; \
goto cleanup ; \
} \
( _to ) = ( _from ) ; \
} while ( 0 )
# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
# define HYPER_TO_ULONG(_to, _from) HYPER_TO_TYPE(unsigned long, _to, _from)
# else
# define HYPER_TO_LONG(_to, _from) (_to) = (_from)
# define HYPER_TO_ULONG(_to, _from) (_to) = (_from)
# endif
2011-04-12 20:34:30 +04:00
static virDomainPtr get_nonnull_domain ( virConnectPtr conn , remote_nonnull_domain domain ) ;
static virNetworkPtr get_nonnull_network ( virConnectPtr conn , remote_nonnull_network network ) ;
static virInterfacePtr get_nonnull_interface ( virConnectPtr conn , remote_nonnull_interface iface ) ;
static virStoragePoolPtr get_nonnull_storage_pool ( virConnectPtr conn , remote_nonnull_storage_pool pool ) ;
static virStorageVolPtr get_nonnull_storage_vol ( virConnectPtr conn , remote_nonnull_storage_vol vol ) ;
static virSecretPtr get_nonnull_secret ( virConnectPtr conn , remote_nonnull_secret secret ) ;
static virNWFilterPtr get_nonnull_nwfilter ( virConnectPtr conn , remote_nonnull_nwfilter nwfilter ) ;
2011-04-13 22:10:03 +04:00
static virDomainSnapshotPtr get_nonnull_domain_snapshot ( virDomainPtr dom , remote_nonnull_domain_snapshot snapshot ) ;
2011-04-12 20:34:30 +04:00
static void make_nonnull_domain ( remote_nonnull_domain * dom_dst , virDomainPtr dom_src ) ;
static void make_nonnull_network ( remote_nonnull_network * net_dst , virNetworkPtr net_src ) ;
static void make_nonnull_interface ( remote_nonnull_interface * interface_dst , virInterfacePtr interface_src ) ;
static void make_nonnull_storage_pool ( remote_nonnull_storage_pool * pool_dst , virStoragePoolPtr pool_src ) ;
static void make_nonnull_storage_vol ( remote_nonnull_storage_vol * vol_dst , virStorageVolPtr vol_src ) ;
static void make_nonnull_node_device ( remote_nonnull_node_device * dev_dst , virNodeDevicePtr dev_src ) ;
static void make_nonnull_secret ( remote_nonnull_secret * secret_dst , virSecretPtr secret_src ) ;
static void make_nonnull_nwfilter ( remote_nonnull_nwfilter * net_dst , virNWFilterPtr nwfilter_src ) ;
static void make_nonnull_domain_snapshot ( remote_nonnull_domain_snapshot * snapshot_dst , virDomainSnapshotPtr snapshot_src ) ;
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
static int
remoteSerializeTypedParameters ( virTypedParameterPtr params ,
int nparams ,
remote_typed_param * * ret_params_val ,
u_int * ret_params_len ) ;
static virTypedParameterPtr
remoteDeserializeTypedParameters ( remote_typed_param * args_params_val ,
u_int args_params_len ,
int limit ,
int * nparams ) ;
2008-12-05 01:03:24 +03:00
2011-05-16 21:13:11 +04:00
# include "remote_dispatch.h"
# include "qemu_dispatch.h"
2010-04-17 06:09:25 +04:00
2008-10-23 17:18:18 +04:00
/* Prototypes */
static void
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( virNetServerClientPtr client ,
virNetServerProgramPtr program ,
2011-04-12 20:34:30 +04:00
int procnr ,
xdrproc_t proc ,
void * data ) ;
2007-12-05 18:24:15 +03:00
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
static int remoteRelayDomainEventLifecycle ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
int event ,
int detail ,
void * opaque )
2008-10-23 17:18:18 +04:00
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
2010-03-19 17:28:23 +03:00
remote_domain_event_lifecycle_msg data ;
2008-10-23 17:18:18 +04:00
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain lifecycle event %d %d " , event , detail ) ;
2009-07-10 15:48:50 +04:00
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
data . event = event ;
data . detail = detail ;
2009-01-20 22:25:15 +03:00
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE ,
( xdrproc_t ) xdr_remote_domain_event_lifecycle_msg , & data ) ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
2008-10-23 17:18:18 +04:00
return 0 ;
}
2007-12-05 18:24:15 +03:00
2010-03-18 18:25:38 +03:00
static int remoteRelayDomainEventReboot ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
2010-03-18 18:25:38 +03:00
remote_domain_event_reboot_msg data ;
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain reboot event %s %d " , dom - > name , dom - > id ) ;
2010-03-18 18:25:38 +03:00
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
2010-03-18 18:25:38 +03:00
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_REBOOT ,
( xdrproc_t ) xdr_remote_domain_event_reboot_msg , & data ) ;
2010-03-18 18:25:38 +03:00
return 0 ;
}
2007-12-05 18:24:15 +03:00
2010-03-18 21:28:15 +03:00
static int remoteRelayDomainEventRTCChange ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
long long offset ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
2010-03-18 21:28:15 +03:00
remote_domain_event_rtc_change_msg data ;
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain rtc change event %s %d %lld " , dom - > name , dom - > id , offset ) ;
2010-03-18 21:28:15 +03:00
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
2010-03-18 21:28:15 +03:00
data . offset = offset ;
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE ,
( xdrproc_t ) xdr_remote_domain_event_rtc_change_msg , & data ) ;
2010-03-18 21:28:15 +03:00
return 0 ;
}
Add support for an explicit watchdog event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
2010-03-18 22:07:48 +03:00
static int remoteRelayDomainEventWatchdog ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
int action ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
Add support for an explicit watchdog event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
2010-03-18 22:07:48 +03:00
remote_domain_event_watchdog_msg data ;
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain watchdog event %s %d %d " , dom - > name , dom - > id , action ) ;
Add support for an explicit watchdog event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
2010-03-18 22:07:48 +03:00
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
Add support for an explicit watchdog event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
2010-03-18 22:07:48 +03:00
data . action = action ;
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_WATCHDOG ,
( xdrproc_t ) xdr_remote_domain_event_watchdog_msg , & data ) ;
Add support for an explicit watchdog event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
2010-03-18 22:07:48 +03:00
return 0 ;
}
Add support for an explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
static int remoteRelayDomainEventIOError ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
const char * srcPath ,
const char * devAlias ,
int action ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
Add support for an explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
remote_domain_event_io_error_msg data ;
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain io error %s %d %s %s %d " , dom - > name , dom - > id , srcPath , devAlias , action ) ;
Add support for an explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
Add support for an explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
data . srcPath = ( char * ) srcPath ;
data . devAlias = ( char * ) devAlias ;
data . action = action ;
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR ,
( xdrproc_t ) xdr_remote_domain_event_io_error_msg , & data ) ;
Add support for an explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
return 0 ;
}
Add support for another explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
static int remoteRelayDomainEventIOErrorReason ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
const char * srcPath ,
const char * devAlias ,
int action ,
const char * reason ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
Add support for another explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
remote_domain_event_io_error_reason_msg data ;
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain io error %s %d %s %s %d %s " ,
dom - > name , dom - > id , srcPath , devAlias , action , reason ) ;
Add support for another explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
Add support for another explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
data . srcPath = ( char * ) srcPath ;
data . devAlias = ( char * ) devAlias ;
data . action = action ;
data . reason = ( char * ) reason ;
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON ,
( xdrproc_t ) xdr_remote_domain_event_io_error_reason_msg , & data ) ;
Add support for another explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
return 0 ;
}
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
static int remoteRelayDomainEventGraphics ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
int phase ,
virDomainEventGraphicsAddressPtr local ,
virDomainEventGraphicsAddressPtr remote ,
const char * authScheme ,
virDomainEventGraphicsSubjectPtr subject ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
remote_domain_event_graphics_msg data ;
int i ;
if ( ! client )
return - 1 ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Relaying domain graphics event %s %d %d - %d %s %s - %d %s %s - %s " , dom - > name , dom - > id , phase ,
local - > family , local - > service , local - > node ,
remote - > family , remote - > service , remote - > node ,
authScheme ) ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Subject %d " , subject - > nidentity ) ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
for ( i = 0 ; i < subject - > nidentity ; i + + ) {
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " %s=%s " , subject - > identities [ i ] . type , subject - > identities [ i ] . name ) ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
}
/* build return data */
memset ( & data , 0 , sizeof data ) ;
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( & data . dom , dom ) ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
data . phase = phase ;
data . authScheme = ( char * ) authScheme ;
data . local . family = local - > family ;
data . local . node = ( char * ) local - > node ;
data . local . service = ( char * ) local - > service ;
data . remote . family = remote - > family ;
data . remote . node = ( char * ) remote - > node ;
data . remote . service = ( char * ) remote - > service ;
data . subject . subject_len = subject - > nidentity ;
if ( VIR_ALLOC_N ( data . subject . subject_val , data . subject . subject_len ) < 0 ) {
2011-05-16 21:13:11 +04:00
virReportOOMError ( ) ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
return - 1 ;
}
for ( i = 0 ; i < data . subject . subject_len ; i + + ) {
data . subject . subject_val [ i ] . type = ( char * ) subject - > identities [ i ] . type ;
data . subject . subject_val [ i ] . name = ( char * ) subject - > identities [ i ] . name ;
}
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-04-12 20:34:30 +04:00
REMOTE_PROC_DOMAIN_EVENT_GRAPHICS ,
( xdrproc_t ) xdr_remote_domain_event_graphics_msg , & data ) ;
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
VIR_FREE ( data . subject . subject_val ) ;
return 0 ;
}
2011-05-29 16:21:53 +04:00
static int remoteRelayDomainEventControlError ( virConnectPtr conn ATTRIBUTE_UNUSED ,
virDomainPtr dom ,
void * opaque )
{
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client = opaque ;
2011-05-29 16:21:53 +04:00
remote_domain_event_control_error_msg data ;
if ( ! client )
return - 1 ;
VIR_DEBUG ( " Relaying domain control error %s %d " , dom - > name , dom - > id ) ;
/* build return data */
memset ( & data , 0 , sizeof data ) ;
make_nonnull_domain ( & data . dom , dom ) ;
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( client , remoteProgram ,
2011-05-29 16:21:53 +04:00
REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR ,
( xdrproc_t ) xdr_remote_domain_event_control_error_msg , & data ) ;
return 0 ;
}
2010-03-18 18:25:38 +03:00
static virConnectDomainEventGenericCallback domainEventCallbacks [ ] = {
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventLifecycle ) ,
2010-03-18 18:25:38 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventReboot ) ,
2010-03-18 21:28:15 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventRTCChange ) ,
Add support for an explicit watchdog event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
2010-03-18 22:07:48 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventWatchdog ) ,
Add support for an explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventIOError ) ,
Add domain events for graphics network clients
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
2010-03-19 16:27:45 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventGraphics ) ,
Add support for another explicit IO error event
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
2010-03-18 22:37:44 +03:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventIOErrorReason ) ,
2011-05-29 16:21:53 +04:00
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventControlError ) ,
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
} ;
verify ( ARRAY_CARDINALITY ( domainEventCallbacks ) = = VIR_DOMAIN_EVENT_ID_LAST ) ;
2011-05-16 21:13:11 +04:00
/*
* You must hold lock for at least the client
* We don ' t free stuff here , merely disconnect the client ' s
* network socket & resources .
* We keep the libvirt connection open until any async
* jobs have finished , then clean it up elsewhere
*/
static void remoteClientFreeFunc ( void * data )
{
struct daemonClientPrivate * priv = data ;
/* Deregister event delivery callback */
if ( priv - > conn ) {
int i ;
for ( i = 0 ; i < VIR_DOMAIN_EVENT_ID_LAST ; i + + ) {
if ( priv - > domainEventCallbackID [ i ] ! = - 1 ) {
VIR_DEBUG ( " Deregistering to relay remote events %d " , i ) ;
virConnectDomainEventDeregisterAny ( priv - > conn ,
priv - > domainEventCallbackID [ i ] ) ;
}
priv - > domainEventCallbackID [ i ] = - 1 ;
}
virConnectClose ( priv - > conn ) ;
}
VIR_FREE ( priv ) ;
}
int remoteClientInitHook ( virNetServerPtr srv ATTRIBUTE_UNUSED ,
virNetServerClientPtr client )
{
struct daemonClientPrivate * priv ;
int i ;
if ( VIR_ALLOC ( priv ) < 0 ) {
virReportOOMError ( ) ;
return - 1 ;
}
if ( virMutexInit ( & priv - > lock ) < 0 ) {
VIR_FREE ( priv ) ;
virReportOOMError ( ) ;
return - 1 ;
}
for ( i = 0 ; i < VIR_DOMAIN_EVENT_ID_LAST ; i + + )
priv - > domainEventCallbackID [ i ] = - 1 ;
virNetServerClientSetPrivateData ( client , priv , remoteClientFreeFunc ) ;
return 0 ;
}
2007-06-11 15:47:01 +04:00
/*----- Functions. -----*/
static int
2011-05-16 21:13:11 +04:00
remoteDispatchOpen ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
struct remote_open_args * args )
2007-06-11 15:47:01 +04:00
{
const char * name ;
2011-04-13 19:21:35 +04:00
int flags ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv = virNetServerClientGetPrivateData ( client ) ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " priv=%p conn=%p " , priv , priv - > conn ) ;
virMutexLock ( & priv - > lock ) ;
/* Already opened? */
if ( priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection already open " ) ) ;
goto cleanup ;
}
2007-06-11 15:47:01 +04:00
name = args - > name ? * args - > name : NULL ;
/* If this connection arrived on a readonly socket, force
* the connection to be readonly .
*/
flags = args - > flags ;
2011-05-16 21:13:11 +04:00
if ( virNetServerClientGetReadonly ( client ) )
flags | = VIR_CONNECT_RO ;
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
priv - > conn =
2007-06-11 15:47:01 +04:00
flags & VIR_CONNECT_RO
2011-04-12 20:34:30 +04:00
? virConnectOpenReadOnly ( name )
: virConnectOpen ( name ) ;
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
if ( priv - > conn = = NULL )
2011-04-13 19:21:35 +04:00
goto cleanup ;
rv = 0 ;
2008-12-05 01:12:53 +03:00
2011-04-13 19:21:35 +04:00
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2007-06-11 15:47:01 +04:00
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchClose ( virNetServerPtr server ATTRIBUTE_UNUSED ,
2011-07-08 15:54:29 +04:00
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
2011-05-16 21:13:11 +04:00
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED )
2007-06-11 15:47:01 +04:00
{
2011-07-08 15:54:29 +04:00
virNetServerClientDelayedClose ( client ) ;
2008-12-05 01:12:53 +03:00
return 0 ;
2007-06-11 15:47:01 +04:00
}
2011-05-16 21:13:11 +04:00
2007-06-22 17:16:10 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetSchedulerType ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_domain_get_scheduler_type_args * args ,
remote_domain_get_scheduler_type_ret * ret )
2007-06-22 17:16:10 +04:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2007-06-22 17:16:10 +04:00
char * type ;
int nparams ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2007-06-22 17:16:10 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2007-06-22 17:16:10 +04:00
2011-04-13 21:50:40 +04:00
if ( ! ( type = virDomainGetSchedulerType ( dom , & nparams ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2007-06-22 17:16:10 +04:00
ret - > type = type ;
ret - > nparams = nparams ;
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
2007-06-22 17:16:10 +04:00
}
2011-05-18 00:58:40 +04:00
/* Helper to serialize typed parameters. */
static int
remoteSerializeTypedParameters ( virTypedParameterPtr params ,
int nparams ,
2011-05-30 22:12:18 +04:00
remote_typed_param * * ret_params_val ,
u_int * ret_params_len )
2011-05-18 00:58:40 +04:00
{
int i ;
int rv = - 1 ;
remote_typed_param * val ;
* ret_params_len = nparams ;
if ( VIR_ALLOC_N ( val , nparams ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
for ( i = 0 ; i < nparams ; + + i ) {
/* remoteDispatchClientRequest will free this: */
val [ i ] . field = strdup ( params [ i ] . field ) ;
if ( val [ i ] . field = = NULL ) {
virReportOOMError ( ) ;
goto cleanup ;
}
val [ i ] . value . type = params [ i ] . type ;
switch ( params [ i ] . type ) {
case VIR_TYPED_PARAM_INT :
val [ i ] . value . remote_typed_param_value_u . i = params [ i ] . value . i ;
break ;
case VIR_TYPED_PARAM_UINT :
val [ i ] . value . remote_typed_param_value_u . ui = params [ i ] . value . ui ;
break ;
case VIR_TYPED_PARAM_LLONG :
val [ i ] . value . remote_typed_param_value_u . l = params [ i ] . value . l ;
break ;
case VIR_TYPED_PARAM_ULLONG :
val [ i ] . value . remote_typed_param_value_u . ul = params [ i ] . value . ul ;
break ;
case VIR_TYPED_PARAM_DOUBLE :
val [ i ] . value . remote_typed_param_value_u . d = params [ i ] . value . d ;
break ;
case VIR_TYPED_PARAM_BOOLEAN :
val [ i ] . value . remote_typed_param_value_u . b = params [ i ] . value . b ;
break ;
default :
virNetError ( VIR_ERR_RPC , _ ( " unknown parameter type: %d " ) ,
params [ i ] . type ) ;
goto cleanup ;
}
}
* ret_params_val = val ;
val = NULL ;
rv = 0 ;
cleanup :
if ( val ) {
for ( i = 0 ; i < nparams ; i + + )
VIR_FREE ( val [ i ] . field ) ;
VIR_FREE ( val ) ;
}
return rv ;
}
/* Helper to deserialize typed parameters. */
static virTypedParameterPtr
2011-05-30 22:12:18 +04:00
remoteDeserializeTypedParameters ( remote_typed_param * args_params_val ,
u_int args_params_len ,
2011-05-18 00:58:40 +04:00
int limit ,
int * nparams )
{
int i ;
int rv = - 1 ;
virTypedParameterPtr params = NULL ;
/* Check the length of the returned list carefully. */
if ( args_params_len > limit ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
}
if ( VIR_ALLOC_N ( params , args_params_len ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
* nparams = args_params_len ;
/* Deserialise the result. */
for ( i = 0 ; i < args_params_len ; + + i ) {
if ( virStrcpyStatic ( params [ i ] . field ,
args_params_val [ i ] . field ) = = NULL ) {
virNetError ( VIR_ERR_INTERNAL_ERROR ,
_ ( " Parameter %s too big for destination " ) ,
args_params_val [ i ] . field ) ;
goto cleanup ;
}
params [ i ] . type = args_params_val [ i ] . value . type ;
switch ( params [ i ] . type ) {
case VIR_TYPED_PARAM_INT :
params [ i ] . value . i =
args_params_val [ i ] . value . remote_typed_param_value_u . i ;
break ;
case VIR_TYPED_PARAM_UINT :
params [ i ] . value . ui =
args_params_val [ i ] . value . remote_typed_param_value_u . ui ;
break ;
case VIR_TYPED_PARAM_LLONG :
params [ i ] . value . l =
args_params_val [ i ] . value . remote_typed_param_value_u . l ;
break ;
case VIR_TYPED_PARAM_ULLONG :
params [ i ] . value . ul =
args_params_val [ i ] . value . remote_typed_param_value_u . ul ;
break ;
case VIR_TYPED_PARAM_DOUBLE :
params [ i ] . value . d =
args_params_val [ i ] . value . remote_typed_param_value_u . d ;
break ;
case VIR_TYPED_PARAM_BOOLEAN :
params [ i ] . value . b =
args_params_val [ i ] . value . remote_typed_param_value_u . b ;
break ;
default :
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " unknown parameter type: %d " ) ,
params [ i ] . type ) ;
goto cleanup ;
}
}
rv = 0 ;
cleanup :
if ( rv < 0 )
VIR_FREE ( params ) ;
return params ;
}
2007-06-22 17:16:10 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetSchedulerParameters ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_domain_get_scheduler_parameters_args * args ,
remote_domain_get_scheduler_parameters_ret * ret )
2007-06-22 17:16:10 +04:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2011-05-26 21:39:04 +04:00
virTypedParameterPtr params = NULL ;
2011-05-03 21:24:23 +04:00
int nparams = args - > nparams ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2007-06-22 17:16:10 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2007-06-22 17:16:10 +04:00
if ( nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
2007-06-22 17:16:10 +04:00
}
2011-04-13 19:21:35 +04:00
if ( VIR_ALLOC_N ( params , nparams ) < 0 )
goto no_memory ;
2007-06-22 17:16:10 +04:00
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2007-06-22 17:16:10 +04:00
2011-04-13 21:50:40 +04:00
if ( virDomainGetSchedulerParameters ( dom , params , & nparams ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2007-06-22 17:16:10 +04:00
2011-05-18 00:58:40 +04:00
if ( remoteSerializeTypedParameters ( params , nparams ,
2011-05-30 22:12:18 +04:00
& ret - > params . params_val ,
& ret - > params . params_len ) < 0 )
2011-05-18 01:45:03 +04:00
goto cleanup ;
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-05-18 01:45:03 +04:00
if ( dom )
virDomainFree ( dom ) ;
VIR_FREE ( params ) ;
return rv ;
no_memory :
virReportOOMError ( ) ;
goto cleanup ;
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetSchedulerParametersFlags ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-05-18 01:45:03 +04:00
remote_domain_get_scheduler_parameters_flags_args * args ,
remote_domain_get_scheduler_parameters_flags_ret * ret )
{
virDomainPtr dom = NULL ;
virTypedParameterPtr params = NULL ;
int nparams = args - > nparams ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-05-18 01:45:03 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-05-18 01:45:03 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
if ( nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
}
if ( VIR_ALLOC_N ( params , nparams ) < 0 )
goto no_memory ;
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-05-18 01:45:03 +04:00
goto cleanup ;
if ( virDomainGetSchedulerParametersFlags ( dom , params , & nparams ,
args - > flags ) < 0 )
goto cleanup ;
if ( remoteSerializeTypedParameters ( params , nparams ,
2011-05-30 22:12:18 +04:00
& ret - > params . params_val ,
& ret - > params . params_len ) < 0 )
2011-05-18 00:58:40 +04:00
goto cleanup ;
2007-06-22 17:16:10 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
2008-06-06 14:52:01 +04:00
cleanup :
2011-05-18 00:58:40 +04:00
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
if ( dom )
virDomainFree ( dom ) ;
2008-06-06 14:52:01 +04:00
VIR_FREE ( params ) ;
2011-04-13 19:21:35 +04:00
return rv ;
no_memory :
virReportOOMError ( ) ;
goto cleanup ;
2007-06-22 17:16:10 +04:00
}
2009-12-20 15:43:19 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMemoryStats ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_domain_memory_stats_args * args ,
remote_domain_memory_stats_ret * ret )
2009-12-20 15:43:19 +03:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2009-12-20 15:43:19 +03:00
struct _virDomainMemoryStat * stats ;
2011-04-13 21:13:37 +04:00
int nr_stats , i ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2009-12-20 15:43:19 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2009-12-20 15:43:19 +03:00
if ( args - > maxStats > REMOTE_DOMAIN_MEMORY_STATS_MAX ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " ,
_ ( " maxStats > REMOTE_DOMAIN_MEMORY_STATS_MAX " ) ) ;
goto cleanup ;
2009-12-20 15:43:19 +03:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2009-12-20 15:43:19 +03:00
/* Allocate stats array for making dispatch call */
if ( VIR_ALLOC_N ( stats , args - > maxStats ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2010-06-12 19:13:33 +04:00
}
2009-12-20 15:43:19 +03:00
2011-04-12 20:34:30 +04:00
nr_stats = virDomainMemoryStats ( dom , stats , args - > maxStats , 0 ) ;
2011-04-13 21:23:00 +04:00
if ( nr_stats < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2009-12-20 15:43:19 +03:00
/* Allocate return buffer */
if ( VIR_ALLOC_N ( ret - > stats . stats_val , args - > maxStats ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2009-12-20 15:43:19 +03:00
}
/* Copy the stats into the xdr return structure */
for ( i = 0 ; i < nr_stats ; i + + ) {
ret - > stats . stats_val [ i ] . tag = stats [ i ] . tag ;
ret - > stats . stats_val [ i ] . val = stats [ i ] . val ;
}
ret - > stats . stats_len = nr_stats ;
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
if ( dom )
virDomainFree ( dom ) ;
2009-12-20 15:43:19 +03:00
VIR_FREE ( stats ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2009-12-20 15:43:19 +03:00
}
2008-06-06 01:12:26 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainBlockPeek ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_domain_block_peek_args * args ,
remote_domain_block_peek_ret * ret )
2008-06-06 01:12:26 +04:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2008-06-06 01:12:26 +04:00
char * path ;
unsigned long long offset ;
size_t size ;
unsigned int flags ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2008-06-06 01:12:26 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2008-06-06 01:12:26 +04:00
path = args - > path ;
offset = args - > offset ;
size = args - > size ;
flags = args - > flags ;
if ( size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR ,
" %s " , _ ( " size > maximum buffer size " ) ) ;
goto cleanup ;
2008-06-06 01:12:26 +04:00
}
ret - > buffer . buffer_len = size ;
2011-04-12 20:34:30 +04:00
if ( VIR_ALLOC_N ( ret - > buffer . buffer_val , size ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2008-06-06 01:12:26 +04:00
}
2011-04-12 20:34:30 +04:00
if ( virDomainBlockPeek ( dom , path , offset , size ,
2011-04-13 21:23:00 +04:00
ret - > buffer . buffer_val , flags ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2008-06-06 01:12:26 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
VIR_FREE ( ret - > buffer . buffer_val ) ;
}
if ( dom )
virDomainFree ( dom ) ;
return rv ;
2008-06-06 01:12:26 +04:00
}
2008-06-10 14:43:28 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMemoryPeek ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_domain_memory_peek_args * args ,
remote_domain_memory_peek_ret * ret )
2008-06-10 14:43:28 +04:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2008-06-10 14:43:28 +04:00
unsigned long long offset ;
size_t size ;
unsigned int flags ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2008-06-10 14:43:28 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2008-06-10 14:43:28 +04:00
offset = args - > offset ;
size = args - > size ;
flags = args - > flags ;
if ( size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR ,
" %s " , _ ( " size > maximum buffer size " ) ) ;
goto cleanup ;
2008-06-10 14:43:28 +04:00
}
ret - > buffer . buffer_len = size ;
2011-04-12 20:34:30 +04:00
if ( VIR_ALLOC_N ( ret - > buffer . buffer_val , size ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2008-06-10 14:43:28 +04:00
}
2011-04-12 20:34:30 +04:00
if ( virDomainMemoryPeek ( dom , offset , size ,
2011-04-13 21:23:00 +04:00
ret - > buffer . buffer_val , flags ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2008-06-10 14:43:28 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
VIR_FREE ( ret - > buffer . buffer_val ) ;
}
if ( dom )
virDomainFree ( dom ) ;
return rv ;
2008-06-10 14:43:28 +04:00
}
2009-05-21 17:50:56 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetSecurityLabel ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_domain_get_security_label_args * args ,
remote_domain_get_security_label_ret * ret )
2009-05-21 17:50:56 +04:00
{
2011-04-22 19:09:33 +04:00
virDomainPtr dom = NULL ;
virSecurityLabelPtr seclabel = NULL ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-04-13 19:21:35 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-22 19:09:33 +04:00
goto cleanup ;
if ( VIR_ALLOC ( seclabel ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
if ( virDomainGetSecurityLabel ( dom , seclabel ) < 0 )
goto cleanup ;
ret - > label . label_len = strlen ( seclabel - > label ) + 1 ;
if ( VIR_ALLOC_N ( ret - > label . label_val , ret - > label . label_len ) < 0 ) {
virReportOOMError ( ) ;
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
}
strcpy ( ret - > label . label_val , seclabel - > label ) ;
ret - > enforcing = seclabel - > enforcing ;
2011-04-13 21:50:40 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
if ( dom )
virDomainFree ( dom ) ;
VIR_FREE ( seclabel ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2009-05-21 17:50:56 +04:00
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchNodeGetSecurityModel ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_node_get_security_model_ret * ret )
2009-05-21 17:50:56 +04:00
{
2011-04-22 19:09:33 +04:00
virSecurityModel secmodel ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-04-13 19:21:35 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-04-22 19:09:33 +04:00
memset ( & secmodel , 0 , sizeof secmodel ) ;
2011-05-16 21:13:11 +04:00
if ( virNodeGetSecurityModel ( priv - > conn , & secmodel ) < 0 )
2011-04-22 19:09:33 +04:00
goto cleanup ;
ret - > model . model_len = strlen ( secmodel . model ) + 1 ;
if ( VIR_ALLOC_N ( ret - > model . model_val , ret - > model . model_len ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
strcpy ( ret - > model . model_val , secmodel . model ) ;
ret - > doi . doi_len = strlen ( secmodel . doi ) + 1 ;
if ( VIR_ALLOC_N ( ret - > doi . doi_val , ret - > doi . doi_len ) < 0 ) {
virReportOOMError ( ) ;
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
}
strcpy ( ret - > doi . doi_val , secmodel . doi ) ;
2011-04-13 21:50:40 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2009-05-21 17:50:56 +04:00
}
2011-06-24 13:00:22 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetVcpuPinInfo ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-06-25 03:09:46 +04:00
remote_domain_get_vcpu_pin_info_args * args ,
remote_domain_get_vcpu_pin_info_ret * ret )
2011-06-24 13:00:22 +04:00
{
virDomainPtr dom = NULL ;
unsigned char * cpumaps = NULL ;
int num ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-06-24 13:00:22 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-06-24 13:00:22 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-06-24 13:00:22 +04:00
goto cleanup ;
if ( args - > ncpumaps > REMOTE_VCPUINFO_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " ncpumaps > REMOTE_VCPUINFO_MAX " ) ) ;
goto cleanup ;
}
if ( INT_MULTIPLY_OVERFLOW ( args - > ncpumaps , args - > maplen ) | |
args - > ncpumaps * args - > maplen > REMOTE_CPUMAPS_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " maxinfo * maplen > REMOTE_CPUMAPS_MAX " ) ) ;
goto cleanup ;
}
/* Allocate buffers to take the results. */
if ( args - > maplen > 0 & &
VIR_ALLOC_N ( cpumaps , args - > ncpumaps * args - > maplen ) < 0 )
goto no_memory ;
2011-06-25 03:09:46 +04:00
if ( ( num = virDomainGetVcpuPinInfo ( dom ,
2011-06-24 13:00:22 +04:00
args - > ncpumaps ,
cpumaps ,
args - > maplen ,
args - > flags ) ) < 0 )
goto cleanup ;
ret - > num = num ;
/* Don't need to allocate/copy the cpumaps if we make the reasonable
* assumption that unsigned char and char are the same size .
* Note that remoteDispatchClientRequest will free .
*/
ret - > cpumaps . cpumaps_len = args - > ncpumaps * args - > maplen ;
ret - > cpumaps . cpumaps_val = ( char * ) cpumaps ;
cpumaps = NULL ;
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-06-24 13:00:22 +04:00
VIR_FREE ( cpumaps ) ;
if ( dom )
virDomainFree ( dom ) ;
return rv ;
no_memory :
virReportOOMError ( ) ;
goto cleanup ;
}
2007-06-11 15:47:01 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetVcpus ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_domain_get_vcpus_args * args ,
remote_domain_get_vcpus_ret * ret )
2007-06-11 15:47:01 +04:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2011-04-22 19:09:33 +04:00
virVcpuInfoPtr info = NULL ;
unsigned char * cpumaps = NULL ;
int info_len , i ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2007-06-11 15:47:01 +04:00
2011-04-22 19:09:33 +04:00
if ( args - > maxinfo > REMOTE_VCPUINFO_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " maxinfo > REMOTE_VCPUINFO_MAX " ) ) ;
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
}
2011-04-13 19:21:35 +04:00
2011-06-24 22:16:05 +04:00
if ( INT_MULTIPLY_OVERFLOW ( args - > maxinfo , args - > maplen ) | |
args - > maxinfo * args - > maplen > REMOTE_CPUMAPS_MAX ) {
2011-04-22 19:09:33 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " maxinfo * maplen > REMOTE_CPUMAPS_MAX " ) ) ;
goto cleanup ;
}
/* Allocate buffers to take the results. */
if ( VIR_ALLOC_N ( info , args - > maxinfo ) < 0 )
goto no_memory ;
if ( args - > maplen > 0 & &
VIR_ALLOC_N ( cpumaps , args - > maxinfo * args - > maplen ) < 0 )
goto no_memory ;
if ( ( info_len = virDomainGetVcpus ( dom ,
info , args - > maxinfo ,
cpumaps , args - > maplen ) ) < 0 )
goto cleanup ;
/* Allocate the return buffer for info. */
ret - > info . info_len = info_len ;
if ( VIR_ALLOC_N ( ret - > info . info_val , info_len ) < 0 )
goto no_memory ;
for ( i = 0 ; i < info_len ; + + i ) {
ret - > info . info_val [ i ] . number = info [ i ] . number ;
ret - > info . info_val [ i ] . state = info [ i ] . state ;
ret - > info . info_val [ i ] . cpu_time = info [ i ] . cpuTime ;
ret - > info . info_val [ i ] . cpu = info [ i ] . cpu ;
}
/* Don't need to allocate/copy the cpumaps if we make the reasonable
* assumption that unsigned char and char are the same size .
* Note that remoteDispatchClientRequest will free .
*/
ret - > cpumaps . cpumaps_len = args - > maxinfo * args - > maplen ;
ret - > cpumaps . cpumaps_val = ( char * ) cpumaps ;
cpumaps = NULL ;
rv = 0 ;
2011-04-13 19:21:35 +04:00
cleanup :
2011-04-22 19:09:33 +04:00
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
VIR_FREE ( ret - > info . info_val ) ;
}
VIR_FREE ( cpumaps ) ;
VIR_FREE ( info ) ;
2011-04-13 19:21:35 +04:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
2011-04-22 19:09:33 +04:00
no_memory :
virReportOOMError ( ) ;
goto cleanup ;
2007-06-11 15:47:01 +04:00
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigratePrepare ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_domain_migrate_prepare_args * args ,
remote_domain_migrate_prepare_ret * ret )
2007-06-11 15:47:01 +04:00
{
2011-04-22 19:09:33 +04:00
char * cookie = NULL ;
int cookielen = 0 ;
char * uri_in ;
char * * uri_out ;
char * dname ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-04-22 19:09:33 +04:00
uri_in = args - > uri_in = = NULL ? NULL : * args - > uri_in ;
dname = args - > dname = = NULL ? NULL : * args - > dname ;
/* Wacky world of XDR ... */
if ( VIR_ALLOC ( uri_out ) < 0 ) {
virReportOOMError ( ) ;
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
}
2007-06-11 15:47:01 +04:00
2011-05-16 21:13:11 +04:00
if ( virDomainMigratePrepare ( priv - > conn , & cookie , & cookielen ,
2011-04-22 19:09:33 +04:00
uri_in , uri_out ,
args - > flags , dname , args - > resource ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2007-06-11 15:47:01 +04:00
2011-04-22 19:09:33 +04:00
/* remoteDispatchClientRequest will free cookie, uri_out and
* the string if there is one .
*/
ret - > cookie . cookie_len = cookielen ;
ret - > cookie . cookie_val = cookie ;
if ( * uri_out = = NULL ) {
ret - > uri_out = NULL ;
} else {
ret - > uri_out = uri_out ;
uri_out = NULL ;
}
2007-06-11 15:47:01 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
2007-07-24 18:21:03 +04:00
2011-04-13 19:21:35 +04:00
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
VIR_FREE ( uri_out ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2007-06-11 15:47:01 +04:00
}
2009-03-03 12:27:02 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigratePrepare2 ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_domain_migrate_prepare2_args * args ,
remote_domain_migrate_prepare2_ret * ret )
2009-03-03 12:27:02 +03:00
{
2011-04-22 19:09:33 +04:00
char * cookie = NULL ;
int cookielen = 0 ;
char * uri_in ;
char * * uri_out ;
char * dname ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2009-03-03 12:27:02 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-04-22 19:09:33 +04:00
uri_in = args - > uri_in = = NULL ? NULL : * args - > uri_in ;
dname = args - > dname = = NULL ? NULL : * args - > dname ;
2009-03-03 12:27:02 +03:00
2011-04-22 19:09:33 +04:00
/* Wacky world of XDR ... */
if ( VIR_ALLOC ( uri_out ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2011-04-03 13:21:25 +04:00
}
2011-05-16 21:13:11 +04:00
if ( virDomainMigratePrepare2 ( priv - > conn , & cookie , & cookielen ,
2011-04-22 19:09:33 +04:00
uri_in , uri_out ,
args - > flags , dname , args - > resource ,
args - > dom_xml ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2009-03-03 12:27:02 +03:00
2011-04-22 19:09:33 +04:00
/* remoteDispatchClientRequest will free cookie, uri_out and
* the string if there is one .
*/
ret - > cookie . cookie_len = cookielen ;
ret - > cookie . cookie_val = cookie ;
ret - > uri_out = * uri_out = = NULL ? NULL : uri_out ;
2009-03-03 12:27:02 +03:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2009-03-03 12:27:02 +03:00
}
2009-09-30 14:51:54 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetMemoryParameters ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_domain_get_memory_parameters_args * args ,
remote_domain_get_memory_parameters_ret * ret )
2009-09-30 14:51:54 +04:00
{
2011-04-22 19:09:33 +04:00
virDomainPtr dom = NULL ;
2011-05-26 21:39:04 +04:00
virTypedParameterPtr params = NULL ;
2011-04-22 19:09:33 +04:00
int nparams = args - > nparams ;
unsigned int flags ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-04-12 20:33:49 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2009-09-30 14:51:54 +04:00
2011-04-22 19:09:33 +04:00
flags = args - > flags ;
2009-09-30 14:51:54 +04:00
2011-04-22 19:09:33 +04:00
if ( nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
}
if ( VIR_ALLOC_N ( params , nparams ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2009-09-30 14:51:54 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2009-09-30 14:51:54 +04:00
2011-04-22 19:09:33 +04:00
if ( virDomainGetMemoryParameters ( dom , params , & nparams , flags ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2009-09-30 14:51:54 +04:00
2011-04-22 19:09:33 +04:00
/* In this case, we need to send back the number of parameters
* supported
*/
if ( args - > nparams = = 0 ) {
ret - > nparams = nparams ;
goto success ;
2011-04-13 19:21:35 +04:00
}
2011-05-18 00:58:40 +04:00
if ( remoteSerializeTypedParameters ( params , nparams ,
2011-05-30 22:12:18 +04:00
& ret - > params . params_val ,
& ret - > params . params_len ) < 0 )
2011-05-18 00:58:40 +04:00
goto cleanup ;
2007-06-11 15:47:01 +04:00
2011-04-22 19:09:33 +04:00
success :
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
2011-05-18 00:58:40 +04:00
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
if ( dom )
virDomainFree ( dom ) ;
2011-04-22 19:09:33 +04:00
VIR_FREE ( params ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2007-06-11 15:47:01 +04:00
}
2010-10-12 21:23:04 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetBlkioParameters ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_domain_get_blkio_parameters_args * args ,
remote_domain_get_blkio_parameters_ret * ret )
2010-10-12 21:23:04 +04:00
{
2011-04-13 19:21:35 +04:00
virDomainPtr dom = NULL ;
2011-05-26 21:39:04 +04:00
virTypedParameterPtr params = NULL ;
2011-05-03 21:24:23 +04:00
int nparams = args - > nparams ;
2010-10-12 21:23:04 +04:00
unsigned int flags ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2010-10-12 21:23:04 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2010-10-12 21:23:04 +04:00
flags = args - > flags ;
2011-04-22 19:09:33 +04:00
if ( nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
2010-10-12 21:23:04 +04:00
}
if ( VIR_ALLOC_N ( params , nparams ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2010-10-12 21:23:04 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2010-10-12 21:23:04 +04:00
2011-04-22 19:09:33 +04:00
if ( virDomainGetBlkioParameters ( dom , params , & nparams , flags ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-13 21:50:40 +04:00
2010-10-12 21:23:04 +04:00
/* In this case, we need to send back the number of parameters
* supported
*/
if ( args - > nparams = = 0 ) {
ret - > nparams = nparams ;
goto success ;
}
2011-05-18 00:58:40 +04:00
if ( remoteSerializeTypedParameters ( params , nparams ,
2011-05-30 22:12:18 +04:00
& ret - > params . params_val ,
& ret - > params . params_len ) < 0 )
2011-05-18 00:58:40 +04:00
goto cleanup ;
2011-02-22 08:34:28 +03:00
2011-04-13 19:21:35 +04:00
success :
rv = 0 ;
2011-02-22 08:34:28 +03:00
2011-04-13 19:21:35 +04:00
cleanup :
2011-05-18 00:58:40 +04:00
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
VIR_FREE ( params ) ;
2011-04-13 19:21:35 +04:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
2011-02-22 08:34:28 +03:00
}
2011-06-07 05:01:12 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchNodeGetCPUStats ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_node_get_cpu_stats_args * args ,
remote_node_get_cpu_stats_ret * ret )
2011-06-07 05:01:12 +04:00
{
2011-06-15 14:39:57 +04:00
virNodeCPUStatsPtr params = NULL ;
2011-06-07 05:01:12 +04:00
int i ;
int cpuNum = args - > cpuNum ;
int nparams = args - > nparams ;
unsigned int flags ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-06-07 05:01:12 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-06-07 05:01:12 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
flags = args - > flags ;
if ( nparams > REMOTE_NODE_CPU_STATS_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
}
if ( VIR_ALLOC_N ( params , nparams ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( virNodeGetCPUStats ( priv - > conn , cpuNum , params , & nparams , flags ) < 0 )
2011-06-07 05:01:12 +04:00
goto cleanup ;
/* In this case, we need to send back the number of stats
* supported
*/
if ( args - > nparams = = 0 ) {
ret - > nparams = nparams ;
goto success ;
}
/* Serialise the memory parameters. */
ret - > params . params_len = nparams ;
if ( VIR_ALLOC_N ( ret - > params . params_val , nparams ) < 0 )
goto no_memory ;
for ( i = 0 ; i < nparams ; + + i ) {
/* remoteDispatchClientRequest will free this: */
ret - > params . params_val [ i ] . field = strdup ( params [ i ] . field ) ;
if ( ret - > params . params_val [ i ] . field = = NULL )
goto no_memory ;
ret - > params . params_val [ i ] . value = params [ i ] . value ;
}
success :
rv = 0 ;
2011-06-07 05:05:40 +04:00
cleanup :
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-06-07 05:05:40 +04:00
if ( ret - > params . params_val ) {
for ( i = 0 ; i < nparams ; i + + )
VIR_FREE ( ret - > params . params_val [ i ] . field ) ;
VIR_FREE ( ret - > params . params_val ) ;
}
}
VIR_FREE ( params ) ;
return rv ;
no_memory :
virReportOOMError ( ) ;
goto cleanup ;
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchNodeGetMemoryStats ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_node_get_memory_stats_args * args ,
remote_node_get_memory_stats_ret * ret )
2011-06-07 05:05:40 +04:00
{
2011-06-15 14:39:57 +04:00
virNodeMemoryStatsPtr params = NULL ;
2011-06-07 05:05:40 +04:00
int i ;
int cellNum = args - > cellNum ;
int nparams = args - > nparams ;
unsigned int flags ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-06-07 05:05:40 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-06-07 05:05:40 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
flags = args - > flags ;
if ( nparams > REMOTE_NODE_MEMORY_STATS_MAX ) {
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " nparams too large " ) ) ;
goto cleanup ;
}
if ( VIR_ALLOC_N ( params , nparams ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( virNodeGetMemoryStats ( priv - > conn , cellNum , params , & nparams , flags ) < 0 )
2011-06-07 05:05:40 +04:00
goto cleanup ;
/* In this case, we need to send back the number of parameters
* supported
*/
if ( args - > nparams = = 0 ) {
ret - > nparams = nparams ;
goto success ;
}
/* Serialise the memory parameters. */
ret - > params . params_len = nparams ;
if ( VIR_ALLOC_N ( ret - > params . params_val , nparams ) < 0 )
goto no_memory ;
for ( i = 0 ; i < nparams ; + + i ) {
/* remoteDispatchClientRequest will free this: */
ret - > params . params_val [ i ] . field = strdup ( params [ i ] . field ) ;
if ( ret - > params . params_val [ i ] . field = = NULL )
goto no_memory ;
ret - > params . params_val [ i ] . value = params [ i ] . value ;
}
success :
rv = 0 ;
2011-06-07 05:01:12 +04:00
cleanup :
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-06-07 05:01:12 +04:00
if ( ret - > params . params_val ) {
for ( i = 0 ; i < nparams ; i + + )
VIR_FREE ( ret - > params . params_val [ i ] . field ) ;
VIR_FREE ( ret - > params . params_val ) ;
}
}
VIR_FREE ( params ) ;
return rv ;
no_memory :
virReportOOMError ( ) ;
goto cleanup ;
}
2009-05-20 18:26:49 +04:00
/*-------------------------------------------------------------*/
2007-12-05 18:24:15 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchAuthList ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_auth_list_ret * ret )
2007-12-05 18:24:15 +03:00
{
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
int auth = virNetServerClientGetAuth ( client ) ;
uid_t callerUid ;
pid_t callerPid ;
/* If the client is root then we want to bypass the
* policykit auth to avoid root being denied if
* some piece of polkit isn ' t present / running
*/
if ( auth = = VIR_NET_SERVER_SERVICE_AUTH_POLKIT ) {
if ( virNetServerClientGetLocalIdentity ( client , & callerUid , & callerPid ) < 0 ) {
/* Don't do anything on error - it'll be validated at next
* phase of auth anyway */
virResetLastError ( ) ;
} else if ( callerUid = = 0 ) {
char ident [ 100 ] ;
rv = snprintf ( ident , sizeof ident , " pid:%d,uid:%d " , callerPid , callerUid ) ;
if ( rv > 0 | | rv < sizeof ident ) {
VIR_INFO ( " Bypass polkit auth for privileged client %s " ,
ident ) ;
if ( virNetServerClientSetIdentity ( client , ident ) < 0 )
virResetLastError ( ) ;
else
auth = VIR_NET_SERVER_SERVICE_AUTH_NONE ;
}
rv = - 1 ;
}
}
2011-04-13 19:21:35 +04:00
2007-12-05 18:24:15 +03:00
ret - > types . types_len = 1 ;
2008-06-06 14:52:01 +04:00
if ( VIR_ALLOC_N ( ret - > types . types_val , ret - > types . types_len ) < 0 ) {
2011-04-13 19:21:35 +04:00
virReportOOMError ( ) ;
goto cleanup ;
2007-12-05 18:24:15 +03:00
}
2011-05-16 21:13:11 +04:00
switch ( auth ) {
case VIR_NET_SERVER_SERVICE_AUTH_NONE :
ret - > types . types_val [ 0 ] = REMOTE_AUTH_NONE ;
break ;
case VIR_NET_SERVER_SERVICE_AUTH_POLKIT :
ret - > types . types_val [ 0 ] = REMOTE_AUTH_POLKIT ;
break ;
case VIR_NET_SERVER_SERVICE_AUTH_SASL :
ret - > types . types_val [ 0 ] = REMOTE_AUTH_SASL ;
break ;
default :
ret - > types . types_val [ 0 ] = REMOTE_AUTH_NONE ;
}
2008-12-05 01:16:40 +03:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2007-12-05 18:24:15 +03:00
}
2011-06-30 21:18:08 +04:00
# ifdef HAVE_SASL
2007-12-05 18:24:15 +03:00
/*
* Initializes the SASL session in prepare for authentication
2008-05-15 10:12:32 +04:00
* and gives the client a list of allowed mechanisms to choose
2007-12-05 18:24:15 +03:00
*/
static int
2011-05-16 21:13:11 +04:00
remoteDispatchAuthSaslInit ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_auth_sasl_init_ret * ret )
2007-12-05 18:24:15 +03:00
{
2011-05-16 21:13:11 +04:00
virNetSASLSessionPtr sasl = NULL ;
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2007-12-05 18:24:15 +03:00
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
2008-12-05 01:16:40 +03:00
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Initialize SASL auth %d " , virNetServerClientGetFD ( client ) ) ;
if ( virNetServerClientGetAuth ( client ) ! = VIR_NET_SERVER_SERVICE_AUTH_SASL | |
priv - > sasl ! = NULL ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " client tried invalid SASL init request " ) ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
}
2011-05-16 21:13:11 +04:00
sasl = virNetSASLSessionNewServer ( saslCtxt ,
" libvirt " ,
virNetServerClientLocalAddrString ( client ) ,
virNetServerClientRemoteAddrString ( client ) ) ;
if ( ! sasl )
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
2007-12-05 18:27:08 +03:00
/* Inform SASL that we've got an external SSF layer from TLS */
2011-05-16 21:13:11 +04:00
if ( virNetServerClientHasTLSSession ( client ) ) {
int ssf ;
if ( ( ssf = virNetServerClientGetTLSKeySize ( client ) ) < 0 )
2008-12-05 01:16:40 +03:00
goto authfail ;
2011-05-16 21:13:11 +04:00
ssf * = 8 ; /* key size is bytes, sasl wants bits */
VIR_DEBUG ( " Setting external SSF %d " , ssf ) ;
if ( virNetSASLSessionExtKeySize ( sasl , ssf ) < 0 )
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:27:08 +03:00
}
2011-05-16 21:13:11 +04:00
if ( virNetServerClientIsSecure ( client ) )
2007-12-05 18:27:08 +03:00
/* If we've got TLS or UNIX domain sock, we don't care about SSF */
2011-05-16 21:13:11 +04:00
virNetSASLSessionSecProps ( sasl , 0 , 0 , true ) ;
else
2007-12-05 18:27:08 +03:00
/* Plain TCP, better get an SSF layer */
2011-05-16 21:13:11 +04:00
virNetSASLSessionSecProps ( sasl ,
56 , /* Good enough to require kerberos */
100000 , /* Arbitrary big number */
false ) ; /* No anonymous */
2007-12-05 18:27:08 +03:00
2011-05-16 21:13:11 +04:00
if ( ! ( ret - > mechlist = virNetSASLSessionListMechanisms ( sasl ) ) )
2008-12-05 01:16:40 +03:00
goto authfail ;
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Available mechanisms for client: '%s' " , ret - > mechlist ) ;
2007-12-05 18:24:15 +03:00
2011-05-16 21:13:11 +04:00
priv - > sasl = sasl ;
virMutexUnlock ( & priv - > lock ) ;
2007-12-05 18:24:15 +03:00
return 0 ;
2008-12-05 01:16:40 +03:00
authfail :
2011-05-16 21:13:11 +04:00
virResetLastError ( ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
PROBE ( CLIENT_AUTH_FAIL , " fd=%d, auth=%d " ,
virNetServerClientGetFD ( client ) , REMOTE_AUTH_SASL ) ;
virNetSASLSessionFree ( sasl ) ;
virMutexUnlock ( & priv - > lock ) ;
2008-12-05 01:16:40 +03:00
return - 1 ;
2007-12-05 18:24:15 +03:00
}
2011-05-16 21:13:11 +04:00
/*
2010-09-14 20:50:25 +04:00
* Returns 0 if ok , - 1 on error , - 2 if rejected
*/
2007-12-05 18:27:08 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteSASLFinish ( virNetServerClientPtr client )
{
const char * identity ;
struct daemonClientPrivate * priv = virNetServerClientGetPrivateData ( client ) ;
int ssf ;
/* TLS or UNIX domain sockets trivially OK */
if ( ! virNetServerClientIsSecure ( client ) ) {
if ( ( ssf = virNetSASLSessionGetKeySize ( priv - > sasl ) ) < 0 )
goto error ;
VIR_DEBUG ( " negotiated an SSF of %d " , ssf ) ;
if ( ssf < 56 ) { /* 56 is good for Kerberos */
VIR_ERROR ( _ ( " negotiated SSF %d was not strong enough " ) , ssf ) ;
return - 2 ;
}
2007-12-05 18:27:08 +03:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( identity = virNetSASLSessionGetIdentity ( priv - > sasl ) ) )
2010-09-14 20:50:25 +04:00
return - 2 ;
2007-12-05 18:27:08 +03:00
2011-05-16 21:13:11 +04:00
if ( ! virNetSASLContextCheckIdentity ( saslCtxt , identity ) )
return - 2 ;
2007-12-05 18:27:08 +03:00
2011-05-16 21:13:11 +04:00
if ( virNetServerClientSetIdentity ( client , identity ) < 0 )
goto error ;
2007-12-05 18:27:08 +03:00
2011-05-16 21:13:11 +04:00
virNetServerClientSetSASLSession ( client , priv - > sasl ) ;
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Authentication successful %d " , virNetServerClientGetFD ( client ) ) ;
2011-06-29 02:33:09 +04:00
identity = virNetSASLSessionGetIdentity ( priv - > sasl ) ;
2011-05-16 21:13:11 +04:00
PROBE ( CLIENT_AUTH_ALLOW , " fd=%d, auth=%d, username=%s " ,
2011-06-29 02:33:09 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_SASL , identity ) ;
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
virNetSASLSessionFree ( priv - > sasl ) ;
priv - > sasl = NULL ;
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
return 0 ;
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
error :
return - 1 ;
}
2007-12-05 18:34:05 +03:00
2007-12-05 18:24:15 +03:00
/*
* This starts the SASL authentication negotiation .
*/
static int
2011-05-16 21:13:11 +04:00
remoteDispatchAuthSaslStart ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_auth_sasl_start_args * args ,
remote_auth_sasl_start_ret * ret )
2007-12-05 18:24:15 +03:00
{
const char * serverout ;
2011-05-16 21:13:11 +04:00
size_t serveroutlen ;
2007-12-05 18:24:15 +03:00
int err ;
2011-05-16 21:13:11 +04:00
int rv = - 1 ;
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-06-29 02:33:09 +04:00
const char * identity ;
2007-12-05 18:24:15 +03:00
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
2008-12-05 01:16:40 +03:00
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Start SASL auth %d " , virNetServerClientGetFD ( client ) ) ;
if ( virNetServerClientGetAuth ( client ) ! = VIR_NET_SERVER_SERVICE_AUTH_SASL | |
priv - > sasl = = NULL ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " client tried invalid SASL start request " ) ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
}
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " Using SASL mechanism %s. Data %d bytes, nil: %d " ,
args - > mech , args - > data . data_len , args - > nil ) ;
2011-05-16 21:13:11 +04:00
err = virNetSASLSessionServerStart ( priv - > sasl ,
args - > mech ,
/* NB, distinction of NULL vs "" is *critical* in SASL */
args - > nil ? NULL : args - > data . data_val ,
args - > data . data_len ,
& serverout ,
& serveroutlen ) ;
if ( err ! = VIR_NET_SASL_COMPLETE & &
err ! = VIR_NET_SASL_CONTINUE )
2008-12-05 01:16:40 +03:00
goto authfail ;
2011-05-16 21:13:11 +04:00
2007-12-05 18:24:15 +03:00
if ( serveroutlen > REMOTE_AUTH_SASL_DATA_MAX ) {
2011-05-16 21:13:11 +04:00
VIR_ERROR ( _ ( " sasl start reply data too long %d " ) , ( int ) serveroutlen ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
}
/* NB, distinction of NULL vs "" is *critical* in SASL */
if ( serverout ) {
2011-05-16 21:13:11 +04:00
if ( VIR_ALLOC_N ( ret - > data . data_val , serveroutlen ) < 0 )
goto authfail ;
2007-12-05 18:24:15 +03:00
memcpy ( ret - > data . data_val , serverout , serveroutlen ) ;
} else {
ret - > data . data_val = NULL ;
}
ret - > nil = serverout ? 0 : 1 ;
ret - > data . data_len = serveroutlen ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " SASL return data %d bytes, nil; %d " , ret - > data . data_len , ret - > nil ) ;
2011-05-16 21:13:11 +04:00
if ( err = = VIR_NET_SASL_CONTINUE ) {
2007-12-05 18:24:15 +03:00
ret - > complete = 0 ;
} else {
2007-12-05 18:34:05 +03:00
/* Check username whitelist ACL */
2011-05-16 21:13:11 +04:00
if ( ( err = remoteSASLFinish ( client ) ) < 0 ) {
2010-09-14 20:50:25 +04:00
if ( err = = - 2 )
goto authdeny ;
else
goto authfail ;
}
2007-12-05 18:34:05 +03:00
2007-12-05 18:24:15 +03:00
ret - > complete = 1 ;
}
2011-05-16 21:13:11 +04:00
virMutexUnlock ( & priv - > lock ) ;
2007-12-05 18:24:15 +03:00
return 0 ;
2008-12-05 01:16:40 +03:00
authfail :
2011-05-16 21:13:11 +04:00
PROBE ( CLIENT_AUTH_FAIL , " fd=%d, auth=%d " ,
virNetServerClientGetFD ( client ) , REMOTE_AUTH_SASL ) ;
2010-09-14 20:50:25 +04:00
goto error ;
authdeny :
2011-06-29 02:33:09 +04:00
identity = virNetSASLSessionGetIdentity ( priv - > sasl ) ;
Add dtrace static probes in libvirtd
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
2010-09-14 20:30:32 +04:00
PROBE ( CLIENT_AUTH_DENY , " fd=%d, auth=%d, username=%s " ,
2011-06-29 02:33:09 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_SASL , identity ) ;
2010-09-14 20:50:25 +04:00
goto error ;
2008-12-05 01:16:40 +03:00
error :
2011-05-16 21:13:11 +04:00
virNetSASLSessionFree ( priv - > sasl ) ;
priv - > sasl = NULL ;
virResetLastError ( ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
if ( rv < 0 )
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2008-12-05 01:16:40 +03:00
return - 1 ;
2007-12-05 18:24:15 +03:00
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchAuthSaslStep ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_auth_sasl_step_args * args ,
remote_auth_sasl_step_ret * ret )
2007-12-05 18:24:15 +03:00
{
const char * serverout ;
2011-05-16 21:13:11 +04:00
size_t serveroutlen ;
2007-12-05 18:24:15 +03:00
int err ;
2011-05-16 21:13:11 +04:00
int rv = - 1 ;
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-06-29 02:33:09 +04:00
const char * identity ;
2008-12-05 01:16:40 +03:00
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
VIR_DEBUG ( " Step SASL auth %d " , virNetServerClientGetFD ( client ) ) ;
if ( virNetServerClientGetAuth ( client ) ! = VIR_NET_SERVER_SERVICE_AUTH_SASL | |
priv - > sasl = = NULL ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " client tried invalid SASL start request " ) ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
}
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Step using SASL Data %d bytes, nil: %d " ,
2011-04-13 19:10:01 +04:00
args - > data . data_len , args - > nil ) ;
2011-05-16 21:13:11 +04:00
err = virNetSASLSessionServerStep ( priv - > sasl ,
/* NB, distinction of NULL vs "" is *critical* in SASL */
args - > nil ? NULL : args - > data . data_val ,
args - > data . data_len ,
& serverout ,
& serveroutlen ) ;
if ( err ! = VIR_NET_SASL_COMPLETE & &
err ! = VIR_NET_SASL_CONTINUE )
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
if ( serveroutlen > REMOTE_AUTH_SASL_DATA_MAX ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " sasl step reply data too long %d " ) ,
2011-05-16 21:13:11 +04:00
( int ) serveroutlen ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 18:24:15 +03:00
}
/* NB, distinction of NULL vs "" is *critical* in SASL */
if ( serverout ) {
2011-05-16 21:13:11 +04:00
if ( VIR_ALLOC_N ( ret - > data . data_val , serveroutlen ) < 0 )
goto authfail ;
2007-12-05 18:24:15 +03:00
memcpy ( ret - > data . data_val , serverout , serveroutlen ) ;
} else {
ret - > data . data_val = NULL ;
}
ret - > nil = serverout ? 0 : 1 ;
ret - > data . data_len = serveroutlen ;
2011-04-13 19:10:01 +04:00
VIR_DEBUG ( " SASL return data %d bytes, nil; %d " , ret - > data . data_len , ret - > nil ) ;
2011-05-16 21:13:11 +04:00
if ( err = = VIR_NET_SASL_CONTINUE ) {
2007-12-05 18:24:15 +03:00
ret - > complete = 0 ;
} else {
2007-12-05 18:34:05 +03:00
/* Check username whitelist ACL */
2011-05-16 21:13:11 +04:00
if ( ( err = remoteSASLFinish ( client ) ) < 0 ) {
2010-09-14 20:50:25 +04:00
if ( err = = - 2 )
goto authdeny ;
else
goto authfail ;
}
2007-12-05 18:34:05 +03:00
2007-12-05 18:24:15 +03:00
ret - > complete = 1 ;
}
2011-05-16 21:13:11 +04:00
virMutexUnlock ( & priv - > lock ) ;
2007-12-05 18:24:15 +03:00
return 0 ;
2008-12-05 01:16:40 +03:00
authfail :
2011-05-16 21:13:11 +04:00
PROBE ( CLIENT_AUTH_FAIL , " fd=%d, auth=%d " ,
virNetServerClientGetFD ( client ) , REMOTE_AUTH_SASL ) ;
2010-09-14 20:50:25 +04:00
goto error ;
authdeny :
2011-06-29 02:33:09 +04:00
identity = virNetSASLSessionGetIdentity ( priv - > sasl ) ;
Add dtrace static probes in libvirtd
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
2010-09-14 20:30:32 +04:00
PROBE ( CLIENT_AUTH_DENY , " fd=%d, auth=%d, username=%s " ,
2011-06-29 02:33:09 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_SASL , identity ) ;
2010-09-14 20:50:25 +04:00
goto error ;
2008-12-05 01:16:40 +03:00
error :
2011-05-16 21:13:11 +04:00
virNetSASLSessionFree ( priv - > sasl ) ;
priv - > sasl = NULL ;
virResetLastError ( ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
if ( rv < 0 )
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2007-12-05 18:24:15 +03:00
return - 1 ;
}
2011-06-30 21:18:08 +04:00
# else
static int
remoteDispatchAuthSaslInit ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_auth_sasl_init_ret * ret ATTRIBUTE_UNUSED )
{
VIR_WARN ( " Client tried unsupported SASL auth " ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
return - 1 ;
}
static int
remoteDispatchAuthSaslStart ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_auth_sasl_start_args * args ATTRIBUTE_UNUSED ,
remote_auth_sasl_start_ret * ret ATTRIBUTE_UNUSED )
{
VIR_WARN ( " Client tried unsupported SASL auth " ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
return - 1 ;
}
static int
remoteDispatchAuthSaslStep ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_auth_sasl_step_args * args ATTRIBUTE_UNUSED ,
remote_auth_sasl_step_ret * ret ATTRIBUTE_UNUSED )
{
VIR_WARN ( " Client tried unsupported SASL auth " ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
return - 1 ;
}
# endif
2007-12-05 18:24:15 +03:00
2009-08-06 16:54:08 +04:00
# if HAVE_POLKIT1
static int
2011-05-16 21:13:11 +04:00
remoteDispatchAuthPolkit ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_auth_polkit_ret * ret )
2009-08-06 16:54:08 +04:00
{
2010-09-14 20:50:25 +04:00
pid_t callerPid = - 1 ;
uid_t callerUid = - 1 ;
2009-08-06 16:54:08 +04:00
const char * action ;
int status = - 1 ;
char pidbuf [ 50 ] ;
2010-09-14 20:50:25 +04:00
char ident [ 100 ] ;
2011-05-16 21:13:11 +04:00
int rv = - 1 ;
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2009-08-06 16:54:08 +04:00
2010-09-14 20:50:25 +04:00
memset ( ident , 0 , sizeof ident ) ;
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
action = virNetServerClientGetReadonly ( client ) ?
2009-08-06 16:54:08 +04:00
" org.libvirt.unix.monitor " :
" org.libvirt.unix.manage " ;
const char * const pkcheck [ ] = {
PKCHECK_PATH ,
" --action-id " , action ,
" --process " , pidbuf ,
" --allow-user-interaction " ,
NULL
} ;
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Start PolicyKit auth %d " , virNetServerClientGetFD ( client ) ) ;
if ( virNetServerClientGetAuth ( client ) ! = VIR_NET_SERVER_SERVICE_AUTH_POLKIT ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " client tried invalid PolicyKit init request " ) ) ;
2009-08-06 16:54:08 +04:00
goto authfail ;
}
2011-05-16 21:13:11 +04:00
if ( virNetServerClientGetLocalIdentity ( client , & callerUid , & callerPid ) < 0 ) {
2009-08-06 16:54:08 +04:00
goto authfail ;
}
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 19:08:44 +04:00
VIR_INFO ( " Checking PID %d running as %d " , callerPid , callerUid ) ;
2009-08-06 16:54:08 +04:00
rv = snprintf ( pidbuf , sizeof pidbuf , " %d " , callerPid ) ;
if ( rv < 0 | | rv > = sizeof pidbuf ) {
VIR_ERROR ( _ ( " Caller PID was too large %d " ) , callerPid ) ;
2009-08-25 20:18:27 +04:00
goto authfail ;
2009-08-06 16:54:08 +04:00
}
2010-09-14 20:50:25 +04:00
rv = snprintf ( ident , sizeof ident , " pid:%d,uid:%d " , callerPid , callerUid ) ;
if ( rv < 0 | | rv > = sizeof ident ) {
VIR_ERROR ( _ ( " Caller identity was too large %d:%d " ) , callerPid , callerUid ) ;
goto authfail ;
}
2010-02-05 01:41:52 +03:00
if ( virRun ( pkcheck , & status ) < 0 ) {
2009-08-06 16:54:08 +04:00
VIR_ERROR ( _ ( " Cannot invoke %s " ) , PKCHECK_PATH ) ;
2009-08-25 20:18:27 +04:00
goto authfail ;
2009-08-06 16:54:08 +04:00
}
if ( status ! = 0 ) {
2011-03-22 20:55:45 +03:00
char * tmp = virCommandTranslateStatus ( status ) ;
VIR_ERROR ( _ ( " Policy kit denied action %s from pid %d, uid %d: %s " ) ,
action , callerPid , callerUid , NULLSTR ( tmp ) ) ;
VIR_FREE ( tmp ) ;
2010-09-14 20:50:25 +04:00
goto authdeny ;
2009-08-06 16:54:08 +04:00
}
Add dtrace static probes in libvirtd
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
2010-09-14 20:30:32 +04:00
PROBE ( CLIENT_AUTH_ALLOW , " fd=%d, auth=%d, username=%s " ,
2011-05-16 21:13:11 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_POLKIT , ident ) ;
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 19:08:44 +04:00
VIR_INFO ( " Policy allowed action %s from pid %d, uid %d " ,
2009-08-06 16:54:08 +04:00
action , callerPid , callerUid ) ;
ret - > complete = 1 ;
2011-05-16 21:13:11 +04:00
virNetServerClientSetIdentity ( client , ident ) ;
virMutexUnlock ( & priv - > lock ) ;
2009-08-06 16:54:08 +04:00
return 0 ;
2011-05-16 21:13:11 +04:00
error :
virResetLastError ( ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
return - 1 ;
2009-08-06 16:54:08 +04:00
authfail :
2011-05-16 21:13:11 +04:00
PROBE ( CLIENT_AUTH_FAIL , " fd=%d, auth=%d " ,
virNetServerClientGetFD ( client ) , REMOTE_AUTH_POLKIT ) ;
2010-09-14 20:50:25 +04:00
goto error ;
authdeny :
Add dtrace static probes in libvirtd
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
2010-09-14 20:30:32 +04:00
PROBE ( CLIENT_AUTH_DENY , " fd=%d, auth=%d, username=%s " ,
2011-05-16 21:13:11 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_POLKIT , ( char * ) ident ) ;
2010-09-14 20:50:25 +04:00
goto error ;
2009-08-06 16:54:08 +04:00
}
# elif HAVE_POLKIT0
2007-12-05 21:21:27 +03:00
static int
2011-07-08 01:12:26 +04:00
remoteDispatchAuthPolkit ( virNetServerPtr server ,
2011-05-16 21:13:11 +04:00
virNetServerClientPtr client ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
remote_auth_polkit_ret * ret )
2007-12-05 21:21:27 +03:00
{
pid_t callerPid ;
uid_t callerUid ;
2008-04-04 19:09:19 +04:00
PolKitCaller * pkcaller = NULL ;
PolKitAction * pkaction = NULL ;
PolKitContext * pkcontext = NULL ;
PolKitError * pkerr = NULL ;
PolKitResult pkresult ;
DBusError err ;
2008-12-05 01:16:40 +03:00
const char * action ;
2010-09-14 20:50:25 +04:00
char ident [ 100 ] ;
2011-05-16 21:13:11 +04:00
int rv = - 1 ;
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2010-09-14 20:50:25 +04:00
memset ( ident , 0 , sizeof ident ) ;
2008-12-05 01:16:40 +03:00
2011-07-08 01:12:26 +04:00
virMutexLock ( & priv - > lock ) ;
2008-12-05 01:16:40 +03:00
2011-07-08 01:12:26 +04:00
action = virNetServerClientGetReadonly ( client ) ?
2008-04-04 19:09:19 +04:00
" org.libvirt.unix.monitor " :
" org.libvirt.unix.manage " ;
2007-12-05 21:21:27 +03:00
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Start PolicyKit auth %d " , virNetServerClientGetFD ( client ) ) ;
2011-07-08 01:12:26 +04:00
if ( virNetServerClientGetAuth ( client ) ! = VIR_NET_SERVER_SERVICE_AUTH_POLKIT ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " client tried invalid PolicyKit init request " ) ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 21:21:27 +03:00
}
2011-07-08 01:12:26 +04:00
if ( virNetServerClientGetLocalIdentity ( client , & callerUid , & callerPid ) < 0 ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " cannot get peer socket identity " ) ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2007-12-05 21:21:27 +03:00
}
2010-09-14 20:50:25 +04:00
rv = snprintf ( ident , sizeof ident , " pid:%d,uid:%d " , callerPid , callerUid ) ;
if ( rv < 0 | | rv > = sizeof ident ) {
VIR_ERROR ( _ ( " Caller identity was too large %d:%d " ) , callerPid , callerUid ) ;
goto authfail ;
}
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 19:08:44 +04:00
VIR_INFO ( " Checking PID %d running as %d " , callerPid , callerUid ) ;
2008-04-04 19:09:19 +04:00
dbus_error_init ( & err ) ;
2011-07-08 01:12:26 +04:00
if ( ! ( pkcaller = polkit_caller_new_from_pid ( virNetServerGetDBusConn ( server ) ,
2008-04-04 19:09:19 +04:00
callerPid , & err ) ) ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " Failed to lookup policy kit caller: %s " ) , err . message ) ;
2008-04-04 19:09:19 +04:00
dbus_error_free ( & err ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2008-04-04 19:09:19 +04:00
}
2007-12-05 21:21:27 +03:00
2008-04-04 19:09:19 +04:00
if ( ! ( pkaction = polkit_action_new ( ) ) ) {
2009-02-05 19:28:30 +03:00
char ebuf [ 1024 ] ;
2010-01-19 16:17:20 +03:00
VIR_ERROR ( _ ( " Failed to create polkit action %s " ) ,
2009-02-05 19:28:30 +03:00
virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2008-04-04 19:09:19 +04:00
polkit_caller_unref ( pkcaller ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2008-04-04 19:09:19 +04:00
}
polkit_action_set_action_id ( pkaction , action ) ;
if ( ! ( pkcontext = polkit_context_new ( ) ) | |
! polkit_context_init ( pkcontext , & pkerr ) ) {
2009-02-05 19:28:30 +03:00
char ebuf [ 1024 ] ;
2010-01-19 16:17:20 +03:00
VIR_ERROR ( _ ( " Failed to create polkit context %s " ) ,
2009-01-06 21:32:03 +03:00
( pkerr ? polkit_error_get_error_message ( pkerr )
2009-02-05 19:28:30 +03:00
: virStrerror ( errno , ebuf , sizeof ebuf ) ) ) ;
2008-04-04 19:09:19 +04:00
if ( pkerr )
polkit_error_free ( pkerr ) ;
polkit_caller_unref ( pkcaller ) ;
polkit_action_unref ( pkaction ) ;
dbus_error_free ( & err ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2008-04-04 19:09:19 +04:00
}
2007-12-05 21:21:27 +03:00
2010-03-09 21:22:22 +03:00
# if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
2008-04-04 19:09:19 +04:00
pkresult = polkit_context_is_caller_authorized ( pkcontext ,
pkaction ,
pkcaller ,
0 ,
& pkerr ) ;
if ( pkerr & & polkit_error_is_set ( pkerr ) ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " Policy kit failed to check authorization %d %s " ) ,
polkit_error_get_error_code ( pkerr ) ,
polkit_error_get_error_message ( pkerr ) ) ;
2008-12-05 01:16:40 +03:00
goto authfail ;
2008-04-04 19:09:19 +04:00
}
2010-03-09 21:22:22 +03:00
# else
2008-04-04 19:09:19 +04:00
pkresult = polkit_context_can_caller_do_action ( pkcontext ,
pkaction ,
pkcaller ) ;
2010-03-09 21:22:22 +03:00
# endif
2008-04-04 19:09:19 +04:00
polkit_context_unref ( pkcontext ) ;
polkit_caller_unref ( pkcaller ) ;
polkit_action_unref ( pkaction ) ;
if ( pkresult ! = POLKIT_RESULT_YES ) {
2010-01-19 16:17:20 +03:00
VIR_ERROR ( _ ( " Policy kit denied action %s from pid %d, uid %d, result: %s " ) ,
2009-01-06 21:32:03 +03:00
action , callerPid , callerUid ,
polkit_result_to_string_representation ( pkresult ) ) ;
2010-09-14 20:50:25 +04:00
goto authdeny ;
2007-12-05 21:21:27 +03:00
}
Add dtrace static probes in libvirtd
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
2010-09-14 20:30:32 +04:00
PROBE ( CLIENT_AUTH_ALLOW , " fd=%d, auth=%d, username=%s " ,
2011-05-16 21:13:11 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_POLKIT , ident ) ;
maint: omit translation for all VIR_INFO
We were 31/73 on whether to translate; since less than 50% translated
and since VIR_INFO is less than VIR_WARN which also doesn't translate,
this makes sense.
* cfg.mk (sc_prohibit_gettext_markup): Add VIR_INFO, since it
falls between WARN and DEBUG.
* daemon/libvirtd.c (qemudDispatchSignalEvent, remoteCheckAccess)
(qemudDispatchServer): Adjust offenders.
* daemon/remote.c (remoteDispatchAuthPolkit): Likewise.
* src/network/bridge_driver.c (networkReloadIptablesRules)
(networkStartNetworkDaemon, networkShutdownNetworkDaemon)
(networkCreate, networkDefine, networkUndefine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainDefine)
(qemudDomainUndefine): Likewise.
* src/storage/storage_driver.c (storagePoolCreate)
(storagePoolDefine, storagePoolUndefine, storagePoolStart)
(storagePoolDestroy, storagePoolDelete, storageVolumeCreateXML)
(storageVolumeCreateXMLFrom, storageVolumeDelete): Likewise.
* src/util/bridge.c (brProbeVnetHdr): Likewise.
* po/POTFILES.in: Drop src/util/bridge.c.
2011-05-11 19:08:44 +04:00
VIR_INFO ( " Policy allowed action %s from pid %d, uid %d, result %s " ,
2011-04-22 19:09:33 +04:00
action , callerPid , callerUid ,
polkit_result_to_string_representation ( pkresult ) ) ;
ret - > complete = 1 ;
2011-07-08 01:12:26 +04:00
virNetServerClientSetIdentity ( client , ident ) ;
2011-04-12 20:33:49 +04:00
2011-07-08 01:12:26 +04:00
virMutexUnlock ( & priv - > lock ) ;
2011-04-22 19:09:33 +04:00
return 0 ;
2008-02-20 18:22:35 +03:00
2011-05-16 21:13:11 +04:00
error :
virResetLastError ( ) ;
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
2011-07-08 01:12:26 +04:00
virMutexUnlock ( & priv - > lock ) ;
2011-05-16 21:13:11 +04:00
return - 1 ;
2011-04-22 19:09:33 +04:00
authfail :
2011-05-16 21:13:11 +04:00
PROBE ( CLIENT_AUTH_FAIL , " fd=%d, auth=%d " ,
virNetServerClientGetFD ( client ) , REMOTE_AUTH_POLKIT ) ;
2011-04-22 19:09:33 +04:00
goto error ;
2011-04-13 19:21:35 +04:00
2011-04-22 19:09:33 +04:00
authdeny :
PROBE ( CLIENT_AUTH_DENY , " fd=%d, auth=%d, username=%s " ,
2011-05-16 21:13:11 +04:00
virNetServerClientGetFD ( client ) , REMOTE_AUTH_POLKIT , ident ) ;
2011-04-22 19:09:33 +04:00
goto error ;
2008-02-20 18:22:35 +03:00
}
2011-04-22 19:09:33 +04:00
# else /* !HAVE_POLKIT0 & !HAVE_POLKIT1*/
2008-02-20 18:22:35 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchAuthPolkit ( virNetServerPtr server ATTRIBUTE_UNUSED ,
2011-06-28 23:09:05 +04:00
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
2011-05-16 21:13:11 +04:00
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_auth_polkit_ret * ret ATTRIBUTE_UNUSED )
2008-02-20 18:22:35 +03:00
{
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " client tried unsupported PolicyKit init request " ) ) ;
2011-05-16 21:13:11 +04:00
virNetError ( VIR_ERR_AUTH_FAILED , " %s " ,
_ ( " authentication failed " ) ) ;
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
return - 1 ;
}
# endif /* HAVE_POLKIT1 */
2011-04-13 19:21:35 +04:00
2011-04-22 19:09:33 +04:00
/***************************************************************
* NODE INFO APIS
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-11-21 15:31:04 +03:00
2009-07-28 06:01:00 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchNodeDeviceGetParent ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_node_device_get_parent_args * args ,
remote_node_device_get_parent_ret * ret )
2009-07-28 06:01:00 +04:00
{
2011-04-22 19:09:33 +04:00
virNodeDevicePtr dev = NULL ;
const char * parent = NULL ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2009-07-28 06:01:00 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dev = virNodeDeviceLookupByName ( priv - > conn , args - > name ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
parent = virNodeDeviceGetParent ( dev ) ;
if ( parent = = NULL ) {
ret - > parent = NULL ;
} else {
/* remoteDispatchClientRequest will free this. */
char * * parent_p ;
if ( VIR_ALLOC ( parent_p ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
if ( ! ( * parent_p = strdup ( parent ) ) ) {
VIR_FREE ( parent_p ) ;
virReportOOMError ( ) ;
goto cleanup ;
}
ret - > parent = parent_p ;
}
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
if ( dev )
virNodeDeviceFree ( dev ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2009-07-28 06:01:00 +04:00
}
2011-04-22 19:09:33 +04:00
/***************************
* Register / deregister events
* * * * * * * * * * * * * * * * * * * * * * * * * * */
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventsRegister ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED ,
2011-04-22 19:09:33 +04:00
remote_domain_events_register_ret * ret ATTRIBUTE_UNUSED )
2010-11-15 06:23:34 +03:00
{
2011-04-22 19:09:33 +04:00
int callbackID ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2010-11-15 06:23:34 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
if ( priv - > domainEventCallbackID [ VIR_DOMAIN_EVENT_ID_LIFECYCLE ] ! = - 1 ) {
2011-04-22 19:09:33 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " domain event %d already registered " ) , VIR_DOMAIN_EVENT_ID_LIFECYCLE ) ;
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
}
2010-11-15 06:23:34 +03:00
2011-05-16 21:13:11 +04:00
if ( ( callbackID = virConnectDomainEventRegisterAny ( priv - > conn ,
2011-04-22 19:09:33 +04:00
NULL ,
VIR_DOMAIN_EVENT_ID_LIFECYCLE ,
VIR_DOMAIN_EVENT_CALLBACK ( remoteRelayDomainEventLifecycle ) ,
client , NULL ) ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2010-11-15 06:23:34 +03:00
2011-05-16 21:13:11 +04:00
priv - > domainEventCallbackID [ VIR_DOMAIN_EVENT_ID_LIFECYCLE ] = callbackID ;
2011-04-22 19:09:33 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2010-11-15 06:23:34 +03:00
}
2011-04-22 19:09:33 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventsDeregister ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED ,
2011-04-22 19:09:33 +04:00
remote_domain_events_deregister_ret * ret ATTRIBUTE_UNUSED )
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
{
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
if ( priv - > domainEventCallbackID [ VIR_DOMAIN_EVENT_ID_LIFECYCLE ] < 0 ) {
2011-04-22 19:09:33 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " domain event %d not registered " ) , VIR_DOMAIN_EVENT_ID_LIFECYCLE ) ;
2011-04-13 19:21:35 +04:00
goto cleanup ;
2011-04-22 19:09:33 +04:00
}
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
2011-05-16 21:13:11 +04:00
if ( virConnectDomainEventDeregisterAny ( priv - > conn ,
priv - > domainEventCallbackID [ VIR_DOMAIN_EVENT_ID_LIFECYCLE ] ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
2011-05-16 21:13:11 +04:00
priv - > domainEventCallbackID [ VIR_DOMAIN_EVENT_ID_LIFECYCLE ] = - 1 ;
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
2011-04-22 19:09:33 +04:00
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2011-04-22 19:09:33 +04:00
return rv ;
}
static void
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventSend ( virNetServerClientPtr client ,
virNetServerProgramPtr program ,
2011-04-22 19:09:33 +04:00
int procnr ,
xdrproc_t proc ,
void * data )
{
2011-05-16 21:13:11 +04:00
virNetMessagePtr msg ;
2011-04-22 19:09:33 +04:00
2011-05-16 21:13:11 +04:00
if ( ! ( msg = virNetMessageNew ( ) ) )
2011-04-22 19:09:33 +04:00
return ;
2011-05-16 21:13:11 +04:00
msg - > header . prog = virNetServerProgramGetID ( program ) ;
msg - > header . vers = virNetServerProgramGetVersion ( program ) ;
msg - > header . proc = procnr ;
msg - > header . type = VIR_NET_MESSAGE ;
msg - > header . serial = 1 ;
msg - > header . status = VIR_NET_OK ;
2011-04-22 19:09:33 +04:00
2011-05-16 21:13:11 +04:00
if ( virNetMessageEncodeHeader ( msg ) < 0 )
2011-04-22 19:09:33 +04:00
goto cleanup ;
2011-05-16 21:13:11 +04:00
if ( virNetMessageEncodePayload ( msg , proc , data ) < 0 )
goto cleanup ;
2011-04-22 19:09:33 +04:00
2011-05-16 21:13:11 +04:00
VIR_DEBUG ( " Queue event %d %zu " , procnr , msg - > bufferLength ) ;
virNetServerClientSendMessage ( client , msg ) ;
2011-04-22 19:09:33 +04:00
return ;
cleanup :
2011-05-16 21:13:11 +04:00
virNetMessageFree ( msg ) ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
}
2011-04-22 19:09:33 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchSecretGetValue ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-22 19:09:33 +04:00
remote_secret_get_value_args * args ,
remote_secret_get_value_ret * ret )
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
{
2011-04-22 19:09:33 +04:00
virSecretPtr secret = NULL ;
size_t value_size ;
unsigned char * value ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( secret = get_nonnull_secret ( priv - > conn , args - > secret ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
2011-04-22 19:09:33 +04:00
if ( ! ( value = virSecretGetValue ( secret , & value_size , args - > flags ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
2011-04-22 19:09:33 +04:00
ret - > value . value_len = value_size ;
ret - > value . value_val = ( char * ) value ;
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-22 19:09:33 +04:00
if ( secret )
virSecretFree ( secret ) ;
2011-04-13 19:21:35 +04:00
return rv ;
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 18:12:03 +04:00
}
2011-04-26 18:47:22 +04:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainGetState ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-26 18:47:22 +04:00
remote_domain_get_state_args * args ,
remote_domain_get_state_ret * ret )
{
virDomainPtr dom = NULL ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-04-26 18:47:22 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-26 18:47:22 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-26 18:47:22 +04:00
goto cleanup ;
if ( virDomainGetState ( dom , & ret - > state , & ret - > reason , args - > flags ) < 0 )
goto cleanup ;
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-26 18:47:22 +04:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
}
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventsRegisterAny ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED ,
remote_domain_events_register_any_args * args )
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
{
int callbackID ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
if ( args - > eventID > = VIR_DOMAIN_EVENT_ID_LAST | |
args - > eventID < 0 ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " unsupported event ID %d " ) , args - > eventID ) ;
goto cleanup ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
}
2011-05-16 21:13:11 +04:00
if ( priv - > domainEventCallbackID [ args - > eventID ] ! = - 1 ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " domain event %d already registered " ) , args - > eventID ) ;
goto cleanup ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
}
2011-05-16 21:13:11 +04:00
if ( ( callbackID = virConnectDomainEventRegisterAny ( priv - > conn ,
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
NULL ,
args - > eventID ,
domainEventCallbacks [ args - > eventID ] ,
2011-04-13 21:23:00 +04:00
client , NULL ) ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
2011-05-16 21:13:11 +04:00
priv - > domainEventCallbackID [ args - > eventID ] = callbackID ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2011-04-13 19:21:35 +04:00
return rv ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainEventsDeregisterAny ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED ,
remote_domain_events_deregister_any_args * args )
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
{
int callbackID = - 1 ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
virMutexLock ( & priv - > lock ) ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
if ( args - > eventID > = VIR_DOMAIN_EVENT_ID_LAST | |
args - > eventID < 0 ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " unsupported event ID %d " ) , args - > eventID ) ;
goto cleanup ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
}
2011-05-16 21:13:11 +04:00
callbackID = priv - > domainEventCallbackID [ args - > eventID ] ;
if ( callbackID < 0 ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , _ ( " domain event %d not registered " ) , args - > eventID ) ;
goto cleanup ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
}
2011-05-16 21:13:11 +04:00
if ( virConnectDomainEventDeregisterAny ( priv - > conn , callbackID ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
2011-05-16 21:13:11 +04:00
priv - > domainEventCallbackID [ args - > eventID ] = - 1 ;
2011-04-13 19:21:35 +04:00
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
virMutexUnlock ( & priv - > lock ) ;
2011-04-13 19:21:35 +04:00
return rv ;
Remote driver & daemon impl of new event API
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
2010-03-18 17:56:56 +03:00
}
2010-04-17 06:09:25 +04:00
static int
2011-05-16 21:13:11 +04:00
qemuDispatchMonitorCommand ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-04-12 20:34:30 +04:00
qemu_monitor_command_args * args ,
qemu_monitor_command_ret * ret )
2010-04-17 06:09:25 +04:00
{
2011-04-13 22:10:03 +04:00
virDomainPtr dom = NULL ;
2011-04-13 19:21:35 +04:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2010-04-17 06:09:25 +04:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-04-13 19:21:35 +04:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
2011-04-12 20:33:49 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2010-04-17 06:09:25 +04:00
2011-04-13 22:10:03 +04:00
if ( virDomainQemuMonitorCommand ( dom , args - > cmd , & ret - > result ,
2011-04-13 21:23:00 +04:00
args - > flags ) < 0 )
2011-04-13 19:21:35 +04:00
goto cleanup ;
2010-04-17 06:09:25 +04:00
2011-04-13 19:21:35 +04:00
rv = 0 ;
2010-04-17 06:09:25 +04:00
2011-04-13 19:21:35 +04:00
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-04-13 22:10:03 +04:00
if ( dom )
virDomainFree ( dom ) ;
2011-04-13 19:21:35 +04:00
return rv ;
2010-04-17 06:09:25 +04:00
}
2010-04-27 23:29:15 +04:00
2011-02-01 17:23:40 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigrateBegin3 ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-02-01 17:23:40 +03:00
remote_domain_migrate_begin3_args * args ,
remote_domain_migrate_begin3_ret * ret )
{
char * xml = NULL ;
virDomainPtr dom = NULL ;
char * dname ;
2011-05-18 13:26:30 +04:00
char * xmlin ;
2011-02-01 17:23:40 +03:00
char * cookieout = NULL ;
int cookieoutlen = 0 ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-02-01 17:23:40 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-02-01 17:23:40 +03:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-02-01 17:23:40 +03:00
goto cleanup ;
2011-05-18 13:26:30 +04:00
xmlin = args - > xmlin = = NULL ? NULL : * args - > xmlin ;
2011-02-01 17:23:40 +03:00
dname = args - > dname = = NULL ? NULL : * args - > dname ;
2011-05-18 13:26:30 +04:00
if ( ! ( xml = virDomainMigrateBegin3 ( dom , xmlin ,
2011-02-01 17:23:40 +03:00
& cookieout , & cookieoutlen ,
args - > flags , dname , args - > resource ) ) )
goto cleanup ;
/* remoteDispatchClientRequest will free cookie and
* the xml string if there is one .
*/
ret - > cookie_out . cookie_out_len = cookieoutlen ;
ret - > cookie_out . cookie_out_val = cookieout ;
ret - > xml = xml ;
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-02-01 17:23:40 +03:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigratePrepare3 ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-02-01 17:23:40 +03:00
remote_domain_migrate_prepare3_args * args ,
remote_domain_migrate_prepare3_ret * ret )
{
char * cookieout = NULL ;
int cookieoutlen = 0 ;
char * uri_in ;
char * * uri_out ;
char * dname ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-02-01 17:23:40 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-02-01 17:23:40 +03:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
uri_in = args - > uri_in = = NULL ? NULL : * args - > uri_in ;
dname = args - > dname = = NULL ? NULL : * args - > dname ;
/* Wacky world of XDR ... */
if ( VIR_ALLOC ( uri_out ) < 0 ) {
virReportOOMError ( ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( virDomainMigratePrepare3 ( priv - > conn ,
2011-02-01 17:23:40 +03:00
args - > cookie_in . cookie_in_val ,
args - > cookie_in . cookie_in_len ,
& cookieout , & cookieoutlen ,
uri_in , uri_out ,
args - > flags , dname , args - > resource ,
args - > dom_xml ) < 0 )
goto cleanup ;
/* remoteDispatchClientRequest will free cookie, uri_out and
* the string if there is one .
*/
ret - > cookie_out . cookie_out_len = cookieoutlen ;
ret - > cookie_out . cookie_out_val = cookieout ;
ret - > uri_out = * uri_out = = NULL ? NULL : uri_out ;
rv = 0 ;
cleanup :
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-02-01 17:23:40 +03:00
VIR_FREE ( uri_out ) ;
}
return rv ;
}
2011-05-16 21:13:11 +04:00
2011-02-01 17:23:40 +03:00
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigratePerform3 ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-02-01 17:23:40 +03:00
remote_domain_migrate_perform3_args * args ,
remote_domain_migrate_perform3_ret * ret )
{
virDomainPtr dom = NULL ;
2011-05-18 13:26:30 +04:00
char * xmlin ;
2011-02-01 17:23:40 +03:00
char * dname ;
Add a second URI parameter to virDomainMigratePerform3 method
The virDomainMigratePerform3 currently has a single URI parameter
whose meaning varies. It is either
- A QEMU migration URI (normal migration)
- A libvirtd connection URI (peer2peer migration)
Unfortunately when using peer2peer migration, without also
using tunnelled migration, it is possible that both URIs are
required.
This adds a second URI parameter to the virDomainMigratePerform3
method, to cope with this scenario. Each parameter how has a fixed
meaning.
NB, there is no way to actually take advantage of this yet,
since virDomainMigrate/virDomainMigrateToURI do not have any
way to provide the 2 separate URIs
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs: Add
the second URI parameter to perform3 message
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add
the second URI parameter to Perform3 method
* src/libvirt_internal.h, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Update to handle URIs correctly
2011-05-18 17:18:53 +04:00
char * uri ;
char * dconnuri ;
2011-02-01 17:23:40 +03:00
char * cookieout = NULL ;
int cookieoutlen = 0 ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-02-01 17:23:40 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-02-01 17:23:40 +03:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-02-01 17:23:40 +03:00
goto cleanup ;
2011-05-18 13:26:30 +04:00
xmlin = args - > xmlin = = NULL ? NULL : * args - > xmlin ;
2011-02-01 17:23:40 +03:00
dname = args - > dname = = NULL ? NULL : * args - > dname ;
Add a second URI parameter to virDomainMigratePerform3 method
The virDomainMigratePerform3 currently has a single URI parameter
whose meaning varies. It is either
- A QEMU migration URI (normal migration)
- A libvirtd connection URI (peer2peer migration)
Unfortunately when using peer2peer migration, without also
using tunnelled migration, it is possible that both URIs are
required.
This adds a second URI parameter to the virDomainMigratePerform3
method, to cope with this scenario. Each parameter how has a fixed
meaning.
NB, there is no way to actually take advantage of this yet,
since virDomainMigrate/virDomainMigrateToURI do not have any
way to provide the 2 separate URIs
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs: Add
the second URI parameter to perform3 message
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add
the second URI parameter to Perform3 method
* src/libvirt_internal.h, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Update to handle URIs correctly
2011-05-18 17:18:53 +04:00
uri = args - > uri = = NULL ? NULL : * args - > uri ;
dconnuri = args - > dconnuri = = NULL ? NULL : * args - > dconnuri ;
2011-02-01 17:23:40 +03:00
2011-05-18 13:26:30 +04:00
if ( virDomainMigratePerform3 ( dom , xmlin ,
2011-02-01 17:23:40 +03:00
args - > cookie_in . cookie_in_val ,
args - > cookie_in . cookie_in_len ,
& cookieout , & cookieoutlen ,
Add a second URI parameter to virDomainMigratePerform3 method
The virDomainMigratePerform3 currently has a single URI parameter
whose meaning varies. It is either
- A QEMU migration URI (normal migration)
- A libvirtd connection URI (peer2peer migration)
Unfortunately when using peer2peer migration, without also
using tunnelled migration, it is possible that both URIs are
required.
This adds a second URI parameter to the virDomainMigratePerform3
method, to cope with this scenario. Each parameter how has a fixed
meaning.
NB, there is no way to actually take advantage of this yet,
since virDomainMigrate/virDomainMigrateToURI do not have any
way to provide the 2 separate URIs
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs: Add
the second URI parameter to perform3 message
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add
the second URI parameter to Perform3 method
* src/libvirt_internal.h, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Update to handle URIs correctly
2011-05-18 17:18:53 +04:00
dconnuri , uri ,
2011-02-01 17:23:40 +03:00
args - > flags , dname , args - > resource ) < 0 )
goto cleanup ;
/* remoteDispatchClientRequest will free cookie
*/
ret - > cookie_out . cookie_out_len = cookieoutlen ;
ret - > cookie_out . cookie_out_val = cookieout ;
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-02-01 17:23:40 +03:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigrateFinish3 ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
2011-02-01 17:23:40 +03:00
remote_domain_migrate_finish3_args * args ,
remote_domain_migrate_finish3_ret * ret )
{
virDomainPtr dom = NULL ;
char * cookieout = NULL ;
int cookieoutlen = 0 ;
Add a second URI parameter to virDomainMigratePerform3 method
The virDomainMigratePerform3 currently has a single URI parameter
whose meaning varies. It is either
- A QEMU migration URI (normal migration)
- A libvirtd connection URI (peer2peer migration)
Unfortunately when using peer2peer migration, without also
using tunnelled migration, it is possible that both URIs are
required.
This adds a second URI parameter to the virDomainMigratePerform3
method, to cope with this scenario. Each parameter how has a fixed
meaning.
NB, there is no way to actually take advantage of this yet,
since virDomainMigrate/virDomainMigrateToURI do not have any
way to provide the 2 separate URIs
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs: Add
the second URI parameter to perform3 message
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add
the second URI parameter to Perform3 method
* src/libvirt_internal.h, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Update to handle URIs correctly
2011-05-18 17:18:53 +04:00
char * uri ;
char * dconnuri ;
2011-02-01 17:23:40 +03:00
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-02-01 17:23:40 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-02-01 17:23:40 +03:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
Add a second URI parameter to virDomainMigratePerform3 method
The virDomainMigratePerform3 currently has a single URI parameter
whose meaning varies. It is either
- A QEMU migration URI (normal migration)
- A libvirtd connection URI (peer2peer migration)
Unfortunately when using peer2peer migration, without also
using tunnelled migration, it is possible that both URIs are
required.
This adds a second URI parameter to the virDomainMigratePerform3
method, to cope with this scenario. Each parameter how has a fixed
meaning.
NB, there is no way to actually take advantage of this yet,
since virDomainMigrate/virDomainMigrateToURI do not have any
way to provide the 2 separate URIs
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs: Add
the second URI parameter to perform3 message
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add
the second URI parameter to Perform3 method
* src/libvirt_internal.h, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Update to handle URIs correctly
2011-05-18 17:18:53 +04:00
uri = args - > uri = = NULL ? NULL : * args - > uri ;
dconnuri = args - > dconnuri = = NULL ? NULL : * args - > dconnuri ;
2011-05-16 21:13:11 +04:00
if ( ! ( dom = virDomainMigrateFinish3 ( priv - > conn , args - > dname ,
Fix the signature of virDomainMigrateFinish3 for error reporting
The current virDomainMigrateFinish3 method signature attempts to
distinguish two types of errors, by allowing return with ret== 0,
but ddomain == NULL, to indicate a failure to start the guest.
This is flawed, because when ret == 0, there is no way for the
virErrorPtr details to be sent back to the client.
Change the signature of virDomainMigrateFinish3 so it simply
returns a virDomainPtr, in the same way as virDomainMigrateFinish2
The disk locking code will protect against the only possible
failure mode this doesn't account for (loosing conenctivity to
libvirtd after Finish3 starts the CPUs, but before the client
sees the reply for Finish3).
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Change
virDomainMigrateFinish3 to return a virDomainPtr instead of int
* src/remote/remote_driver.c, src/remote/remote_protocol.x,
daemon/remote.c, src/qemu/qemu_driver.c, src/qemu/qemu_migration.c:
Update for API change
2011-05-24 16:05:33 +04:00
args - > cookie_in . cookie_in_val ,
args - > cookie_in . cookie_in_len ,
& cookieout , & cookieoutlen ,
dconnuri , uri ,
args - > flags ,
args - > cancelled ) ) )
2011-02-01 17:23:40 +03:00
goto cleanup ;
Fix the signature of virDomainMigrateFinish3 for error reporting
The current virDomainMigrateFinish3 method signature attempts to
distinguish two types of errors, by allowing return with ret== 0,
but ddomain == NULL, to indicate a failure to start the guest.
This is flawed, because when ret == 0, there is no way for the
virErrorPtr details to be sent back to the client.
Change the signature of virDomainMigrateFinish3 so it simply
returns a virDomainPtr, in the same way as virDomainMigrateFinish2
The disk locking code will protect against the only possible
failure mode this doesn't account for (loosing conenctivity to
libvirtd after Finish3 starts the CPUs, but before the client
sees the reply for Finish3).
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Change
virDomainMigrateFinish3 to return a virDomainPtr instead of int
* src/remote/remote_driver.c, src/remote/remote_protocol.x,
daemon/remote.c, src/qemu/qemu_driver.c, src/qemu/qemu_migration.c:
Update for API change
2011-05-24 16:05:33 +04:00
make_nonnull_domain ( & ret - > dom , dom ) ;
2011-02-01 17:23:40 +03:00
/* remoteDispatchClientRequest will free cookie
*/
ret - > cookie_out . cookie_out_len = cookieoutlen ;
ret - > cookie_out . cookie_out_val = cookieout ;
rv = 0 ;
cleanup :
if ( rv < 0 ) {
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-02-01 17:23:40 +03:00
VIR_FREE ( cookieout ) ;
}
if ( dom )
virDomainFree ( dom ) ;
return rv ;
}
static int
2011-05-16 21:13:11 +04:00
remoteDispatchDomainMigrateConfirm3 ( virNetServerPtr server ATTRIBUTE_UNUSED ,
virNetServerClientPtr client ATTRIBUTE_UNUSED ,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED ,
virNetMessageErrorPtr rerr ,
remote_domain_migrate_confirm3_args * args )
2011-02-01 17:23:40 +03:00
{
virDomainPtr dom = NULL ;
int rv = - 1 ;
2011-05-16 21:13:11 +04:00
struct daemonClientPrivate * priv =
virNetServerClientGetPrivateData ( client ) ;
2011-02-01 17:23:40 +03:00
2011-05-16 21:13:11 +04:00
if ( ! priv - > conn ) {
2011-02-01 17:23:40 +03:00
virNetError ( VIR_ERR_INTERNAL_ERROR , " %s " , _ ( " connection not open " ) ) ;
goto cleanup ;
}
2011-05-16 21:13:11 +04:00
if ( ! ( dom = get_nonnull_domain ( priv - > conn , args - > dom ) ) )
2011-02-01 17:23:40 +03:00
goto cleanup ;
if ( virDomainMigrateConfirm3 ( dom ,
args - > cookie_in . cookie_in_val ,
args - > cookie_in . cookie_in_len ,
args - > flags , args - > cancelled ) < 0 )
goto cleanup ;
rv = 0 ;
cleanup :
if ( rv < 0 )
2011-05-16 21:13:11 +04:00
virNetMessageSaveError ( rerr ) ;
2011-02-01 17:23:40 +03:00
if ( dom )
virDomainFree ( dom ) ;
return rv ;
}
2007-06-11 15:47:01 +04:00
/*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* ( name , uuid ) pair into virDomainPtr or virNetworkPtr object .
* virDomainPtr or virNetworkPtr cannot be NULL .
*
* NB . If these return NULL then the caller must return an error .
*/
static virDomainPtr
2011-04-12 20:34:30 +04:00
get_nonnull_domain ( virConnectPtr conn , remote_nonnull_domain domain )
2007-06-11 15:47:01 +04:00
{
virDomainPtr dom ;
2011-04-12 20:34:30 +04:00
dom = virGetDomain ( conn , domain . name , BAD_CAST domain . uuid ) ;
2007-06-11 15:47:01 +04:00
/* Should we believe the domain.id sent by the client? Maybe
* this should be a check rather than an assignment ? XXX
*/
if ( dom ) dom - > id = domain . id ;
return dom ;
}
static virNetworkPtr
2011-04-12 20:34:30 +04:00
get_nonnull_network ( virConnectPtr conn , remote_nonnull_network network )
2007-06-11 15:47:01 +04:00
{
2011-04-12 20:34:30 +04:00
return virGetNetwork ( conn , network . name , BAD_CAST network . uuid ) ;
2007-06-11 15:47:01 +04:00
}
2009-05-20 18:26:49 +04:00
static virInterfacePtr
2011-04-12 20:34:30 +04:00
get_nonnull_interface ( virConnectPtr conn , remote_nonnull_interface iface )
2009-05-20 18:26:49 +04:00
{
2011-04-12 20:34:30 +04:00
return virGetInterface ( conn , iface . name , iface . mac ) ;
2009-05-20 18:26:49 +04:00
}
2008-02-20 18:22:35 +03:00
static virStoragePoolPtr
2011-04-12 20:34:30 +04:00
get_nonnull_storage_pool ( virConnectPtr conn , remote_nonnull_storage_pool pool )
2008-02-20 18:22:35 +03:00
{
2011-04-12 20:34:30 +04:00
return virGetStoragePool ( conn , pool . name , BAD_CAST pool . uuid ) ;
2008-02-20 18:22:35 +03:00
}
static virStorageVolPtr
2011-04-12 20:34:30 +04:00
get_nonnull_storage_vol ( virConnectPtr conn , remote_nonnull_storage_vol vol )
2008-02-20 18:22:35 +03:00
{
virStorageVolPtr ret ;
2011-04-12 20:34:30 +04:00
ret = virGetStorageVol ( conn , vol . pool , vol . name , vol . key ) ;
2008-02-20 18:22:35 +03:00
return ret ;
}
2009-07-28 06:01:00 +04:00
static virSecretPtr
2011-04-12 20:34:30 +04:00
get_nonnull_secret ( virConnectPtr conn , remote_nonnull_secret secret )
2009-07-28 06:01:00 +04:00
{
2011-04-12 20:34:30 +04:00
return virGetSecret ( conn , BAD_CAST secret . uuid , secret . usageType , secret . usageID ) ;
2009-07-28 06:01:00 +04:00
}
2010-03-25 20:46:03 +03:00
static virNWFilterPtr
2011-04-12 20:34:30 +04:00
get_nonnull_nwfilter ( virConnectPtr conn , remote_nonnull_nwfilter nwfilter )
2010-03-25 20:46:03 +03:00
{
2011-04-12 20:34:30 +04:00
return virGetNWFilter ( conn , nwfilter . name , BAD_CAST nwfilter . uuid ) ;
2010-03-25 20:46:03 +03:00
}
2010-04-01 00:33:13 +04:00
static virDomainSnapshotPtr
2011-04-13 22:10:03 +04:00
get_nonnull_domain_snapshot ( virDomainPtr dom , remote_nonnull_domain_snapshot snapshot )
2010-04-01 00:33:13 +04:00
{
2011-04-13 22:10:03 +04:00
return virGetDomainSnapshot ( dom , snapshot . name ) ;
2010-04-01 00:33:13 +04:00
}
2007-06-11 15:47:01 +04:00
/* Make remote_nonnull_domain and remote_nonnull_network. */
static void
2011-04-12 20:34:30 +04:00
make_nonnull_domain ( remote_nonnull_domain * dom_dst , virDomainPtr dom_src )
2007-06-11 15:47:01 +04:00
{
dom_dst - > id = dom_src - > id ;
2011-04-12 20:34:30 +04:00
dom_dst - > name = strdup ( dom_src - > name ) ;
memcpy ( dom_dst - > uuid , dom_src - > uuid , VIR_UUID_BUFLEN ) ;
2007-06-11 15:47:01 +04:00
}
static void
2011-04-12 20:34:30 +04:00
make_nonnull_network ( remote_nonnull_network * net_dst , virNetworkPtr net_src )
2007-06-11 15:47:01 +04:00
{
2011-04-12 20:34:30 +04:00
net_dst - > name = strdup ( net_src - > name ) ;
memcpy ( net_dst - > uuid , net_src - > uuid , VIR_UUID_BUFLEN ) ;
2007-06-11 15:47:01 +04:00
}
2009-05-20 18:26:49 +04:00
static void
2011-04-12 20:34:30 +04:00
make_nonnull_interface ( remote_nonnull_interface * interface_dst ,
virInterfacePtr interface_src )
2009-05-20 18:26:49 +04:00
{
2011-04-12 20:34:30 +04:00
interface_dst - > name = strdup ( interface_src - > name ) ;
interface_dst - > mac = strdup ( interface_src - > mac ) ;
2009-05-20 18:26:49 +04:00
}
2008-02-20 18:22:35 +03:00
static void
2011-04-12 20:34:30 +04:00
make_nonnull_storage_pool ( remote_nonnull_storage_pool * pool_dst , virStoragePoolPtr pool_src )
2008-02-20 18:22:35 +03:00
{
2011-04-12 20:34:30 +04:00
pool_dst - > name = strdup ( pool_src - > name ) ;
memcpy ( pool_dst - > uuid , pool_src - > uuid , VIR_UUID_BUFLEN ) ;
2008-02-20 18:22:35 +03:00
}
static void
2011-04-12 20:34:30 +04:00
make_nonnull_storage_vol ( remote_nonnull_storage_vol * vol_dst , virStorageVolPtr vol_src )
2008-02-20 18:22:35 +03:00
{
2011-04-12 20:34:30 +04:00
vol_dst - > pool = strdup ( vol_src - > pool ) ;
vol_dst - > name = strdup ( vol_src - > name ) ;
vol_dst - > key = strdup ( vol_src - > key ) ;
2008-02-20 18:22:35 +03:00
}
2008-11-21 15:31:04 +03:00
static void
2011-04-12 20:34:30 +04:00
make_nonnull_node_device ( remote_nonnull_node_device * dev_dst , virNodeDevicePtr dev_src )
2008-11-21 15:31:04 +03:00
{
dev_dst - > name = strdup ( dev_src - > name ) ;
}
2009-07-28 06:01:00 +04:00
static void
2011-04-12 20:34:30 +04:00
make_nonnull_secret ( remote_nonnull_secret * secret_dst , virSecretPtr secret_src )
2009-07-28 06:01:00 +04:00
{
2011-04-12 20:34:30 +04:00
memcpy ( secret_dst - > uuid , secret_src - > uuid , VIR_UUID_BUFLEN ) ;
Add usage type/id as a public API property of virSecret
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in: Add
virSecretGetUsageType, virSecretGetUsageID and virLookupSecretByUsage
* python/generator.py: Mark virSecretGetUsageType, virSecretGetUsageID
as not throwing exceptions
* qemud/remote.c: Implement dispatch for virLookupSecretByUsage
* qemud/remote_protocol.x: Add usage type & ID as attributes of
remote_nonnull_secret. Add RPC calls for new public APIs
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.c, src/datatypes.h: Add usageType and usageID as
properties of virSecretPtr
* src/driver.h: Add virLookupSecretByUsage driver entry point
* src/libvirt.c: Implement virSecretGetUsageType, virSecretGetUsageID
and virLookupSecretByUsage
* src/libvirt_public.syms: Export virSecretGetUsageType, virSecretGetUsageID
and virLookupSecretByUsage
* src/remote_internal.c: Implement virLookupSecretByUsage entry
* src/secret_conf.c, src/secret_conf.h: Remove the
virSecretUsageType enum, now in public API. Make volume
path mandatory when parsing XML
* src/secret_driver.c: Enforce usage uniqueness when defining secrets.
Implement virSecretLookupByUsage api method
* src/virsh.c: Include usage for secret-list command
2009-09-11 17:06:15 +04:00
secret_dst - > usageType = secret_src - > usageType ;
2011-04-12 20:34:30 +04:00
secret_dst - > usageID = strdup ( secret_src - > usageID ) ;
2009-07-28 06:01:00 +04:00
}
2010-03-25 20:46:03 +03:00
static void
2011-04-12 20:34:30 +04:00
make_nonnull_nwfilter ( remote_nonnull_nwfilter * nwfilter_dst , virNWFilterPtr nwfilter_src )
2010-03-25 20:46:03 +03:00
{
2011-04-12 20:34:30 +04:00
nwfilter_dst - > name = strdup ( nwfilter_src - > name ) ;
memcpy ( nwfilter_dst - > uuid , nwfilter_src - > uuid , VIR_UUID_BUFLEN ) ;
2010-03-25 20:46:03 +03:00
}
2010-04-01 00:33:13 +04:00
static void
2011-04-12 20:34:30 +04:00
make_nonnull_domain_snapshot ( remote_nonnull_domain_snapshot * snapshot_dst , virDomainSnapshotPtr snapshot_src )
2010-04-01 00:33:13 +04:00
{
snapshot_dst - > name = strdup ( snapshot_src - > name ) ;
2011-04-22 17:40:31 +04:00
make_nonnull_domain ( & snapshot_dst - > dom , snapshot_src - > domain ) ;
2010-04-01 00:33:13 +04:00
}