2007-06-11 11:43:41 +00:00
|
|
|
/*
|
2011-07-20 03:01:45 +00:00
|
|
|
* remote_driver.c: driver to provide access to libvirtd running
|
2007-06-11 11:43:41 +00:00
|
|
|
* on a remote machine
|
|
|
|
*
|
2015-02-09 23:59:23 +00:00
|
|
|
* Copyright (C) 2007-2015 Red Hat, Inc.
|
2007-06-11 11:43:41 +00: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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2007-06-11 11:43:41 +00:00
|
|
|
*
|
|
|
|
* Author: Richard Jones <rjones@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-08-07 14:29:45 +00:00
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
#include <unistd.h>
|
2007-12-07 14:56:37 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
#include "virnetclient.h"
|
|
|
|
#include "virnetclientprogram.h"
|
|
|
|
#include "virnetclientstream.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2008-11-04 23:33:57 +00:00
|
|
|
#include "domain_event.h"
|
2013-12-11 10:38:01 +00:00
|
|
|
#include "network_event.h"
|
2016-06-15 18:35:45 +00:00
|
|
|
#include "storage_event.h"
|
2016-07-28 12:02:53 +00:00
|
|
|
#include "node_device_event.h"
|
2016-12-22 16:11:06 +00:00
|
|
|
#include "secret_event.h"
|
2007-06-11 11:43:41 +00:00
|
|
|
#include "driver.h"
|
2012-12-04 12:04:07 +00:00
|
|
|
#include "virbuffer.h"
|
2009-09-15 17:47:05 +00:00
|
|
|
#include "remote_driver.h"
|
2007-06-11 11:43:41 +00:00
|
|
|
#include "remote_protocol.h"
|
2012-12-21 14:20:04 +00:00
|
|
|
#include "lxc_protocol.h"
|
2010-04-17 02:09:25 +00:00
|
|
|
#include "qemu_protocol.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2012-12-12 16:27:01 +00:00
|
|
|
#include "vircommand.h"
|
2011-06-24 18:16:05 +00:00
|
|
|
#include "intprops.h"
|
2012-01-31 03:20:40 +00:00
|
|
|
#include "virtypedparam.h"
|
2012-02-24 18:48:55 +00:00
|
|
|
#include "viruri.h"
|
2012-03-20 11:11:10 +00:00
|
|
|
#include "virauth.h"
|
|
|
|
#include "virauthconfig.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_REMOTE
|
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("remote.remote_driver");
|
|
|
|
|
2011-05-30 10:58:57 +00:00
|
|
|
#if SIZEOF_LONG < 8
|
2017-11-03 12:09:47 +00:00
|
|
|
# define HYPER_TO_TYPE(_type, _to, _from) \
|
|
|
|
do { \
|
|
|
|
if ((_from) != (_type)(_from)) { \
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
2012-07-18 13:35:21 +00:00
|
|
|
_("conversion from hyper to %s overflowed"), #_type); \
|
2017-11-03 12:09:47 +00:00
|
|
|
goto done; \
|
|
|
|
} \
|
|
|
|
(_to) = (_from); \
|
2011-05-30 10:58:57 +00:00
|
|
|
} 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
|
|
|
|
|
2014-10-28 18:38:04 +00:00
|
|
|
static bool inside_daemon;
|
2007-10-27 01:23:28 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data {
|
|
|
|
virMutex lock;
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientPtr client;
|
|
|
|
virNetClientProgramPtr remoteProgram;
|
|
|
|
virNetClientProgramPtr qemuProgram;
|
2012-12-21 14:20:04 +00:00
|
|
|
virNetClientProgramPtr lxcProgram;
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
int counter; /* Serial number for RPC */
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2013-01-08 21:02:05 +00:00
|
|
|
#ifdef WITH_GNUTLS
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetTLSContextPtr tls;
|
2013-01-07 14:54:18 +00:00
|
|
|
#endif
|
2009-01-20 11:41:24 +00: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 14:12:03 +00:00
|
|
|
int is_secure; /* Secure if TLS or SASL or UNIX sockets */
|
2007-06-11 11:43:41 +00:00
|
|
|
char *type; /* Cached return from remoteType. */
|
2008-02-20 15:23:36 +00:00
|
|
|
int localUses; /* Ref count for private data */
|
2007-12-05 15:24:15 +00:00
|
|
|
char *hostname; /* Original hostname */
|
2011-09-22 12:59:06 +00:00
|
|
|
bool serverKeepAlive; /* Does server support keepalive protocol? */
|
2014-01-08 04:00:54 +00:00
|
|
|
bool serverEventFilter; /* Does server support modern event filtering */
|
2016-02-17 12:15:02 +00:00
|
|
|
bool serverCloseCallback; /* Does server support driver close callback */
|
2009-01-20 16:36:34 +00:00
|
|
|
|
2014-01-04 13:14:33 +00:00
|
|
|
virObjectEventStatePtr eventState;
|
2016-03-01 14:17:38 +00:00
|
|
|
virConnectCloseCallbackDataPtr closeCallback;
|
2007-06-11 11:43:41 +00:00
|
|
|
};
|
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
enum {
|
2010-12-01 16:46:36 +00:00
|
|
|
REMOTE_CALL_QEMU = (1 << 0),
|
2012-12-21 14:20:04 +00:00
|
|
|
REMOTE_CALL_LXC = (1 << 1),
|
2007-12-05 15:24:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
static void remoteDriverLock(struct private_data *driver)
|
|
|
|
{
|
|
|
|
virMutexLock(&driver->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void remoteDriverUnlock(struct private_data *driver)
|
|
|
|
{
|
|
|
|
virMutexUnlock(&driver->lock);
|
|
|
|
}
|
|
|
|
|
2011-10-21 11:49:23 +00:00
|
|
|
static int call(virConnectPtr conn, struct private_data *priv,
|
|
|
|
unsigned int flags, int proc_nr,
|
|
|
|
xdrproc_t args_filter, char *args,
|
|
|
|
xdrproc_t ret_filter, char *ret);
|
2012-12-21 14:20:04 +00:00
|
|
|
static int callFull(virConnectPtr conn, struct private_data *priv,
|
|
|
|
unsigned int flags,
|
|
|
|
int *fdin, size_t fdinlen,
|
|
|
|
int **fdout, size_t *fdoutlen,
|
|
|
|
int proc_nr,
|
|
|
|
xdrproc_t args_filter, char *args,
|
|
|
|
xdrproc_t ret_filter, char *ret);
|
2012-10-17 09:23:12 +00:00
|
|
|
static int remoteAuthenticate(virConnectPtr conn, struct private_data *priv,
|
|
|
|
virConnectAuthPtr auth, const char *authtype);
|
2012-09-20 11:58:29 +00:00
|
|
|
#if WITH_SASL
|
2012-10-17 09:23:12 +00:00
|
|
|
static int remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
|
|
|
|
virConnectAuthPtr auth, const char *mech);
|
2016-04-14 18:58:40 +00:00
|
|
|
#endif /* WITH_SASL */
|
2012-10-17 09:23:12 +00:00
|
|
|
static int remoteAuthPolkit(virConnectPtr conn, struct private_data *priv,
|
|
|
|
virConnectAuthPtr auth);
|
2010-04-03 12:55:42 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
static virDomainPtr get_nonnull_domain(virConnectPtr conn, remote_nonnull_domain domain);
|
|
|
|
static virNetworkPtr get_nonnull_network(virConnectPtr conn, remote_nonnull_network network);
|
|
|
|
static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
|
|
|
|
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 virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev);
|
|
|
|
static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
|
|
|
|
static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot);
|
|
|
|
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 vol_src);
|
|
|
|
static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
|
2016-07-28 12:02:53 +00:00
|
|
|
static void
|
|
|
|
make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src);
|
2012-10-17 09:23:12 +00:00
|
|
|
static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
|
|
|
|
static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
|
|
|
|
static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
|
2014-01-06 12:32:55 +00:00
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* Helper functions for remoteOpen. */
|
2018-04-13 08:51:25 +00:00
|
|
|
static int remoteSplitURIScheme(virURIPtr uri,
|
|
|
|
char **driver,
|
|
|
|
char **transport)
|
|
|
|
{
|
|
|
|
char *p = strchr(uri->scheme, '+');
|
|
|
|
|
|
|
|
*driver = *transport = NULL;
|
|
|
|
|
|
|
|
if (VIR_STRNDUP(*driver, uri->scheme, p ? p - uri->scheme : -1) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (p &&
|
|
|
|
VIR_STRDUP(*transport, p + 1) < 0) {
|
|
|
|
VIR_FREE(*driver);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2007-10-27 01:23:28 +00:00
|
|
|
static int
|
2013-04-23 12:50:18 +00:00
|
|
|
remoteStateInitialize(bool privileged ATTRIBUTE_UNUSED,
|
|
|
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2007-10-27 01:23:28 +00:00
|
|
|
{
|
|
|
|
/* Mark that we're inside the daemon so we can avoid
|
|
|
|
* re-entering ourselves
|
|
|
|
*/
|
2012-10-31 19:03:54 +00:00
|
|
|
inside_daemon = true;
|
2007-10-27 01:23:28 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-05-06 15:23:57 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-08 14:57:25 +00:00
|
|
|
remoteDomainBuildEventCallbackLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackRTCChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackWatchdog(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventIOError(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackIOError(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackIOErrorReason(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventGraphics(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackGraphics(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDomainBuildEventControlError(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackControlError(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2011-07-22 05:57:42 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackBlockJob(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2011-07-22 05:57:42 +00:00
|
|
|
|
2011-10-18 14:15:42 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDiskChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2011-10-18 14:15:42 +00:00
|
|
|
|
2012-03-23 13:44:50 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackTrayChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2012-03-23 13:44:50 +00:00
|
|
|
|
2012-03-23 14:43:14 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackPMWakeup(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2012-03-23 14:43:14 +00:00
|
|
|
|
2012-03-23 14:50:36 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2012-07-13 09:05:17 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackPMSuspend(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2012-07-13 09:05:17 +00:00
|
|
|
remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2012-10-12 19:13:39 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventCallbackBalloonChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static void
|
2012-10-12 19:13:39 +00:00
|
|
|
remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackPMSuspendDisk(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2012-03-23 14:50:36 +00:00
|
|
|
|
2013-06-19 13:27:29 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2014-01-09 18:22:53 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2015-03-30 16:46:21 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2016-03-30 16:09:45 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
2013-06-19 13:27:29 +00:00
|
|
|
|
blockjob: use stable disk string in job event
When the block job event was first added, it was for block pull,
where the active layer of the disk remains the same name. It was
also in a day where we only cared about local files, and so we
always had a canonical absolute file name. But two things have
changed since then: we now have network disks, where determining
a single absolute string does not really make sense; and we have
two-phase jobs (copy and active commit) where the name of the
active layer changes between the first event (ready, on the old
name) and second (complete, on the pivoted name).
Adam Litke reported that having an unstable string between events
makes life harder for clients. Furthermore, all of our API that
operate on a particular disk of a domain accept multiple strings:
not only the absolute name of the active layer, but also the
destination device name (such as 'vda'). As this latter name is
stable, even for network sources, it serves as a better string
to supply in block job events.
But backwards-compatibility demands that we should not change the
name handed to users unless they explicitly request it. Therefore,
this patch adds a new event, BLOCK_JOB_2 (alas, I couldn't think of
any nicer name - but at least Migrate2 and Migrate3 are precedent
for a number suffix). We must double up on emitting both old-style
and new-style events according to what clients have registered for
(see also how IOError and IOErrorReason emits double events, but
there the difference was a larger struct rather than changed
meaning of one of the struct members).
Unfortunately, adding a new event isn't something that can easily
be broken into pieces, so the commit is rather large.
* include/libvirt/libvirt.h.in (virDomainEventID): Add a new id
for VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2.
(virConnectDomainEventBlockJobCallback): Document new semantics.
* src/conf/domain_event.c (_virDomainEventBlockJob): Rename field,
to ensure we catch all clients.
(virDomainEventBlockJobNew): Add parameter.
(virDomainEventBlockJobDispose)
(virDomainEventBlockJobNewFromObj)
(virDomainEventBlockJobNewFromDom)
(virDomainEventDispatchDefaultFunc): Adjust clients.
(virDomainEventBlockJob2NewFromObj)
(virDomainEventBlockJob2NewFromDom): New functions.
* src/conf/domain_event.h: Add new prototypes.
* src/libvirt_private.syms (domain_event.h): Export new functions.
* src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Generate two
different events.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Likewise.
* src/remote/remote_protocol.x
(remote_domain_event_block_job_2_msg): New struct.
(REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2): New RPC.
* src/remote/remote_driver.c
(remoteDomainBuildEventBlockJob2): New handler.
(remoteEvents): Register new event.
* daemon/remote.c (remoteRelayDomainEventBlockJob2): New handler.
(domainEventCallbacks): Register new event.
* tools/virsh-domain.c (vshEventCallbacks): Likewise.
(vshEventBlockJobPrint): Adjust client.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-06-14 13:18:04 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2014-09-10 11:28:24 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2014-11-19 09:32:20 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2015-12-10 15:09:09 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-02-17 20:20:11 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackJobCompleted(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-12-22 14:41:30 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackMetadataChange(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2013-12-11 10:38:01 +00:00
|
|
|
static void
|
|
|
|
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-06-15 18:35:45 +00:00
|
|
|
static void
|
|
|
|
remoteStoragePoolBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-06-24 16:35:51 +00:00
|
|
|
static void
|
|
|
|
remoteStoragePoolBuildEventRefresh(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-07-28 12:02:53 +00:00
|
|
|
static void
|
|
|
|
remoteNodeDeviceBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-08-11 15:15:23 +00:00
|
|
|
static void
|
|
|
|
remoteNodeDeviceBuildEventUpdate(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-12-22 16:11:06 +00:00
|
|
|
static void
|
|
|
|
remoteSecretBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2017-01-05 13:51:07 +00:00
|
|
|
static void
|
|
|
|
remoteSecretBuildEventValueChanged(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2017-02-21 14:03:07 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventBlockThreshold(virNetClientProgramPtr prog,
|
|
|
|
virNetClientPtr client,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2016-02-17 12:15:02 +00:00
|
|
|
static void
|
|
|
|
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
2014-01-04 13:14:33 +00:00
|
|
|
static virNetClientProgramEvent remoteEvents[] = {
|
2010-12-01 16:46:36 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
|
|
|
|
remoteDomainBuildEventLifecycle,
|
|
|
|
sizeof(remote_domain_event_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_lifecycle_msg },
|
2014-01-09 18:22:53 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_REBOOT,
|
|
|
|
remoteDomainBuildEventReboot,
|
|
|
|
sizeof(remote_domain_event_reboot_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_reboot_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
|
|
|
|
remoteDomainBuildEventRTCChange,
|
|
|
|
sizeof(remote_domain_event_rtc_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_rtc_change_msg },
|
2010-12-01 16:46:36 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_WATCHDOG,
|
|
|
|
remoteDomainBuildEventWatchdog,
|
|
|
|
sizeof(remote_domain_event_watchdog_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_watchdog_msg},
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR,
|
|
|
|
remoteDomainBuildEventIOError,
|
|
|
|
sizeof(remote_domain_event_io_error_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_io_error_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_GRAPHICS,
|
|
|
|
remoteDomainBuildEventGraphics,
|
|
|
|
sizeof(remote_domain_event_graphics_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_graphics_msg },
|
2014-01-09 18:22:53 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON,
|
|
|
|
remoteDomainBuildEventIOErrorReason,
|
|
|
|
sizeof(remote_domain_event_io_error_reason_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_io_error_reason_msg },
|
2010-12-01 16:46:36 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR,
|
|
|
|
remoteDomainBuildEventControlError,
|
|
|
|
sizeof(remote_domain_event_control_error_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_control_error_msg },
|
2011-07-22 05:57:42 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB,
|
|
|
|
remoteDomainBuildEventBlockJob,
|
|
|
|
sizeof(remote_domain_event_block_job_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_block_job_msg },
|
2011-10-18 14:15:42 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE,
|
|
|
|
remoteDomainBuildEventDiskChange,
|
|
|
|
sizeof(remote_domain_event_disk_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_disk_change_msg },
|
2012-03-23 13:44:50 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE,
|
|
|
|
remoteDomainBuildEventTrayChange,
|
|
|
|
sizeof(remote_domain_event_tray_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_tray_change_msg },
|
2012-03-23 14:43:14 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP,
|
|
|
|
remoteDomainBuildEventPMWakeup,
|
|
|
|
sizeof(remote_domain_event_pmwakeup_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_pmwakeup_msg },
|
2012-03-23 14:50:36 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND,
|
|
|
|
remoteDomainBuildEventPMSuspend,
|
|
|
|
sizeof(remote_domain_event_pmsuspend_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_pmsuspend_msg },
|
2012-07-13 09:05:17 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_BALLOON_CHANGE,
|
|
|
|
remoteDomainBuildEventBalloonChange,
|
|
|
|
sizeof(remote_domain_event_balloon_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_balloon_change_msg },
|
2012-10-12 19:13:39 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK,
|
|
|
|
remoteDomainBuildEventPMSuspendDisk,
|
|
|
|
sizeof(remote_domain_event_pmsuspend_disk_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_pmsuspend_disk_msg },
|
2013-06-19 13:27:29 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED,
|
|
|
|
remoteDomainBuildEventDeviceRemoved,
|
|
|
|
sizeof(remote_domain_event_device_removed_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_device_removed_msg },
|
2014-01-08 14:57:25 +00:00
|
|
|
/* All events above here are legacy events, missing the callback
|
|
|
|
* ID, which means the server has a single global registration and
|
|
|
|
* we do full filtering in the client. If the server lacks
|
|
|
|
* VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK, those are the only
|
|
|
|
* events we should ever receive. Conversely, all events below
|
|
|
|
* here should only be triggered by modern servers, and all
|
|
|
|
* contain a callbackID. Although we have to duplicate the first
|
|
|
|
* 16 domain events in both styles for back-compat, any future
|
|
|
|
* domain event additions should only use the modern style. */
|
2013-12-11 10:38:01 +00:00
|
|
|
{ REMOTE_PROC_NETWORK_EVENT_LIFECYCLE,
|
|
|
|
remoteNetworkBuildEventLifecycle,
|
|
|
|
sizeof(remote_network_event_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_network_event_lifecycle_msg },
|
2014-01-08 14:57:25 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_LIFECYCLE,
|
|
|
|
remoteDomainBuildEventCallbackLifecycle,
|
|
|
|
sizeof(remote_domain_event_callback_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_lifecycle_msg },
|
2014-01-09 18:22:53 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_REBOOT,
|
|
|
|
remoteDomainBuildEventCallbackReboot,
|
|
|
|
sizeof(remote_domain_event_callback_reboot_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_reboot_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_RTC_CHANGE,
|
|
|
|
remoteDomainBuildEventCallbackRTCChange,
|
|
|
|
sizeof(remote_domain_event_callback_rtc_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_rtc_change_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WATCHDOG,
|
|
|
|
remoteDomainBuildEventCallbackWatchdog,
|
|
|
|
sizeof(remote_domain_event_callback_watchdog_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_watchdog_msg},
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR,
|
|
|
|
remoteDomainBuildEventCallbackIOError,
|
|
|
|
sizeof(remote_domain_event_callback_io_error_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_io_error_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_GRAPHICS,
|
|
|
|
remoteDomainBuildEventCallbackGraphics,
|
|
|
|
sizeof(remote_domain_event_callback_graphics_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_graphics_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR_REASON,
|
|
|
|
remoteDomainBuildEventCallbackIOErrorReason,
|
|
|
|
sizeof(remote_domain_event_callback_io_error_reason_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_io_error_reason_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CONTROL_ERROR,
|
|
|
|
remoteDomainBuildEventCallbackControlError,
|
|
|
|
sizeof(remote_domain_event_callback_control_error_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_control_error_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BLOCK_JOB,
|
|
|
|
remoteDomainBuildEventCallbackBlockJob,
|
|
|
|
sizeof(remote_domain_event_callback_block_job_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_block_job_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DISK_CHANGE,
|
|
|
|
remoteDomainBuildEventCallbackDiskChange,
|
|
|
|
sizeof(remote_domain_event_callback_disk_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_disk_change_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TRAY_CHANGE,
|
|
|
|
remoteDomainBuildEventCallbackTrayChange,
|
|
|
|
sizeof(remote_domain_event_callback_tray_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_tray_change_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMWAKEUP,
|
|
|
|
remoteDomainBuildEventCallbackPMWakeup,
|
|
|
|
sizeof(remote_domain_event_callback_pmwakeup_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_pmwakeup_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND,
|
|
|
|
remoteDomainBuildEventCallbackPMSuspend,
|
|
|
|
sizeof(remote_domain_event_callback_pmsuspend_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_pmsuspend_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE,
|
|
|
|
remoteDomainBuildEventCallbackBalloonChange,
|
|
|
|
sizeof(remote_domain_event_callback_balloon_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_balloon_change_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK,
|
|
|
|
remoteDomainBuildEventCallbackPMSuspendDisk,
|
|
|
|
sizeof(remote_domain_event_callback_pmsuspend_disk_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_pmsuspend_disk_msg },
|
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED,
|
|
|
|
remoteDomainBuildEventCallbackDeviceRemoved,
|
|
|
|
sizeof(remote_domain_event_callback_device_removed_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_device_removed_msg },
|
blockjob: use stable disk string in job event
When the block job event was first added, it was for block pull,
where the active layer of the disk remains the same name. It was
also in a day where we only cared about local files, and so we
always had a canonical absolute file name. But two things have
changed since then: we now have network disks, where determining
a single absolute string does not really make sense; and we have
two-phase jobs (copy and active commit) where the name of the
active layer changes between the first event (ready, on the old
name) and second (complete, on the pivoted name).
Adam Litke reported that having an unstable string between events
makes life harder for clients. Furthermore, all of our API that
operate on a particular disk of a domain accept multiple strings:
not only the absolute name of the active layer, but also the
destination device name (such as 'vda'). As this latter name is
stable, even for network sources, it serves as a better string
to supply in block job events.
But backwards-compatibility demands that we should not change the
name handed to users unless they explicitly request it. Therefore,
this patch adds a new event, BLOCK_JOB_2 (alas, I couldn't think of
any nicer name - but at least Migrate2 and Migrate3 are precedent
for a number suffix). We must double up on emitting both old-style
and new-style events according to what clients have registered for
(see also how IOError and IOErrorReason emits double events, but
there the difference was a larger struct rather than changed
meaning of one of the struct members).
Unfortunately, adding a new event isn't something that can easily
be broken into pieces, so the commit is rather large.
* include/libvirt/libvirt.h.in (virDomainEventID): Add a new id
for VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2.
(virConnectDomainEventBlockJobCallback): Document new semantics.
* src/conf/domain_event.c (_virDomainEventBlockJob): Rename field,
to ensure we catch all clients.
(virDomainEventBlockJobNew): Add parameter.
(virDomainEventBlockJobDispose)
(virDomainEventBlockJobNewFromObj)
(virDomainEventBlockJobNewFromDom)
(virDomainEventDispatchDefaultFunc): Adjust clients.
(virDomainEventBlockJob2NewFromObj)
(virDomainEventBlockJob2NewFromDom): New functions.
* src/conf/domain_event.h: Add new prototypes.
* src/libvirt_private.syms (domain_event.h): Export new functions.
* src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Generate two
different events.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Likewise.
* src/remote/remote_protocol.x
(remote_domain_event_block_job_2_msg): New struct.
(REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2): New RPC.
* src/remote/remote_driver.c
(remoteDomainBuildEventBlockJob2): New handler.
(remoteEvents): Register new event.
* daemon/remote.c (remoteRelayDomainEventBlockJob2): New handler.
(domainEventCallbacks): Register new event.
* tools/virsh-domain.c (vshEventCallbacks): Likewise.
(vshEventBlockJobPrint): Adjust client.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-06-14 13:18:04 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2,
|
|
|
|
remoteDomainBuildEventBlockJob2,
|
|
|
|
sizeof(remote_domain_event_block_job_2_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_block_job_2_msg },
|
2014-09-10 11:28:24 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE,
|
|
|
|
remoteDomainBuildEventCallbackTunable,
|
|
|
|
sizeof(remote_domain_event_callback_tunable_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_tunable_msg },
|
2014-11-19 09:32:20 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
|
|
|
|
remoteDomainBuildEventCallbackAgentLifecycle,
|
|
|
|
sizeof(remote_domain_event_callback_agent_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg },
|
2015-03-30 16:46:21 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED,
|
|
|
|
remoteDomainBuildEventCallbackDeviceAdded,
|
|
|
|
sizeof(remote_domain_event_callback_device_added_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_device_added_msg },
|
2015-12-10 15:09:09 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION,
|
|
|
|
remoteDomainBuildEventCallbackMigrationIteration,
|
|
|
|
sizeof(remote_domain_event_callback_migration_iteration_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_migration_iteration_msg },
|
2016-02-17 12:15:02 +00:00
|
|
|
{ REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED,
|
|
|
|
remoteConnectNotifyEventConnectionClosed,
|
|
|
|
sizeof(remote_connect_event_connection_closed_msg),
|
|
|
|
(xdrproc_t)xdr_remote_connect_event_connection_closed_msg },
|
2016-02-17 20:20:11 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_JOB_COMPLETED,
|
|
|
|
remoteDomainBuildEventCallbackJobCompleted,
|
|
|
|
sizeof(remote_domain_event_callback_job_completed_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_job_completed_msg },
|
2016-03-30 16:09:45 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED,
|
|
|
|
remoteDomainBuildEventCallbackDeviceRemovalFailed,
|
|
|
|
sizeof(remote_domain_event_callback_device_removal_failed_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_device_removal_failed_msg },
|
2016-12-22 14:41:30 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_METADATA_CHANGE,
|
|
|
|
remoteDomainBuildEventCallbackMetadataChange,
|
|
|
|
sizeof(remote_domain_event_callback_metadata_change_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_callback_metadata_change_msg },
|
2016-06-15 18:35:45 +00:00
|
|
|
{ REMOTE_PROC_STORAGE_POOL_EVENT_LIFECYCLE,
|
|
|
|
remoteStoragePoolBuildEventLifecycle,
|
|
|
|
sizeof(remote_storage_pool_event_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_storage_pool_event_lifecycle_msg },
|
2016-06-24 16:35:51 +00:00
|
|
|
{ REMOTE_PROC_STORAGE_POOL_EVENT_REFRESH,
|
|
|
|
remoteStoragePoolBuildEventRefresh,
|
|
|
|
sizeof(remote_storage_pool_event_refresh_msg),
|
|
|
|
(xdrproc_t)xdr_remote_storage_pool_event_refresh_msg },
|
2016-07-28 12:02:53 +00:00
|
|
|
{ REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE,
|
|
|
|
remoteNodeDeviceBuildEventLifecycle,
|
|
|
|
sizeof(remote_node_device_event_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_node_device_event_lifecycle_msg },
|
2016-08-11 15:15:23 +00:00
|
|
|
{ REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE,
|
|
|
|
remoteNodeDeviceBuildEventUpdate,
|
|
|
|
sizeof(remote_node_device_event_update_msg),
|
|
|
|
(xdrproc_t)xdr_remote_node_device_event_update_msg },
|
2016-12-22 16:11:06 +00:00
|
|
|
{ REMOTE_PROC_SECRET_EVENT_LIFECYCLE,
|
|
|
|
remoteSecretBuildEventLifecycle,
|
|
|
|
sizeof(remote_secret_event_lifecycle_msg),
|
|
|
|
(xdrproc_t)xdr_remote_secret_event_lifecycle_msg },
|
2017-01-05 13:51:07 +00:00
|
|
|
{ REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED,
|
|
|
|
remoteSecretBuildEventValueChanged,
|
|
|
|
sizeof(remote_secret_event_value_changed_msg),
|
|
|
|
(xdrproc_t)xdr_remote_secret_event_value_changed_msg },
|
2017-02-21 14:03:07 +00:00
|
|
|
{ REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD,
|
|
|
|
remoteDomainBuildEventBlockThreshold,
|
|
|
|
sizeof(remote_domain_event_block_threshold_msg),
|
|
|
|
(xdrproc_t)xdr_remote_domain_event_block_threshold_msg },
|
2010-12-01 16:46:36 +00:00
|
|
|
};
|
2007-07-04 03:59:13 +00:00
|
|
|
|
2016-02-17 12:15:02 +00:00
|
|
|
static void
|
|
|
|
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_connect_event_connection_closed_msg *msg = evdata;
|
|
|
|
|
|
|
|
virConnectCloseCallbackDataCall(priv->closeCallback, msg->reason);
|
|
|
|
}
|
2014-01-29 22:30:44 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque);
|
|
|
|
|
|
|
|
static virNetClientProgramEvent qemuEvents[] = {
|
|
|
|
{ QEMU_PROC_DOMAIN_MONITOR_EVENT,
|
|
|
|
remoteDomainBuildQemuMonitorEvent,
|
|
|
|
sizeof(qemu_domain_monitor_event_msg),
|
|
|
|
(xdrproc_t)xdr_qemu_domain_monitor_event_msg },
|
|
|
|
};
|
|
|
|
|
2007-09-12 10:33:48 +00:00
|
|
|
enum virDrvOpenRemoteFlags {
|
2007-07-04 03:59:13 +00:00
|
|
|
VIR_DRV_OPEN_REMOTE_RO = (1 << 0),
|
2009-06-12 12:06:15 +00:00
|
|
|
VIR_DRV_OPEN_REMOTE_USER = (1 << 1), /* Use the per-user socket path */
|
|
|
|
VIR_DRV_OPEN_REMOTE_AUTOSTART = (1 << 2), /* Autostart a per-user daemon */
|
2007-09-12 10:33:48 +00:00
|
|
|
};
|
2007-07-04 03:59:13 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
|
2013-03-29 17:21:19 +00:00
|
|
|
static void
|
|
|
|
remoteClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
int reason,
|
|
|
|
void *opaque)
|
2012-07-19 14:58:38 +00:00
|
|
|
{
|
2016-02-17 12:14:54 +00:00
|
|
|
virConnectCloseCallbackDataCall((virConnectCloseCallbackDataPtr)opaque,
|
|
|
|
reason);
|
2012-07-19 14:58:38 +00:00
|
|
|
}
|
|
|
|
|
2016-02-17 12:15:01 +00:00
|
|
|
static bool
|
|
|
|
remoteConnectSupportsFeatureUnlocked(virConnectPtr conn,
|
|
|
|
struct private_data *priv,
|
|
|
|
int feature)
|
|
|
|
{
|
|
|
|
remote_connect_supports_feature_args args = { feature };
|
|
|
|
remote_connect_supports_feature_ret ret = { 0 };
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = call(conn, priv, 0, REMOTE_PROC_CONNECT_SUPPORTS_FEATURE,
|
|
|
|
(xdrproc_t)xdr_remote_connect_supports_feature_args, (char *) &args,
|
|
|
|
(xdrproc_t)xdr_remote_connect_supports_feature_ret, (char *) &ret);
|
|
|
|
|
|
|
|
return rc != -1 && ret.supported;
|
|
|
|
}
|
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
/* helper macro to ease extraction of arguments from the URI */
|
2017-11-03 12:09:47 +00:00
|
|
|
#define EXTRACT_URI_ARG_STR(ARG_NAME, ARG_VAR) \
|
|
|
|
if (STRCASEEQ(var->name, ARG_NAME)) { \
|
|
|
|
VIR_FREE(ARG_VAR); \
|
|
|
|
if (VIR_STRDUP(ARG_VAR, var->value) < 0) \
|
|
|
|
goto failed; \
|
|
|
|
var->ignore = 1; \
|
|
|
|
continue; \
|
2012-07-17 12:25:34 +00:00
|
|
|
}
|
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define EXTRACT_URI_ARG_BOOL(ARG_NAME, ARG_VAR) \
|
|
|
|
if (STRCASEEQ(var->name, ARG_NAME)) { \
|
|
|
|
int tmp; \
|
|
|
|
if (virStrToLong_i(var->value, NULL, 10, &tmp) < 0) { \
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG, \
|
|
|
|
_("Failed to parse value of URI component %s"), \
|
|
|
|
var->name); \
|
|
|
|
goto failed; \
|
|
|
|
} \
|
|
|
|
ARG_VAR = tmp == 0; \
|
|
|
|
var->ignore = 1; \
|
|
|
|
continue; \
|
2012-07-17 12:25:34 +00:00
|
|
|
}
|
2018-03-23 10:41:23 +00:00
|
|
|
|
|
|
|
|
2018-04-24 18:30:16 +00:00
|
|
|
#ifndef WIN32
|
2018-03-23 10:41:23 +00:00
|
|
|
static char *remoteGetUNIXSocketNonRoot(void)
|
|
|
|
{
|
|
|
|
char *sockname = NULL;
|
|
|
|
char *userdir = virGetUserRuntimeDirectory();
|
|
|
|
|
|
|
|
if (!userdir)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (virAsprintf(&sockname, "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) {
|
|
|
|
VIR_FREE(userdir);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
VIR_FREE(userdir);
|
|
|
|
|
|
|
|
VIR_DEBUG("Chosen UNIX sockname %s", sockname);
|
|
|
|
return sockname;
|
|
|
|
}
|
2018-04-24 18:30:16 +00:00
|
|
|
#endif /* WIN32 */
|
2018-03-23 10:41:23 +00:00
|
|
|
|
|
|
|
static char *remoteGetUNIXSocketRoot(unsigned int flags)
|
|
|
|
{
|
|
|
|
char *sockname = NULL;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(sockname,
|
|
|
|
flags & VIR_DRV_OPEN_REMOTE_RO ?
|
|
|
|
LIBVIRTD_PRIV_UNIX_SOCKET_RO : LIBVIRTD_PRIV_UNIX_SOCKET) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
VIR_DEBUG("Chosen UNIX sockname %s", sockname);
|
|
|
|
return sockname;
|
|
|
|
}
|
|
|
|
|
2009-06-12 12:06:15 +00:00
|
|
|
/*
|
|
|
|
* URIs that this driver needs to handle:
|
|
|
|
*
|
|
|
|
* The easy answer:
|
|
|
|
* - Everything that no one else has yet claimed, but nothing if
|
|
|
|
* we're inside the libvirtd daemon
|
|
|
|
*
|
|
|
|
* The hard answer:
|
|
|
|
* - Plain paths (///var/lib/xen/xend-socket) -> UNIX domain socket
|
|
|
|
* - xxx://servername/ -> TLS connection
|
|
|
|
* - xxx+tls://servername/ -> TLS connection
|
|
|
|
* - xxx+tls:/// -> TLS connection to localhost
|
|
|
|
* - xxx+tcp://servername/ -> TCP connection
|
|
|
|
* - xxx+tcp:/// -> TCP connection to localhost
|
|
|
|
* - xxx+unix:/// -> UNIX domain socket
|
|
|
|
* - xxx:/// -> UNIX domain socket
|
2012-07-17 13:48:04 +00:00
|
|
|
* - xxx+ssh:/// -> SSH connection (legacy)
|
|
|
|
* - xxx+libssh2:/// -> SSH connection (using libssh2)
|
2016-11-09 14:28:36 +00:00
|
|
|
* - xxx+libssh:/// -> SSH connection (using libssh)
|
2009-06-12 12:06:15 +00:00
|
|
|
*/
|
2007-07-04 03:59:13 +00:00
|
|
|
static int
|
2012-07-17 12:25:34 +00:00
|
|
|
doRemoteOpen(virConnectPtr conn,
|
|
|
|
struct private_data *priv,
|
2018-04-13 08:51:25 +00:00
|
|
|
const char *driver_str,
|
|
|
|
const char *transport_str,
|
2012-07-17 12:25:34 +00:00
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
2016-06-03 17:20:27 +00:00
|
|
|
virConfPtr conf,
|
2012-07-17 12:25:34 +00:00
|
|
|
unsigned int flags)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2009-06-12 12:06:15 +00:00
|
|
|
enum {
|
|
|
|
trans_tls,
|
|
|
|
trans_unix,
|
|
|
|
trans_ssh,
|
2012-07-17 13:48:04 +00:00
|
|
|
trans_libssh2,
|
2009-06-12 12:06:15 +00:00
|
|
|
trans_ext,
|
|
|
|
trans_tcp,
|
2016-11-09 14:28:36 +00:00
|
|
|
trans_libssh,
|
2009-06-12 12:06:15 +00:00
|
|
|
} transport;
|
2011-12-07 10:39:14 +00:00
|
|
|
#ifndef WIN32
|
2014-07-15 11:36:00 +00:00
|
|
|
char *daemonPath = NULL;
|
2011-12-07 10:39:14 +00:00
|
|
|
#endif
|
2016-06-06 14:41:01 +00:00
|
|
|
char *tls_priority = NULL;
|
2008-11-17 11:44:51 +00:00
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
/* We handle *ALL* URIs here. The caller has rejected any
|
2009-06-12 12:06:15 +00:00
|
|
|
* URIs we don't care about */
|
2008-11-17 11:44:51 +00:00
|
|
|
|
2009-06-12 12:06:15 +00:00
|
|
|
if (conn->uri) {
|
2018-04-09 15:33:22 +00:00
|
|
|
if (!transport_str) {
|
|
|
|
if (conn->uri->server)
|
|
|
|
transport = trans_tls;
|
|
|
|
else
|
|
|
|
transport = trans_unix;
|
|
|
|
} else {
|
|
|
|
if (STRCASEEQ(transport_str, "tls")) {
|
|
|
|
transport = trans_tls;
|
|
|
|
} else if (STRCASEEQ(transport_str, "unix")) {
|
|
|
|
if (conn->uri->server) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("using unix socket and remote "
|
|
|
|
"server '%s' is not supported."),
|
|
|
|
conn->uri->server);
|
2009-06-12 12:06:15 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2018-04-09 15:33:22 +00:00
|
|
|
} else {
|
|
|
|
transport = trans_unix;
|
2009-06-12 12:06:15 +00:00
|
|
|
}
|
2018-04-09 15:33:22 +00:00
|
|
|
} else if (STRCASEEQ(transport_str, "ssh")) {
|
|
|
|
transport = trans_ssh;
|
|
|
|
} else if (STRCASEEQ(transport_str, "libssh2")) {
|
|
|
|
transport = trans_libssh2;
|
|
|
|
} else if (STRCASEEQ(transport_str, "ext")) {
|
|
|
|
transport = trans_ext;
|
|
|
|
} else if (STRCASEEQ(transport_str, "tcp")) {
|
|
|
|
transport = trans_tcp;
|
|
|
|
} else if (STRCASEEQ(transport_str, "libssh")) {
|
|
|
|
transport = trans_libssh;
|
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("remote_open: transport in URL not recognised "
|
|
|
|
"(should be tls|unix|ssh|ext|tcp|libssh2)"));
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2009-06-12 12:06:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* No URI, then must be probing so use UNIX socket */
|
|
|
|
transport = trans_unix;
|
2007-07-04 03:59:13 +00:00
|
|
|
}
|
2007-06-26 23:48:46 +00:00
|
|
|
|
2013-10-09 10:44:50 +00:00
|
|
|
/*
|
|
|
|
* We don't want to be executing external programs in setuid mode,
|
|
|
|
* so this rules out 'ext' and 'ssh' transports. Exclude libssh
|
|
|
|
* and tls too, since we're not confident the libraries are safe
|
|
|
|
* for setuid usage. Just allow UNIX sockets, since that does
|
|
|
|
* not require any external libraries or command execution
|
|
|
|
*/
|
|
|
|
if (virIsSUID() &&
|
|
|
|
transport != trans_unix) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Only Unix socket URI transport is allowed in setuid mode"));
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
|
2010-04-07 15:12:02 +00:00
|
|
|
/* Local variables which we will initialize. These can
|
2007-06-26 11:42:46 +00:00
|
|
|
* get freed in the failed: path.
|
|
|
|
*/
|
2009-01-31 13:49:11 +00:00
|
|
|
char *name = NULL, *command = NULL, *sockname = NULL, *netcat = NULL;
|
|
|
|
char *port = NULL, *authtype = NULL, *username = NULL;
|
2011-11-04 20:10:54 +00:00
|
|
|
bool sanity = true, verify = true, tty ATTRIBUTE_UNUSED = true;
|
2012-07-17 13:48:04 +00:00
|
|
|
char *pkipath = NULL, *keyfile = NULL, *sshauth = NULL;
|
|
|
|
|
|
|
|
char *knownHostsVerify = NULL, *knownHosts = NULL;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2007-06-26 11:42:46 +00:00
|
|
|
/* Return code from this function, and the private data. */
|
|
|
|
int retcode = VIR_DRV_OPEN_ERROR;
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Remote server defaults to "localhost" if not specified. */
|
2008-11-17 11:44:51 +00:00
|
|
|
if (conn->uri && conn->uri->port != 0) {
|
2012-07-17 12:25:34 +00:00
|
|
|
if (virAsprintf(&port, "%d", conn->uri->port) < 0)
|
2013-07-04 10:14:34 +00:00
|
|
|
goto failed;
|
2007-06-11 11:43:41 +00:00
|
|
|
} else if (transport == trans_tls) {
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(port, LIBVIRTD_TLS_PORT) < 0)
|
|
|
|
goto failed;
|
2007-06-11 11:43:41 +00:00
|
|
|
} else if (transport == trans_tcp) {
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(port, LIBVIRTD_TCP_PORT) < 0)
|
|
|
|
goto failed;
|
2012-07-17 12:25:34 +00:00
|
|
|
} /* Port not used for unix, ext., default for ssh */
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(priv->hostname,
|
|
|
|
conn->uri && conn->uri->server ?
|
|
|
|
conn->uri->server : "localhost") < 0)
|
|
|
|
goto failed;
|
2012-07-17 12:25:34 +00:00
|
|
|
|
2013-05-03 12:47:37 +00:00
|
|
|
if (conn->uri && VIR_STRDUP(username, conn->uri->user) < 0)
|
|
|
|
goto failed;
|
2007-09-25 13:54:17 +00:00
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Get the variables from the query string.
|
|
|
|
* Then we need to reconstruct the query string (because
|
|
|
|
* feasibly it might contain variables needed by the real driver,
|
|
|
|
* although that won't be the case for now).
|
|
|
|
*/
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
if (conn->uri) {
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0; i < conn->uri->paramsCount; i++) {
|
2012-03-20 14:11:10 +00:00
|
|
|
virURIParamPtr var = &conn->uri->params[i];
|
2012-07-17 12:25:34 +00:00
|
|
|
EXTRACT_URI_ARG_STR("name", name);
|
|
|
|
EXTRACT_URI_ARG_STR("command", command);
|
|
|
|
EXTRACT_URI_ARG_STR("socket", sockname);
|
|
|
|
EXTRACT_URI_ARG_STR("auth", authtype);
|
2012-07-17 13:48:04 +00:00
|
|
|
EXTRACT_URI_ARG_STR("sshauth", sshauth);
|
2012-07-17 12:25:34 +00:00
|
|
|
EXTRACT_URI_ARG_STR("netcat", netcat);
|
|
|
|
EXTRACT_URI_ARG_STR("keyfile", keyfile);
|
|
|
|
EXTRACT_URI_ARG_STR("pkipath", pkipath);
|
2012-07-17 13:48:04 +00:00
|
|
|
EXTRACT_URI_ARG_STR("known_hosts", knownHosts);
|
|
|
|
EXTRACT_URI_ARG_STR("known_hosts_verify", knownHostsVerify);
|
2016-06-06 14:41:01 +00:00
|
|
|
EXTRACT_URI_ARG_STR("tls_priority", tls_priority);
|
2012-07-17 12:25:34 +00:00
|
|
|
|
|
|
|
EXTRACT_URI_ARG_BOOL("no_sanity", sanity);
|
|
|
|
EXTRACT_URI_ARG_BOOL("no_verify", verify);
|
|
|
|
EXTRACT_URI_ARG_BOOL("no_tty", tty);
|
|
|
|
|
|
|
|
if (STRCASEEQ(var->name, "authfile")) {
|
2012-03-20 11:11:10 +00:00
|
|
|
/* Strip this param, used by virauth.c */
|
|
|
|
var->ignore = 1;
|
2012-07-17 12:25:34 +00:00
|
|
|
continue;
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
}
|
2012-07-17 12:25:34 +00:00
|
|
|
|
|
|
|
VIR_DEBUG("passing through variable '%s' ('%s') to remote end",
|
|
|
|
var->name, var->value);
|
2008-11-17 11:44:51 +00:00
|
|
|
}
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
/* Construct the original name. */
|
|
|
|
if (!name) {
|
2009-06-12 12:06:15 +00:00
|
|
|
if (conn->uri->scheme &&
|
|
|
|
(STREQ(conn->uri->scheme, "remote") ||
|
|
|
|
STRPREFIX(conn->uri->scheme, "remote+"))) {
|
2008-11-28 12:03:20 +00:00
|
|
|
/* Allow remote serve to probe */
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(name, "") < 0)
|
|
|
|
goto failed;
|
2008-11-28 12:03:20 +00:00
|
|
|
} else {
|
2012-02-24 18:48:55 +00:00
|
|
|
virURI tmpuri = {
|
2018-04-13 08:51:25 +00:00
|
|
|
.scheme = (char *)driver_str,
|
2012-03-23 14:27:03 +00:00
|
|
|
.query = virURIFormatParams(conn->uri),
|
2008-11-28 12:03:20 +00:00
|
|
|
.path = conn->uri->path,
|
|
|
|
.fragment = conn->uri->fragment,
|
|
|
|
};
|
|
|
|
|
2012-02-24 18:48:55 +00:00
|
|
|
name = virURIFormat(&tmpuri);
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2008-11-28 12:03:20 +00:00
|
|
|
VIR_FREE(tmpuri.query);
|
|
|
|
|
Centralize error reporting for URI parsing/formatting problems
Move error reporting out of the callers, into virURIParse
and virURIFormat, to get consistency.
* include/libvirt/virterror.h, src/util/virterror.c: Add VIR_FROM_URI
* src/util/viruri.c, src/util/viruri.h: Add error reporting
* src/esx/esx_driver.c, src/libvirt.c, src/libxl/libxl_driver.c,
src/lxc/lxc_driver.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/qemu/qemu_migration.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xen/xen_driver.c,
src/xen/xend_internal.c, tests/viruritest.c: Remove error
reporting
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-03-20 12:16:54 +00:00
|
|
|
if (!name)
|
|
|
|
goto failed;
|
2008-11-28 12:03:20 +00:00
|
|
|
}
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
2008-11-17 11:44:51 +00:00
|
|
|
} else {
|
|
|
|
/* Probe URI server side */
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(name, "") < 0)
|
|
|
|
goto failed;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("proceeding with name = %s", name);
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
/* For ext transport, command is required. */
|
|
|
|
if (transport == trans_ext && !command) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("remote_open: for 'ext' transport, command is required"));
|
2008-11-17 11:44:51 +00:00
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Connecting with transport %d", transport);
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Connect to the remote service. */
|
|
|
|
switch (transport) {
|
|
|
|
case trans_tls:
|
2016-07-08 12:53:55 +00:00
|
|
|
if (conf && !tls_priority &&
|
|
|
|
virConfGetValueString(conf, "tls_priority", &tls_priority) < 0)
|
|
|
|
goto failed;
|
2016-06-03 17:20:27 +00:00
|
|
|
|
2013-01-08 21:02:05 +00:00
|
|
|
#ifdef WITH_GNUTLS
|
2010-12-01 16:46:36 +00:00
|
|
|
priv->tls = virNetTLSContextNewClientPath(pkipath,
|
|
|
|
geteuid() != 0 ? true : false,
|
2016-06-06 14:41:01 +00:00
|
|
|
tls_priority,
|
2011-07-21 10:13:11 +00:00
|
|
|
sanity, verify);
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!priv->tls)
|
|
|
|
goto failed;
|
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 14:12:03 +00:00
|
|
|
priv->is_secure = 1;
|
2018-04-02 11:09:28 +00:00
|
|
|
ATTRIBUTE_FALLTHROUGH;
|
2013-01-07 14:54:18 +00:00
|
|
|
#else
|
2016-06-06 14:41:01 +00:00
|
|
|
(void)tls_priority;
|
2013-01-07 14:54:18 +00:00
|
|
|
(void)sanity;
|
2013-07-01 19:21:57 +00:00
|
|
|
(void)verify;
|
2013-01-07 14:54:18 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("GNUTLS support not available in this build"));
|
|
|
|
goto failed;
|
|
|
|
#endif
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
case trans_tcp:
|
2015-05-21 14:51:28 +00:00
|
|
|
priv->client = virNetClientNewTCP(priv->hostname, port, AF_UNSPEC);
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!priv->client)
|
2007-06-11 11:43:41 +00:00
|
|
|
goto failed;
|
|
|
|
|
2013-01-08 21:02:05 +00:00
|
|
|
#ifdef WITH_GNUTLS
|
2010-12-01 16:46:36 +00:00
|
|
|
if (priv->tls) {
|
|
|
|
VIR_DEBUG("Starting TLS session");
|
|
|
|
if (virNetClientSetTLSSession(priv->client, priv->tls) < 0)
|
|
|
|
goto failed;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
2013-01-07 14:54:18 +00:00
|
|
|
#endif
|
2007-06-11 11:43:41 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2012-07-17 13:48:04 +00:00
|
|
|
case trans_libssh2:
|
2013-06-10 12:41:22 +00:00
|
|
|
if (!sockname) {
|
|
|
|
/* Right now we don't support default session connections */
|
2013-06-14 08:41:29 +00:00
|
|
|
if (STREQ_NULLABLE(conn->uri->path, "/session")) {
|
2013-06-10 12:41:22 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
|
_("Connecting to session instance without "
|
|
|
|
"socket path is not supported by the libssh2 "
|
|
|
|
"connection driver"));
|
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
2018-03-23 10:41:23 +00:00
|
|
|
if (!(sockname = remoteGetUNIXSocketRoot(flags)))
|
2013-06-10 12:41:22 +00:00
|
|
|
goto failed;
|
|
|
|
}
|
2012-07-17 13:48:04 +00:00
|
|
|
|
|
|
|
VIR_DEBUG("Starting LibSSH2 session");
|
|
|
|
|
|
|
|
priv->client = virNetClientNewLibSSH2(priv->hostname,
|
|
|
|
port,
|
2015-05-21 14:51:28 +00:00
|
|
|
AF_UNSPEC,
|
2012-07-17 13:48:04 +00:00
|
|
|
username,
|
|
|
|
keyfile,
|
|
|
|
knownHosts,
|
|
|
|
knownHostsVerify,
|
|
|
|
sshauth,
|
|
|
|
netcat,
|
|
|
|
sockname,
|
2013-07-09 14:46:32 +00:00
|
|
|
auth,
|
|
|
|
conn->uri);
|
2012-07-17 13:48:04 +00:00
|
|
|
if (!priv->client)
|
|
|
|
goto failed;
|
|
|
|
|
|
|
|
priv->is_secure = 1;
|
|
|
|
break;
|
|
|
|
|
2016-11-09 14:28:36 +00:00
|
|
|
case trans_libssh:
|
|
|
|
if (!sockname) {
|
|
|
|
/* Right now we don't support default session connections */
|
|
|
|
if (STREQ_NULLABLE(conn->uri->path, "/session")) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
|
_("Connecting to session instance without "
|
|
|
|
"socket path is not supported by the libssh "
|
|
|
|
"connection driver"));
|
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
2018-03-23 10:41:23 +00:00
|
|
|
if (!(sockname = remoteGetUNIXSocketRoot(flags)))
|
2016-11-09 14:28:36 +00:00
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_DEBUG("Starting libssh session");
|
|
|
|
|
|
|
|
priv->client = virNetClientNewLibssh(priv->hostname,
|
|
|
|
port,
|
|
|
|
AF_UNSPEC,
|
|
|
|
username,
|
|
|
|
keyfile,
|
|
|
|
knownHosts,
|
|
|
|
knownHostsVerify,
|
|
|
|
sshauth,
|
|
|
|
netcat,
|
|
|
|
sockname,
|
|
|
|
auth,
|
|
|
|
conn->uri);
|
|
|
|
if (!priv->client)
|
|
|
|
goto failed;
|
|
|
|
|
|
|
|
priv->is_secure = 1;
|
|
|
|
break;
|
|
|
|
|
2007-12-07 14:56:37 +00:00
|
|
|
#ifndef WIN32
|
2010-12-01 16:46:36 +00:00
|
|
|
case trans_unix:
|
2007-06-11 11:43:41 +00:00
|
|
|
if (!sockname) {
|
2018-03-23 10:41:23 +00:00
|
|
|
if (flags & VIR_DRV_OPEN_REMOTE_USER)
|
|
|
|
sockname = remoteGetUNIXSocketNonRoot();
|
|
|
|
else
|
|
|
|
sockname = remoteGetUNIXSocketRoot(flags);
|
|
|
|
if (!sockname)
|
|
|
|
goto failed;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2013-10-09 10:47:13 +00:00
|
|
|
if ((flags & VIR_DRV_OPEN_REMOTE_AUTOSTART) &&
|
2014-04-25 10:55:32 +00:00
|
|
|
!(daemonPath = virFileFindResourceFull("libvirtd",
|
|
|
|
NULL, NULL,
|
2018-03-22 14:53:55 +00:00
|
|
|
abs_topbuilddir "/src",
|
2014-04-25 10:55:32 +00:00
|
|
|
SBINDIR,
|
|
|
|
"LIBVIRTD_PATH")))
|
2011-12-06 21:46:22 +00:00
|
|
|
goto failed;
|
2014-04-25 10:55:32 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!(priv->client = virNetClientNewUNIX(sockname,
|
|
|
|
flags & VIR_DRV_OPEN_REMOTE_AUTOSTART,
|
2011-12-06 21:46:22 +00:00
|
|
|
daemonPath)))
|
2009-08-03 12:37:44 +00:00
|
|
|
goto failed;
|
2007-06-11 11:43:41 +00: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 14:12:03 +00:00
|
|
|
priv->is_secure = 1;
|
2007-06-11 11:43:41 +00:00
|
|
|
break;
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
case trans_ssh:
|
2013-05-03 12:47:37 +00:00
|
|
|
if (!command && VIR_STRDUP(command, "ssh") < 0)
|
|
|
|
goto failed;
|
2007-11-14 16:29:08 +00:00
|
|
|
|
2013-06-10 12:41:22 +00:00
|
|
|
if (!sockname) {
|
|
|
|
/* Right now we don't support default session connections */
|
2013-06-14 08:41:29 +00:00
|
|
|
if (STREQ_NULLABLE(conn->uri->path, "/session")) {
|
2013-06-10 12:41:22 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
|
_("Connecting to session instance without "
|
|
|
|
"socket path is not supported by the ssh "
|
|
|
|
"connection driver"));
|
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
2018-03-23 10:41:23 +00:00
|
|
|
if (!(sockname = remoteGetUNIXSocketRoot(flags)))
|
2013-06-10 12:41:22 +00:00
|
|
|
goto failed;
|
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
|
|
|
|
if (!(priv->client = virNetClientNewSSH(priv->hostname,
|
|
|
|
port,
|
|
|
|
command,
|
|
|
|
username,
|
2011-07-21 10:13:11 +00:00
|
|
|
!tty,
|
|
|
|
!verify,
|
2010-12-01 16:46:36 +00:00
|
|
|
netcat ? netcat : "nc",
|
2011-07-19 17:52:21 +00:00
|
|
|
keyfile,
|
2010-12-01 16:46:36 +00:00
|
|
|
sockname)))
|
|
|
|
goto failed;
|
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 14:12:03 +00:00
|
|
|
|
|
|
|
priv->is_secure = 1;
|
2010-12-01 16:46:36 +00:00
|
|
|
break;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
|
|
|
case trans_ext: {
|
2010-12-01 16:46:36 +00:00
|
|
|
char const *cmd_argv[] = { command, NULL };
|
|
|
|
if (!(priv->client = virNetClientNewExternal(cmd_argv)))
|
2007-06-11 11:43:41 +00:00
|
|
|
goto failed;
|
|
|
|
|
2011-07-20 22:53:31 +00:00
|
|
|
/* Do not set 'is_secure' flag since we can't guarantee
|
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 14:12:03 +00:00
|
|
|
* an external program is secure, and this flag must be
|
|
|
|
* pessimistic */
|
2010-12-01 16:46:36 +00:00
|
|
|
} break;
|
|
|
|
|
2007-12-07 14:56:37 +00:00
|
|
|
#else /* WIN32 */
|
|
|
|
|
|
|
|
case trans_unix:
|
|
|
|
case trans_ssh:
|
|
|
|
case trans_ext:
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("transport methods unix, ssh and ext are not supported "
|
|
|
|
"under Windows"));
|
2009-01-15 20:13:12 +00:00
|
|
|
goto failed;
|
2007-12-07 14:56:37 +00:00
|
|
|
|
|
|
|
#endif /* WIN32 */
|
2007-06-11 11:43:41 +00:00
|
|
|
} /* switch (transport) */
|
|
|
|
|
2012-07-19 14:58:38 +00:00
|
|
|
|
2012-08-07 11:09:51 +00:00
|
|
|
if (virNetClientRegisterAsyncIO(priv->client) < 0) {
|
|
|
|
VIR_DEBUG("Failed to add event watch, disabling events and support for"
|
|
|
|
" keepalive messages");
|
|
|
|
virResetLastError();
|
|
|
|
} else {
|
|
|
|
if (virNetClientRegisterKeepAlive(priv->client) < 0)
|
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
2016-03-01 14:17:38 +00:00
|
|
|
if (!(priv->closeCallback = virNewConnectCloseCallbackData()))
|
|
|
|
goto failed;
|
2017-04-27 06:47:19 +00:00
|
|
|
/* ref on behalf of netclient */
|
2016-03-01 14:17:38 +00:00
|
|
|
virObjectRef(priv->closeCallback);
|
2012-07-19 14:58:38 +00:00
|
|
|
virNetClientSetCloseCallback(priv->client,
|
|
|
|
remoteClientCloseFunc,
|
2016-03-01 14:17:38 +00:00
|
|
|
priv->closeCallback, virObjectFreeCallback);
|
2012-07-19 14:58:38 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM,
|
|
|
|
REMOTE_PROTOCOL_VERSION,
|
2014-01-04 13:14:33 +00:00
|
|
|
remoteEvents,
|
|
|
|
ARRAY_CARDINALITY(remoteEvents),
|
2010-12-01 16:46:36 +00:00
|
|
|
conn)))
|
2009-01-20 16:36:34 +00:00
|
|
|
goto failed;
|
2012-12-21 14:20:04 +00:00
|
|
|
if (!(priv->lxcProgram = virNetClientProgramNew(LXC_PROGRAM,
|
|
|
|
LXC_PROTOCOL_VERSION,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL)))
|
|
|
|
goto failed;
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!(priv->qemuProgram = virNetClientProgramNew(QEMU_PROGRAM,
|
|
|
|
QEMU_PROTOCOL_VERSION,
|
2014-01-29 22:30:44 +00:00
|
|
|
qemuEvents,
|
|
|
|
ARRAY_CARDINALITY(qemuEvents),
|
|
|
|
conn)))
|
2010-02-11 22:39:38 +00:00
|
|
|
goto failed;
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetClientAddProgram(priv->client, priv->remoteProgram) < 0 ||
|
2012-12-21 14:20:04 +00:00
|
|
|
virNetClientAddProgram(priv->client, priv->lxcProgram) < 0 ||
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientAddProgram(priv->client, priv->qemuProgram) < 0)
|
2009-01-20 16:36:34 +00:00
|
|
|
goto failed;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
/* Try and authenticate with server */
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Trying authentication");
|
|
|
|
if (remoteAuthenticate(conn, priv, auth, authtype) == -1)
|
2007-12-05 15:24:15 +00:00
|
|
|
goto failed;
|
|
|
|
|
2011-09-22 12:59:06 +00:00
|
|
|
if (virNetClientKeepAliveIsSupported(priv->client)) {
|
2016-02-17 12:15:01 +00:00
|
|
|
priv->serverKeepAlive = remoteConnectSupportsFeatureUnlocked(conn,
|
|
|
|
priv, VIR_DRV_FEATURE_PROGRAM_KEEPALIVE);
|
|
|
|
if (!priv->serverKeepAlive) {
|
2011-09-22 12:59:06 +00:00
|
|
|
VIR_INFO("Disabling keepalive protocol since it is not supported"
|
|
|
|
" by the server");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Finally we can call the remote side's open function. */
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
{
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_open_args args = { &name, flags };
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Trying to open URI %s", name);
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_OPEN,
|
|
|
|
(xdrproc_t) xdr_remote_connect_open_args, (char *) &args,
|
2012-07-17 12:25:34 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
goto failed;
|
|
|
|
}
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
/* Now try and find out what URI the daemon used */
|
|
|
|
if (conn->uri == NULL) {
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_get_uri_ret uriret;
|
2008-11-17 11:44:51 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Trying to query remote URI");
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&uriret, 0, sizeof(uriret));
|
|
|
|
if (call(conn, priv, 0,
|
2013-04-18 11:07:23 +00:00
|
|
|
REMOTE_PROC_CONNECT_GET_URI,
|
2012-07-17 12:25:34 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
2013-04-18 11:07:23 +00:00
|
|
|
(xdrproc_t) xdr_remote_connect_get_uri_ret, (char *) &uriret) < 0)
|
2008-11-17 11:44:51 +00:00
|
|
|
goto failed;
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Auto-probed URI is %s", uriret.uri);
|
2012-02-24 18:48:55 +00:00
|
|
|
conn->uri = virURIParse(uriret.uri);
|
2008-11-17 11:44:51 +00:00
|
|
|
VIR_FREE(uriret.uri);
|
Centralize error reporting for URI parsing/formatting problems
Move error reporting out of the callers, into virURIParse
and virURIFormat, to get consistency.
* include/libvirt/virterror.h, src/util/virterror.c: Add VIR_FROM_URI
* src/util/viruri.c, src/util/viruri.h: Add error reporting
* src/esx/esx_driver.c, src/libvirt.c, src/libxl/libxl_driver.c,
src/lxc/lxc_driver.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/qemu/qemu_migration.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xen/xen_driver.c,
src/xen/xend_internal.c, tests/viruritest.c: Remove error
reporting
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-03-20 12:16:54 +00:00
|
|
|
if (!conn->uri)
|
2008-11-17 11:44:51 +00:00
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
|
2014-01-08 04:00:54 +00:00
|
|
|
/* Set up events */
|
2014-01-04 13:14:33 +00:00
|
|
|
if (!(priv->eventState = virObjectEventStateNew()))
|
2011-05-13 15:00:10 +00:00
|
|
|
goto failed;
|
2014-01-08 04:00:54 +00:00
|
|
|
|
2016-02-17 12:15:01 +00:00
|
|
|
priv->serverEventFilter = remoteConnectSupportsFeatureUnlocked(conn,
|
|
|
|
priv, VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK);
|
|
|
|
if (!priv->serverEventFilter) {
|
|
|
|
VIR_INFO("Avoiding server event filtering since it is not "
|
|
|
|
"supported by the server");
|
2014-01-08 04:00:54 +00:00
|
|
|
}
|
2011-05-13 15:00:10 +00:00
|
|
|
|
2016-02-17 12:15:02 +00:00
|
|
|
priv->serverCloseCallback = remoteConnectSupportsFeatureUnlocked(conn,
|
|
|
|
priv, VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK);
|
|
|
|
if (!priv->serverCloseCallback) {
|
|
|
|
VIR_INFO("Close callback registering isn't supported "
|
|
|
|
"by the remote side.");
|
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Successful. */
|
|
|
|
retcode = VIR_DRV_OPEN_SUCCESS;
|
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
cleanup:
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Free up the URL and strings. */
|
2009-01-31 13:49:11 +00:00
|
|
|
VIR_FREE(name);
|
|
|
|
VIR_FREE(command);
|
|
|
|
VIR_FREE(sockname);
|
|
|
|
VIR_FREE(authtype);
|
|
|
|
VIR_FREE(netcat);
|
2012-07-17 13:48:04 +00:00
|
|
|
VIR_FREE(sshauth);
|
2011-07-19 17:52:21 +00:00
|
|
|
VIR_FREE(keyfile);
|
2009-01-31 13:49:11 +00:00
|
|
|
VIR_FREE(username);
|
|
|
|
VIR_FREE(port);
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
VIR_FREE(pkipath);
|
2016-06-06 14:41:01 +00:00
|
|
|
VIR_FREE(tls_priority);
|
2012-07-17 13:48:04 +00:00
|
|
|
VIR_FREE(knownHostsVerify);
|
|
|
|
VIR_FREE(knownHosts);
|
2014-07-07 06:18:44 +00:00
|
|
|
#ifndef WIN32
|
|
|
|
VIR_FREE(daemonPath);
|
|
|
|
#endif
|
2007-06-11 11:43:41 +00:00
|
|
|
|
|
|
|
return retcode;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
failed:
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(priv->remoteProgram);
|
2012-12-21 14:20:04 +00:00
|
|
|
virObjectUnref(priv->lxcProgram);
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(priv->qemuProgram);
|
2011-07-19 13:13:32 +00:00
|
|
|
virNetClientClose(priv->client);
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(priv->client);
|
2010-12-01 16:46:36 +00:00
|
|
|
priv->client = NULL;
|
2016-03-01 14:17:38 +00:00
|
|
|
virObjectUnref(priv->closeCallback);
|
|
|
|
priv->closeCallback = NULL;
|
2013-11-22 16:24:32 +00:00
|
|
|
#ifdef WITH_GNUTLS
|
|
|
|
virObjectUnref(priv->tls);
|
|
|
|
priv->tls = NULL;
|
|
|
|
#endif
|
2009-03-17 11:00:56 +00:00
|
|
|
|
2009-01-31 13:49:11 +00:00
|
|
|
VIR_FREE(priv->hostname);
|
2007-12-05 15:24:15 +00:00
|
|
|
goto cleanup;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
2012-07-17 12:25:34 +00:00
|
|
|
#undef EXTRACT_URI_ARG_STR
|
|
|
|
#undef EXTRACT_URI_ARG_BOOL
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-01-29 23:01:37 +00:00
|
|
|
static struct private_data *
|
2010-04-03 12:55:42 +00:00
|
|
|
remoteAllocPrivateData(void)
|
2007-07-04 03:59:13 +00:00
|
|
|
{
|
2007-10-27 01:23:28 +00:00
|
|
|
struct private_data *priv;
|
2013-07-04 10:14:34 +00:00
|
|
|
if (VIR_ALLOC(priv) < 0)
|
2009-01-29 23:01:37 +00:00
|
|
|
return NULL;
|
2007-07-04 03:59:13 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
if (virMutexInit(&priv->lock) < 0) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot initialize mutex"));
|
2009-01-20 11:41:24 +00:00
|
|
|
VIR_FREE(priv);
|
2009-01-29 23:01:37 +00:00
|
|
|
return NULL;
|
2009-01-20 11:41:24 +00:00
|
|
|
}
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses = 1;
|
2009-01-29 23:01:37 +00:00
|
|
|
|
|
|
|
return priv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDrvOpenStatus
|
2013-04-23 12:50:18 +00:00
|
|
|
remoteConnectOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth,
|
2016-06-03 17:20:27 +00:00
|
|
|
virConfPtr conf,
|
2013-04-23 12:50:18 +00:00
|
|
|
unsigned int flags)
|
2009-01-29 23:01:37 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv;
|
2018-04-13 08:51:25 +00:00
|
|
|
int ret = VIR_DRV_OPEN_ERROR;
|
|
|
|
int rflags = 0;
|
2013-10-09 10:18:15 +00:00
|
|
|
const char *autostart = virGetEnvBlockSUID("LIBVIRT_AUTOSTART");
|
2018-04-13 08:51:25 +00:00
|
|
|
char *driver = NULL;
|
|
|
|
char *transport = NULL;
|
|
|
|
|
|
|
|
if (conn->uri &&
|
|
|
|
remoteSplitURIScheme(conn->uri, &driver, &transport) < 0)
|
|
|
|
goto cleanup;
|
2009-01-29 23:01:37 +00:00
|
|
|
|
2018-04-13 08:51:25 +00:00
|
|
|
if (inside_daemon && (!conn->uri || !conn->uri->server)) {
|
|
|
|
ret = VIR_DRV_OPEN_DECLINED;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-01-29 23:01:37 +00:00
|
|
|
|
2010-04-03 12:55:42 +00:00
|
|
|
if (!(priv = remoteAllocPrivateData()))
|
2018-04-13 08:51:25 +00:00
|
|
|
goto cleanup;
|
2009-01-20 11:41:24 +00:00
|
|
|
|
2007-12-05 18:28:05 +00:00
|
|
|
if (flags & VIR_CONNECT_RO)
|
2007-07-04 03:59:13 +00:00
|
|
|
rflags |= VIR_DRV_OPEN_REMOTE_RO;
|
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
/*
|
|
|
|
* If no servername is given, and no +XXX
|
|
|
|
* transport is listed, or transport is unix,
|
|
|
|
* and path is /session, and uid is unprivileged
|
|
|
|
* then auto-spawn a daemon.
|
|
|
|
*/
|
|
|
|
if (conn->uri &&
|
|
|
|
!conn->uri->server &&
|
|
|
|
conn->uri->path &&
|
2008-11-20 14:33:59 +00:00
|
|
|
conn->uri->scheme &&
|
2018-04-13 08:51:25 +00:00
|
|
|
(transport == NULL || STREQ(transport, "unix")) &&
|
2009-07-10 12:14:23 +00:00
|
|
|
(STREQ(conn->uri->path, "/session") ||
|
|
|
|
STRPREFIX(conn->uri->scheme, "test+")) &&
|
2013-10-09 11:13:45 +00:00
|
|
|
geteuid() > 0) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Auto-spawn user daemon instance");
|
2008-11-17 11:44:51 +00:00
|
|
|
rflags |= VIR_DRV_OPEN_REMOTE_USER;
|
2013-10-09 10:47:13 +00:00
|
|
|
if (!virIsSUID() &&
|
|
|
|
(!autostart ||
|
|
|
|
STRNEQ(autostart, "0")))
|
2009-07-06 17:43:21 +00:00
|
|
|
rflags |= VIR_DRV_OPEN_REMOTE_AUTOSTART;
|
2008-11-17 11:44:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-01-22 17:49:41 +00:00
|
|
|
* If URI is NULL, then do a UNIX connection possibly auto-spawning
|
2018-03-28 15:11:53 +00:00
|
|
|
* unprivileged server and probe remote server for URI.
|
2008-11-17 11:44:51 +00:00
|
|
|
*/
|
|
|
|
if (!conn->uri) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Auto-probe remote URI");
|
2013-10-09 11:13:45 +00:00
|
|
|
if (geteuid() > 0) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Auto-spawn user daemon instance");
|
2008-11-17 11:44:51 +00:00
|
|
|
rflags |= VIR_DRV_OPEN_REMOTE_USER;
|
2013-10-09 10:47:13 +00:00
|
|
|
if (!virIsSUID() &&
|
|
|
|
(!autostart ||
|
|
|
|
STRNEQ(autostart, "0")))
|
2009-07-06 17:43:21 +00:00
|
|
|
rflags |= VIR_DRV_OPEN_REMOTE_AUTOSTART;
|
2008-11-17 11:44:51 +00:00
|
|
|
}
|
2008-03-27 09:34:06 +00:00
|
|
|
}
|
2007-07-04 03:59:13 +00:00
|
|
|
|
2018-04-13 08:51:25 +00:00
|
|
|
ret = doRemoteOpen(conn, priv, driver, transport, auth, conf, rflags);
|
2007-07-04 03:59:13 +00:00
|
|
|
if (ret != VIR_DRV_OPEN_SUCCESS) {
|
|
|
|
conn->privateData = NULL;
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(priv);
|
2007-07-04 03:59:13 +00:00
|
|
|
} else {
|
|
|
|
conn->privateData = priv;
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2007-07-04 03:59:13 +00:00
|
|
|
}
|
2018-04-13 08:51:25 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(driver);
|
|
|
|
VIR_FREE(transport);
|
2007-07-04 03:59:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2007-07-12 15:17:08 +00:00
|
|
|
|
|
|
|
static int
|
2012-07-17 12:25:34 +00:00
|
|
|
doRemoteClose(virConnectPtr conn, struct private_data *priv)
|
2007-07-12 15:17:08 +00:00
|
|
|
{
|
2011-07-08 11:41:06 +00:00
|
|
|
int ret = 0;
|
|
|
|
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_CLOSE,
|
2012-07-17 12:25:34 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
2011-07-08 11:41:06 +00:00
|
|
|
ret = -1;
|
2007-07-12 15:17:08 +00:00
|
|
|
|
2013-01-08 21:02:05 +00:00
|
|
|
#ifdef WITH_GNUTLS
|
2012-07-11 13:35:48 +00:00
|
|
|
virObjectUnref(priv->tls);
|
2010-12-01 16:46:36 +00:00
|
|
|
priv->tls = NULL;
|
2013-01-07 14:54:18 +00:00
|
|
|
#endif
|
2013-03-29 17:21:19 +00:00
|
|
|
|
2012-12-05 14:48:43 +00:00
|
|
|
virNetClientSetCloseCallback(priv->client,
|
|
|
|
NULL,
|
2016-03-01 14:17:38 +00:00
|
|
|
priv->closeCallback, virObjectFreeCallback);
|
2013-03-29 17:21:19 +00:00
|
|
|
|
2011-07-19 13:13:32 +00:00
|
|
|
virNetClientClose(priv->client);
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(priv->client);
|
2010-12-01 16:46:36 +00:00
|
|
|
priv->client = NULL;
|
2016-03-01 14:17:38 +00:00
|
|
|
virObjectUnref(priv->closeCallback);
|
|
|
|
priv->closeCallback = NULL;
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(priv->remoteProgram);
|
2012-12-21 14:20:04 +00:00
|
|
|
virObjectUnref(priv->lxcProgram);
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(priv->qemuProgram);
|
2012-12-21 14:20:04 +00:00
|
|
|
priv->remoteProgram = priv->qemuProgram = priv->lxcProgram = NULL;
|
2010-12-01 16:46:36 +00:00
|
|
|
|
|
|
|
/* Free hostname copy */
|
|
|
|
VIR_FREE(priv->hostname);
|
|
|
|
|
|
|
|
/* See comment for remoteType. */
|
|
|
|
VIR_FREE(priv->type);
|
|
|
|
|
2016-10-11 07:48:36 +00:00
|
|
|
virObjectUnref(priv->eventState);
|
2014-01-04 13:14:33 +00:00
|
|
|
priv->eventState = NULL;
|
2007-07-12 15:17:08 +00:00
|
|
|
|
2011-07-08 11:41:06 +00:00
|
|
|
return ret;
|
2010-05-07 12:42:11 +00:00
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
static int
|
2013-04-23 12:50:18 +00:00
|
|
|
remoteConnectClose(virConnectPtr conn)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
int ret = 0;
|
|
|
|
struct private_data *priv = conn->privateData;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
|
|
|
if (!priv->localUses) {
|
|
|
|
ret = doRemoteClose(conn, priv);
|
|
|
|
conn->privateData = NULL;
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
virMutexDestroy(&priv->lock);
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(priv);
|
2010-05-07 12:42:11 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
if (priv)
|
|
|
|
remoteDriverUnlock(priv);
|
2010-05-07 12:42:11 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2007-07-12 15:17:08 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
/* Unfortunately this function is defined to return a static string.
|
|
|
|
* Since the remote end always answers with the same type (for a
|
|
|
|
* single connection anyway) we cache the type in the connection's
|
|
|
|
* private data, and free it when we close the connection.
|
|
|
|
*
|
|
|
|
* See also:
|
|
|
|
* http://www.redhat.com/archives/libvir-list/2007-February/msg00096.html
|
|
|
|
*/
|
|
|
|
static const char *
|
2013-04-18 11:07:23 +00:00
|
|
|
remoteConnectGetType(virConnectPtr conn)
|
2010-12-01 16:46:36 +00:00
|
|
|
{
|
|
|
|
char *rv = NULL;
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_get_type_ret ret;
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverLock(priv);
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
/* Cached? */
|
|
|
|
if (priv->type) {
|
|
|
|
rv = priv->type;
|
|
|
|
goto done;
|
|
|
|
}
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_TYPE,
|
2012-07-17 12:25:34 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
2013-04-18 11:07:23 +00:00
|
|
|
(xdrproc_t) xdr_remote_connect_get_type_ret, (char *) &ret) == -1)
|
2010-12-01 16:46:36 +00:00
|
|
|
goto done;
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
/* Stash. */
|
|
|
|
rv = priv->type = ret.type;
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2013-04-18 11:07:23 +00:00
|
|
|
static int remoteConnectIsSecure(virConnectPtr conn)
|
2010-12-01 16:46:36 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_is_secure_ret ret;
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverLock(priv);
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_IS_SECURE,
|
2012-07-17 12:25:34 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
2013-04-18 11:07:23 +00:00
|
|
|
(xdrproc_t) xdr_remote_connect_is_secure_ret, (char *) &ret) == -1)
|
2010-12-01 16:46:36 +00:00
|
|
|
goto done;
|
2011-05-06 15:00:53 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
/* We claim to be secure, if the remote driver
|
|
|
|
* transport itself is secure, and the remote
|
|
|
|
* HV connection is secure
|
|
|
|
*
|
|
|
|
* ie, we don't want to claim to be secure if the
|
|
|
|
* remote driver is used to connect to a XenD
|
|
|
|
* driver using unencrypted HTTP:/// access
|
|
|
|
*/
|
|
|
|
rv = priv->is_secure && ret.secure ? 1 : 0;
|
2011-05-06 15:00:53 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2013-04-18 11:07:23 +00:00
|
|
|
static int remoteConnectIsEncrypted(virConnectPtr conn)
|
2010-12-01 16:46:36 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
2013-05-24 10:14:02 +00:00
|
|
|
bool encrypted;
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_is_secure_ret ret;
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverLock(priv);
|
remote: Add extra parameter pkipath for URI
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki/libvirt, as long
as one of client cerficate, client key, CA certificate can
not be found, use default global location (LIBVIRT_CACERT,
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY, see
src/remote/remote_driver.h)
Example of use:
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file
or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c: adds support for the new pkipath URI parameter
2011-01-27 08:34:54 +00:00
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_IS_SECURE,
|
2012-07-17 12:25:34 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
2013-04-18 11:07:23 +00:00
|
|
|
(xdrproc_t) xdr_remote_connect_is_secure_ret, (char *) &ret) == -1)
|
2010-12-01 16:46:36 +00:00
|
|
|
goto done;
|
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 14:12:03 +00:00
|
|
|
|
2013-05-24 10:14:02 +00:00
|
|
|
encrypted = virNetClientIsEncrypted(priv->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 14:12:03 +00:00
|
|
|
|
|
|
|
/* We claim to be encrypted, if the remote driver
|
|
|
|
* transport itself is encrypted, and the remote
|
|
|
|
* HV connection is secure.
|
|
|
|
*
|
|
|
|
* Yes, we really don't check the remote 'encrypted'
|
|
|
|
* option, since it will almost always be false,
|
|
|
|
* even if secure (eg UNIX sockets).
|
|
|
|
*/
|
|
|
|
rv = encrypted && ret.secure ? 1 : 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
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 14:12:03 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-06-07 01:01:12 +00:00
|
|
|
static int
|
2012-07-17 12:25:34 +00:00
|
|
|
remoteNodeGetCPUStats(virConnectPtr conn,
|
|
|
|
int cpuNum,
|
|
|
|
virNodeCPUStatsPtr params, int *nparams,
|
|
|
|
unsigned int flags)
|
2011-06-07 01:01:12 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_get_cpu_stats_args args;
|
|
|
|
remote_node_get_cpu_stats_ret ret;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-06-07 01:01:12 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.nparams = *nparams;
|
|
|
|
args.cpuNum = cpuNum;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_CPU_STATS,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_cpu_stats_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_cpu_stats_ret,
|
|
|
|
(char *) &ret) == -1)
|
2011-06-07 01:01:12 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Check the length of the returned list carefully. */
|
|
|
|
if (ret.params.params_len > REMOTE_NODE_CPU_STATS_MAX ||
|
|
|
|
ret.params.params_len > *nparams) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("remoteNodeGetCPUStats: "
|
|
|
|
"returned number of stats exceeds limit"));
|
2011-06-07 01:01:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* Handle the case when the caller does not know the number of stats
|
|
|
|
* and is asking for the number of stats supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*nparams = ret.params.params_len;
|
|
|
|
|
|
|
|
/* Deserialise the result. */
|
|
|
|
for (i = 0; i < *nparams; ++i) {
|
|
|
|
if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Stats %s too big for destination"),
|
|
|
|
ret.params.params_val[i].field);
|
2011-06-07 01:01:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
params[i].value = ret.params.params_val[i].value;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-07-17 12:25:34 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_cpu_stats_ret, (char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-06-07 01:01:12 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-06-07 01:05:40 +00:00
|
|
|
static int
|
2012-07-17 12:25:34 +00:00
|
|
|
remoteNodeGetMemoryStats(virConnectPtr conn,
|
|
|
|
int cellNum,
|
|
|
|
virNodeMemoryStatsPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
2011-06-07 01:05:40 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_get_memory_stats_args args;
|
|
|
|
remote_node_get_memory_stats_ret ret;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-06-07 01:05:40 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.nparams = *nparams;
|
|
|
|
args.cellNum = cellNum;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2012-07-17 12:25:34 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_MEMORY_STATS,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_memory_stats_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_memory_stats_ret, (char *) &ret) == -1)
|
2011-06-07 01:05:40 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Check the length of the returned list carefully. */
|
|
|
|
if (ret.params.params_len > REMOTE_NODE_MEMORY_STATS_MAX ||
|
|
|
|
ret.params.params_len > *nparams) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("remoteNodeGetMemoryStats: "
|
|
|
|
"returned number of stats exceeds limit"));
|
2011-06-07 01:05:40 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* Handle the case when the caller does not know the number of stats
|
|
|
|
* and is asking for the number of stats supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*nparams = ret.params.params_len;
|
|
|
|
|
|
|
|
/* Deserialise the result. */
|
|
|
|
for (i = 0; i < *nparams; ++i) {
|
|
|
|
if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Stats %s too big for destination"),
|
|
|
|
ret.params.params_val[i].field);
|
2011-06-07 01:05:40 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
params[i].value = ret.params.params_val[i].value;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-07-17 12:25:34 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_memory_stats_ret, (char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-06-07 01:05:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2008-05-22 15:20:25 +00:00
|
|
|
static int
|
|
|
|
remoteNodeGetCellsFreeMemory(virConnectPtr conn,
|
2012-07-17 12:25:34 +00:00
|
|
|
unsigned long long *freeMems,
|
|
|
|
int startCell,
|
|
|
|
int maxCells)
|
2008-05-22 15:20:25 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2008-05-22 15:20:25 +00:00
|
|
|
remote_node_get_cells_free_memory_args args;
|
|
|
|
remote_node_get_cells_free_memory_ret ret;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2008-05-22 15:20:25 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2008-05-22 15:20:25 +00:00
|
|
|
if (maxCells > REMOTE_NODE_MAX_CELLS) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("too many NUMA cells: %d > %d"),
|
|
|
|
maxCells, REMOTE_NODE_MAX_CELLS);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-05-22 15:20:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
args.startCell = startCell;
|
2011-05-21 07:52:19 +00:00
|
|
|
args.maxcells = maxCells;
|
2008-05-22 15:20:25 +00:00
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_CELLS_FREE_MEMORY,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_cells_free_memory_args, (char *)&args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_cells_free_memory_ret, (char *)&ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-05-22 15:20:25 +00:00
|
|
|
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0; i < ret.cells.cells_len; i++)
|
2011-05-21 07:52:19 +00:00
|
|
|
freeMems[i] = ret.cells.cells_val[i];
|
2008-05-22 15:20:25 +00:00
|
|
|
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_cells_free_memory_ret, (char *) &ret);
|
|
|
|
|
2011-05-21 07:52:19 +00:00
|
|
|
rv = ret.cells.cells_len;
|
2009-01-15 20:07:10 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2008-05-22 15:20:25 +00:00
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
static int
|
2013-04-18 11:07:23 +00:00
|
|
|
remoteConnectListDomains(virConnectPtr conn, int *ids, int maxids)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_list_domains_args args;
|
|
|
|
remote_connect_list_domains_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2013-08-19 13:23:31 +00:00
|
|
|
if (maxids > REMOTE_DOMAIN_LIST_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
2013-08-19 13:23:31 +00:00
|
|
|
_("Too many domains '%d' for limit '%d'"),
|
|
|
|
maxids, REMOTE_DOMAIN_LIST_MAX);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
args.maxids = maxids;
|
|
|
|
|
2012-07-17 12:25:34 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_LIST_DOMAINS,
|
|
|
|
(xdrproc_t) xdr_remote_connect_list_domains_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_list_domains_ret, (char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
|
|
|
if (ret.ids.ids_len > maxids) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
2013-08-19 13:23:31 +00:00
|
|
|
_("Too many domains '%d' for limit '%d'"),
|
2012-07-18 13:35:21 +00:00
|
|
|
ret.ids.ids_len, maxids);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto cleanup;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < ret.ids.ids_len; ++i)
|
|
|
|
ids[i] = ret.ids.ids_val[i];
|
|
|
|
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = ret.ids.ids_len;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2013-04-18 11:07:23 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_connect_list_domains_ret, (char *) &ret);
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2012-01-31 06:42:31 +00:00
|
|
|
static int
|
|
|
|
remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val,
|
|
|
|
u_int ret_errors_len,
|
|
|
|
int limit,
|
|
|
|
virDomainDiskErrorPtr errors,
|
|
|
|
int maxerrors)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
|
|
|
size_t j;
|
2012-01-31 06:42:31 +00:00
|
|
|
|
|
|
|
if (ret_errors_len > limit || ret_errors_len > maxerrors) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("returned number of disk errors exceeds limit"));
|
2012-01-31 06:42:31 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < ret_errors_len; i++) {
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(errors[i].disk, ret_errors_val[i].disk) < 0)
|
2012-01-31 06:42:31 +00:00
|
|
|
goto error;
|
|
|
|
errors[i].error = ret_errors_val[i].error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2012-01-31 06:42:31 +00:00
|
|
|
for (j = 0; j < i; j++)
|
|
|
|
VIR_FREE(errors[i].disk);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-09-05 08:20:03 +00:00
|
|
|
static int
|
|
|
|
remoteDomainBlockStatsFlags(virDomainPtr domain,
|
|
|
|
const char *path,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_block_stats_flags_args args;
|
|
|
|
remote_domain_block_stats_flags_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-09-05 08:20:03 +00:00
|
|
|
args.nparams = *nparams;
|
|
|
|
args.path = (char *) path;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_block_stats_flags_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_block_stats_flags_ret, (char *) &ret) == -1)
|
2011-09-05 08:20:03 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Check the length of the returned list carefully. */
|
|
|
|
if (ret.params.params_len > REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX ||
|
|
|
|
ret.params.params_len > *nparams) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("remoteDomainBlockStatsFlags: "
|
|
|
|
"returned number of stats exceeds limit"));
|
2011-09-05 08:20:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of stats
|
|
|
|
* and is asking for the number of stats supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*nparams = ret.params.params_len;
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
/* Deserialize the result. */
|
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
2016-10-04 11:05:20 +00:00
|
|
|
REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX,
|
2016-01-28 16:27:42 +00:00
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2011-09-05 08:20:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_block_stats_flags_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-09-05 08:20:03 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-10-12 17:23:04 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetMemoryParameters(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params, int *nparams,
|
|
|
|
unsigned int flags)
|
2010-10-12 17:23:04 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_memory_parameters_args args;
|
|
|
|
remote_domain_get_memory_parameters_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2010-10-12 17:23:04 +00:00
|
|
|
args.nparams = *nparams;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_memory_parameters_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_memory_parameters_ret, (char *) &ret) == -1)
|
2010-10-12 17:23:04 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of parameters
|
|
|
|
* and is asking for the number of parameters supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
|
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2011-05-17 20:58:40 +00:00
|
|
|
goto cleanup;
|
2010-10-12 17:23:04 +00:00
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_memory_parameters_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2010-10-12 17:23:04 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-12-20 08:35:01 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetNumaParameters(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params, int *nparams,
|
|
|
|
unsigned int flags)
|
2011-12-20 08:35:01 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_numa_parameters_args args;
|
|
|
|
remote_domain_get_numa_parameters_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-12-20 08:35:01 +00:00
|
|
|
args.nparams = *nparams;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_NUMA_PARAMETERS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_numa_parameters_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_numa_parameters_ret, (char *) &ret) == -1)
|
2011-12-20 08:35:01 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of parameters
|
|
|
|
* and is asking for the number of parameters supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_NUMA_PARAMETERS_MAX,
|
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2011-12-20 08:35:01 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_numa_parameters_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-12-20 08:35:01 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2018-06-08 14:41:00 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetLaunchSecurityInfo(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr *params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_launch_security_info_args args;
|
|
|
|
remote_domain_get_launch_security_info_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_LAUNCH_SECURITY_INFO,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_launch_security_info_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_launch_security_info_ret, (char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX,
|
|
|
|
params,
|
|
|
|
nparams) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_launch_security_info_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-03-28 13:30:27 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetPerfEvents(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr *params,
|
2016-03-30 15:40:50 +00:00
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
2016-03-28 13:30:27 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_perf_events_args args;
|
|
|
|
remote_domain_get_perf_events_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2016-03-30 15:40:50 +00:00
|
|
|
args.flags = flags;
|
2016-03-28 13:30:27 +00:00
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_PERF_EVENTS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_perf_events_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_perf_events_ret, (char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
2016-03-30 15:40:10 +00:00
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_PERF_EVENTS_MAX,
|
|
|
|
params,
|
|
|
|
nparams) < 0)
|
2016-03-28 13:30:27 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_perf_events_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-02-22 05:34:28 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetBlkioParameters(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params, int *nparams,
|
|
|
|
unsigned int flags)
|
2011-02-22 05:34:28 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_blkio_parameters_args args;
|
|
|
|
remote_domain_get_blkio_parameters_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-02-22 05:34:28 +00:00
|
|
|
args.nparams = *nparams;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1)
|
2011-02-22 05:34:28 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of parameters
|
|
|
|
* and is asking for the number of parameters supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX,
|
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2011-05-17 20:58:40 +00:00
|
|
|
goto cleanup;
|
2011-02-22 05:34:28 +00:00
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-02-22 05:34:28 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-06-24 09:00:22 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetVcpuPinInfo(virDomainPtr domain,
|
|
|
|
int ncpumaps,
|
|
|
|
unsigned char *cpumaps,
|
|
|
|
int maplen,
|
|
|
|
unsigned int flags)
|
2011-06-24 09:00:22 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-06-24 23:09:46 +00:00
|
|
|
remote_domain_get_vcpu_pin_info_args args;
|
|
|
|
remote_domain_get_vcpu_pin_info_ret ret;
|
2011-06-24 09:00:22 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (ncpumaps > REMOTE_VCPUINFO_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("vCPU count exceeds maximum: %d > %d"),
|
|
|
|
ncpumaps, REMOTE_VCPUINFO_MAX);
|
2011-06-24 09:00:22 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (INT_MULTIPLY_OVERFLOW(ncpumaps, maplen) ||
|
|
|
|
ncpumaps * maplen > REMOTE_CPUMAPS_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("vCPU map buffer length exceeds maximum: %d > %d"),
|
|
|
|
ncpumaps * maplen, REMOTE_CPUMAPS_MAX);
|
2011-06-24 09:00:22 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-06-24 09:00:22 +00:00
|
|
|
args.ncpumaps = ncpumaps;
|
|
|
|
args.maplen = maplen;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2011-06-24 09:00:22 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_ret,
|
|
|
|
(char *) &ret) == -1)
|
2011-06-24 09:00:22 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.num > ncpumaps) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("host reports too many vCPUs: %d > %d"),
|
|
|
|
ret.num, ncpumaps);
|
2011-06-24 09:00:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.cpumaps.cpumaps_len > ncpumaps * maplen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("host reports map buffer length exceeds maximum: %d > %d"),
|
|
|
|
ret.cpumaps.cpumaps_len, ncpumaps * maplen);
|
2011-06-24 09:00:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(cpumaps, 0, ncpumaps * maplen);
|
2011-06-24 09:00:22 +00:00
|
|
|
|
|
|
|
for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
|
|
|
|
cpumaps[i] = ret.cpumaps.cpumaps_val[i];
|
|
|
|
|
|
|
|
rv = ret.num;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_ret, (char *) &ret);
|
2011-06-24 09:00:22 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-06-24 09:00:22 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-08-21 09:18:38 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainPinEmulator(virDomainPtr dom,
|
|
|
|
unsigned char *cpumap,
|
|
|
|
int cpumaplen,
|
|
|
|
unsigned int flags)
|
2012-08-21 09:18:38 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
remote_domain_pin_emulator_args args;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (cpumaplen > REMOTE_CPUMAP_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("%s length greater than maximum: %d > %d"),
|
|
|
|
"cpumap", cpumaplen, REMOTE_CPUMAP_MAX);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.cpumap.cpumap_val = (char *)cpumap;
|
|
|
|
args.cpumap.cpumap_len = cpumaplen;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_PIN_EMULATOR,
|
|
|
|
(xdrproc_t) xdr_remote_domain_pin_emulator_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-08-21 09:18:38 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetEmulatorPinInfo(virDomainPtr domain,
|
|
|
|
unsigned char *cpumaps,
|
|
|
|
int maplen,
|
|
|
|
unsigned int flags)
|
2012-08-21 09:18:38 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-08-21 09:18:38 +00:00
|
|
|
remote_domain_get_emulator_pin_info_args args;
|
|
|
|
remote_domain_get_emulator_pin_info_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
/* There is only one cpumap for all emulator threads */
|
|
|
|
if (maplen > REMOTE_CPUMAPS_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("vCPU map buffer length exceeds maximum: %d > %d"),
|
|
|
|
maplen, REMOTE_CPUMAPS_MAX);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.maplen = maplen;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_EMULATOR_PIN_INFO,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_emulator_pin_info_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_emulator_pin_info_ret,
|
|
|
|
(char *) &ret) == -1)
|
2012-08-21 09:18:38 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.cpumaps.cpumaps_len > maplen) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("host reports map buffer length exceeds maximum: %d > %d"),
|
|
|
|
ret.cpumaps.cpumaps_len, maplen);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(cpumaps, 0, maplen);
|
|
|
|
|
|
|
|
for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
|
|
|
|
cpumaps[i] = ret.cpumaps.cpumaps_val[i];
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_emulator_pin_info_ret,
|
|
|
|
(char *) &ret);
|
2012-08-21 09:18:38 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-08-21 09:18:38 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetVcpus(virDomainPtr domain,
|
|
|
|
virVcpuInfoPtr info,
|
|
|
|
int maxinfo,
|
|
|
|
unsigned char *cpumaps,
|
|
|
|
int maplen)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2007-06-11 11:43:41 +00:00
|
|
|
remote_domain_get_vcpus_args args;
|
|
|
|
remote_domain_get_vcpus_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
if (maxinfo > REMOTE_VCPUINFO_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("vCPU count exceeds maximum: %d > %d"),
|
|
|
|
maxinfo, REMOTE_VCPUINFO_MAX);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
2011-06-24 18:16:05 +00:00
|
|
|
if (INT_MULTIPLY_OVERFLOW(maxinfo, maplen) ||
|
|
|
|
maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("vCPU map buffer length exceeds maximum: %d > %d"),
|
|
|
|
maxinfo * maplen, REMOTE_CPUMAPS_MAX);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2007-06-11 11:43:41 +00:00
|
|
|
args.maxinfo = maxinfo;
|
|
|
|
args.maplen = maplen;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_vcpus_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
|
|
|
if (ret.info.info_len > maxinfo) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("host reports too many vCPUs: %d > %d"),
|
|
|
|
ret.info.info_len, maxinfo);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto cleanup;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
2007-06-25 08:23:10 +00:00
|
|
|
if (ret.cpumaps.cpumaps_len > maxinfo * maplen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("host reports map buffer length exceeds maximum: %d > %d"),
|
|
|
|
ret.cpumaps.cpumaps_len, maxinfo * maplen);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto cleanup;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(info, 0, sizeof(virVcpuInfo) * maxinfo);
|
|
|
|
memset(cpumaps, 0, maxinfo * maplen);
|
2007-06-25 08:23:10 +00:00
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
for (i = 0; i < ret.info.info_len; ++i) {
|
|
|
|
info[i].number = ret.info.info_val[i].number;
|
|
|
|
info[i].state = ret.info.info_val[i].state;
|
|
|
|
info[i].cpuTime = ret.info.info_val[i].cpu_time;
|
|
|
|
info[i].cpu = ret.info.info_val[i].cpu;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
|
|
|
|
cpumaps[i] = ret.cpumaps.cpumaps_val[i];
|
|
|
|
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = ret.info.info_len;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret);
|
2009-01-15 20:07:10 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2015-02-09 23:59:23 +00:00
|
|
|
static int
|
2015-03-25 16:02:26 +00:00
|
|
|
remoteDomainGetIOThreadInfo(virDomainPtr dom,
|
|
|
|
virDomainIOThreadInfoPtr **info,
|
|
|
|
unsigned int flags)
|
2015-02-09 23:59:23 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
size_t i;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
2015-03-25 16:02:26 +00:00
|
|
|
remote_domain_get_iothread_info_args args;
|
|
|
|
remote_domain_get_iothread_info_ret ret;
|
2015-02-09 23:59:23 +00:00
|
|
|
remote_domain_iothread_info *src;
|
|
|
|
virDomainIOThreadInfoPtr *info_ret = NULL;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2015-03-25 16:02:26 +00:00
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_IOTHREAD_INFO,
|
|
|
|
(xdrproc_t)xdr_remote_domain_get_iothread_info_args,
|
2015-02-09 23:59:23 +00:00
|
|
|
(char *)&args,
|
2015-03-25 16:02:26 +00:00
|
|
|
(xdrproc_t)xdr_remote_domain_get_iothread_info_ret,
|
2015-02-09 23:59:23 +00:00
|
|
|
(char *)&ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
2015-03-25 16:02:26 +00:00
|
|
|
if (ret.info.info_len > REMOTE_IOTHREAD_INFO_MAX) {
|
2015-02-09 23:59:23 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Too many IOThreads in info: %d for limit %d"),
|
2015-03-25 16:02:26 +00:00
|
|
|
ret.info.info_len, REMOTE_IOTHREAD_INFO_MAX);
|
2015-02-09 23:59:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info) {
|
|
|
|
if (!ret.info.info_len) {
|
|
|
|
*info = NULL;
|
|
|
|
rv = ret.ret;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(info_ret, ret.info.info_len) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.info.info_len; i++) {
|
|
|
|
src = &ret.info.info_val[i];
|
|
|
|
|
|
|
|
if (VIR_ALLOC(info_ret[i]) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
info_ret[i]->iothread_id = src->iothread_id;
|
|
|
|
if (VIR_ALLOC_N(info_ret[i]->cpumap, src->cpumap.cpumap_len) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
memcpy(info_ret[i]->cpumap, src->cpumap.cpumap_val,
|
|
|
|
src->cpumap.cpumap_len);
|
|
|
|
info_ret[i]->cpumaplen = src->cpumap.cpumap_len;
|
|
|
|
}
|
|
|
|
*info = info_ret;
|
|
|
|
info_ret = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (info_ret) {
|
|
|
|
for (i = 0; i < ret.info.info_len; i++)
|
2015-03-25 15:47:49 +00:00
|
|
|
virDomainIOThreadInfoFree(info_ret[i]);
|
2015-02-09 23:59:23 +00:00
|
|
|
VIR_FREE(info_ret);
|
|
|
|
}
|
2015-03-25 16:02:26 +00:00
|
|
|
xdr_free((xdrproc_t)xdr_remote_domain_get_iothread_info_ret,
|
2015-02-09 23:59:23 +00:00
|
|
|
(char *) &ret);
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-03-03 09:27:02 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
|
2009-03-03 09:27:02 +00:00
|
|
|
{
|
|
|
|
remote_domain_get_security_label_args args;
|
|
|
|
remote_domain_get_security_label_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
2009-03-03 19:33:34 +00:00
|
|
|
int rv = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
2009-03-03 09:27:02 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
memset(seclabel, 0, sizeof(*seclabel));
|
2009-06-25 09:37:22 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) == -1) {
|
2009-03-03 19:33:34 +00:00
|
|
|
goto done;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.label.label_val != NULL) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if (strlen(ret.label.label_val) >= sizeof(seclabel->label)) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, _("security label exceeds maximum: %zu"),
|
|
|
|
sizeof(seclabel->label) - 1);
|
2011-07-11 05:14:45 +00:00
|
|
|
goto cleanup;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
2012-10-17 09:23:12 +00:00
|
|
|
strcpy(seclabel->label, ret.label.label_val);
|
2009-03-03 09:27:02 +00:00
|
|
|
seclabel->enforcing = ret.enforcing;
|
|
|
|
}
|
|
|
|
|
2009-03-03 19:33:34 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2011-07-11 05:14:45 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-03-03 19:33:34 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
2012-08-15 22:10:39 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetSecurityLabelList(virDomainPtr domain, virSecurityLabelPtr* seclabels)
|
2012-08-15 22:10:39 +00:00
|
|
|
{
|
|
|
|
remote_domain_get_security_label_list_args args;
|
|
|
|
remote_domain_get_security_label_list_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int rv = -1;
|
2012-08-15 22:10:39 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2012-08-15 22:10:39 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_security_label_list_args, (char *)&args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_security_label_list_ret, (char *)&ret) == -1) {
|
2012-08-15 22:10:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(*seclabels, ret.labels.labels_len) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.labels.labels_len; i++) {
|
|
|
|
remote_domain_get_security_label_ret *cur = &ret.labels.labels_val[i];
|
|
|
|
if (cur->label.label_val != NULL) {
|
|
|
|
if (strlen(cur->label.label_val) >= sizeof((*seclabels)->label)) {
|
|
|
|
virReportError(VIR_ERR_RPC, _("security label exceeds maximum: %zd"),
|
|
|
|
sizeof((*seclabels)->label) - 1);
|
|
|
|
VIR_FREE(*seclabels);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
strcpy((*seclabels)[i].label, cur->label.label_val);
|
|
|
|
(*seclabels)[i].enforcing = cur->enforcing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rv = ret.ret;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-08-15 22:10:39 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_security_label_list_ret, (char *)&ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-08-15 22:10:39 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-04-26 14:47:22 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetState(virDomainPtr domain,
|
|
|
|
int *state,
|
|
|
|
int *reason,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_state_args args;
|
|
|
|
remote_domain_get_state_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-03-29 09:52:04 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2011-04-26 14:47:22 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_STATE,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_state_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_state_ret, (char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
*state = ret.state;
|
|
|
|
if (reason)
|
|
|
|
*reason = ret.reason;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-04-26 14:47:22 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-03-03 09:27:02 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
|
2009-03-03 09:27:02 +00:00
|
|
|
{
|
|
|
|
remote_node_get_security_model_ret ret;
|
|
|
|
struct private_data *priv = conn->privateData;
|
2009-03-03 19:33:34 +00:00
|
|
|
int rv = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
2009-03-03 09:27:02 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
memset(secmodel, 0, sizeof(*secmodel));
|
2009-06-25 09:37:22 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL,
|
|
|
|
(xdrproc_t) xdr_void, NULL,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) == -1) {
|
2009-03-03 19:33:34 +00:00
|
|
|
goto done;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.model.model_val != NULL) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if (strlen(ret.model.model_val) >= sizeof(secmodel->model)) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, _("security model exceeds maximum: %zu"),
|
|
|
|
sizeof(secmodel->model) - 1);
|
2011-07-11 05:14:45 +00:00
|
|
|
goto cleanup;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
2012-10-17 09:23:12 +00:00
|
|
|
strcpy(secmodel->model, ret.model.model_val);
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.doi.doi_val != NULL) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if (strlen(ret.doi.doi_val) >= sizeof(secmodel->doi)) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, _("security doi exceeds maximum: %zu"),
|
|
|
|
sizeof(secmodel->doi) - 1);
|
2011-07-11 05:14:45 +00:00
|
|
|
goto cleanup;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
2012-10-17 09:23:12 +00:00
|
|
|
strcpy(secmodel->doi, ret.doi.doi_val);
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
2009-03-03 19:33:34 +00:00
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2011-07-11 05:14:45 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-03-03 19:33:34 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
2009-03-03 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
2007-08-21 09:31:12 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainMigratePrepare(virConnectPtr dconn,
|
|
|
|
char **cookie, int *cookielen,
|
|
|
|
const char *uri_in, char **uri_out,
|
|
|
|
unsigned long flags, const char *dname,
|
|
|
|
unsigned long resource)
|
2007-08-21 09:31:12 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2007-08-21 09:31:12 +00:00
|
|
|
remote_domain_migrate_prepare_args args;
|
|
|
|
remote_domain_migrate_prepare_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = dconn->privateData;
|
2007-08-21 09:31:12 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2007-08-21 09:31:12 +00:00
|
|
|
args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
|
|
|
|
args.flags = flags;
|
|
|
|
args.dname = dname == NULL ? NULL : (char **) &dname;
|
|
|
|
args.resource = resource;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare_ret, (char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-08-21 09:31:12 +00:00
|
|
|
|
|
|
|
if (ret.cookie.cookie_len > 0) {
|
|
|
|
*cookie = ret.cookie.cookie_val; /* Caller frees. */
|
|
|
|
*cookielen = ret.cookie.cookie_len;
|
|
|
|
}
|
|
|
|
if (ret.uri_out)
|
|
|
|
*uri_out = *ret.uri_out; /* Caller frees. */
|
|
|
|
|
2012-03-16 11:37:05 +00:00
|
|
|
VIR_FREE(ret.uri_out);
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2007-08-21 09:31:12 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 08:42:47 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainMigratePrepare2(virConnectPtr dconn,
|
|
|
|
char **cookie, int *cookielen,
|
|
|
|
const char *uri_in, char **uri_out,
|
|
|
|
unsigned long flags, const char *dname,
|
|
|
|
unsigned long resource,
|
|
|
|
const char *dom_xml)
|
2008-11-14 08:42:47 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2008-11-14 08:42:47 +00:00
|
|
|
remote_domain_migrate_prepare2_args args;
|
|
|
|
remote_domain_migrate_prepare2_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = dconn->privateData;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2008-11-14 08:42:47 +00:00
|
|
|
args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
|
|
|
|
args.flags = flags;
|
|
|
|
args.dname = dname == NULL ? NULL : (char **) &dname;
|
|
|
|
args.resource = resource;
|
|
|
|
args.dom_xml = (char *) dom_xml;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE2,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare2_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare2_ret, (char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-11-14 08:42:47 +00:00
|
|
|
|
|
|
|
if (ret.cookie.cookie_len > 0) {
|
2010-05-12 14:52:06 +00:00
|
|
|
if (!cookie || !cookielen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookie or cookielen"));
|
2010-05-12 14:52:06 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-11-14 08:42:47 +00:00
|
|
|
*cookie = ret.cookie.cookie_val; /* Caller frees. */
|
|
|
|
*cookielen = ret.cookie.cookie_len;
|
|
|
|
}
|
2010-05-12 14:52:06 +00:00
|
|
|
if (ret.uri_out) {
|
|
|
|
if (!uri_out) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores uri_out"));
|
2010-05-12 14:52:06 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2008-11-14 08:42:47 +00:00
|
|
|
*uri_out = *ret.uri_out; /* Caller frees. */
|
2010-05-12 14:52:06 +00:00
|
|
|
}
|
2008-11-14 08:42:47 +00:00
|
|
|
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-03-16 11:37:05 +00:00
|
|
|
VIR_FREE(ret.uri_out);
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2010-05-12 14:52:06 +00:00
|
|
|
if (ret.cookie.cookie_len)
|
|
|
|
VIR_FREE(ret.cookie.cookie_val);
|
|
|
|
if (ret.uri_out)
|
|
|
|
VIR_FREE(*ret.uri_out);
|
|
|
|
goto done;
|
2008-11-14 08:42:47 +00:00
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainCreate(virDomainPtr domain)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2007-06-11 11:43:41 +00:00
|
|
|
remote_domain_create_args args;
|
2009-04-19 15:21:54 +00:00
|
|
|
remote_domain_lookup_by_uuid_args args2;
|
|
|
|
remote_domain_lookup_by_uuid_ret ret2;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_CREATE,
|
|
|
|
(xdrproc_t) xdr_remote_domain_create_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-04-19 15:21:54 +00:00
|
|
|
/* Need to do a lookup figure out ID of newly started guest, because
|
|
|
|
* bug in design of REMOTE_PROC_DOMAIN_CREATE means we aren't getting
|
|
|
|
* it returned.
|
|
|
|
*/
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(args2.uuid, domain->uuid, VIR_UUID_BUFLEN);
|
|
|
|
memset(&ret2, 0, sizeof(ret2));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID,
|
|
|
|
(xdrproc_t) xdr_remote_domain_lookup_by_uuid_args, (char *) &args2,
|
|
|
|
(xdrproc_t) xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2) == -1)
|
2009-04-19 15:21:54 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
domain->id = ret2.dom.id;
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2);
|
2009-04-19 15:21:54 +00:00
|
|
|
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2011-04-23 10:53:57 +00:00
|
|
|
static char *
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetSchedulerType(virDomainPtr domain, int *nparams)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2011-04-23 10:53:57 +00:00
|
|
|
char *rv = NULL;
|
|
|
|
remote_domain_get_scheduler_type_args args;
|
|
|
|
remote_domain_get_scheduler_type_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2007-06-11 11:43:41 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_scheduler_type_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_scheduler_type_ret, (char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2007-06-22 13:16:10 +00:00
|
|
|
|
|
|
|
if (nparams) *nparams = ret.nparams;
|
|
|
|
|
|
|
|
/* Caller frees this. */
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = ret.type;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2007-06-22 13:16:10 +00:00
|
|
|
}
|
|
|
|
|
2009-12-20 12:43:19 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainMemoryStats(virDomainPtr domain,
|
2014-09-16 13:19:47 +00:00
|
|
|
virDomainMemoryStatPtr stats,
|
2012-10-17 09:23:12 +00:00
|
|
|
unsigned int nr_stats,
|
|
|
|
unsigned int flags)
|
2009-12-20 12:43:19 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_memory_stats_args args;
|
|
|
|
remote_domain_memory_stats_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-12-20 12:43:19 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2009-12-20 12:43:19 +00:00
|
|
|
if (nr_stats > REMOTE_DOMAIN_MEMORY_STATS_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("too many memory stats requested: %d > %d"), nr_stats,
|
|
|
|
REMOTE_DOMAIN_MEMORY_STATS_MAX);
|
2009-12-20 12:43:19 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
args.maxStats = nr_stats;
|
libvirt: do not mix internal flags into public API
There were two API in driver.c that were silently masking flags
bits prior to calling out to the drivers, and several others
that were explicitly masking flags bits. This is not
forward-compatible - if we ever have that many flags in the
future, then talking to an old server that masks out the
flags would be indistinguishable from talking to a new server
that can honor the flag. In general, libvirt.c should forward
_all_ flags on to drivers, and only the drivers should reject
unknown flags.
In the case of virDrvSecretGetValue, the solution is to separate
the internal driver callback function to have two parameters
instead of one, with only one parameter affected by the public
API. In the case of virDomainGetXMLDesc, it turns out that
no one was ever mixing VIR_DOMAIN_XML_INTERNAL_STATUS with
the dumpxml path in the first place; that internal flag was
only used in saving and restoring state files, which happened
to be in functions internal to a single file, so there is no
mixing of the internal flag with a public flags argument.
Additionally, virDomainMemoryStats passed a flags argument
over RPC, but not to the driver.
* src/driver.h (VIR_DOMAIN_XML_FLAGS_MASK)
(VIR_SECRET_GET_VALUE_FLAGS_MASK): Delete.
(virDrvSecretGetValue): Separate out internal flags.
(virDrvDomainMemoryStats): Provide missing flags argument.
* src/driver.c (verify): Drop unused check.
* src/conf/domain_conf.h (virDomainObjParseFile): Delete
declaration.
(virDomainXMLInternalFlags): Move...
* src/conf/domain_conf.c: ...here. Delete redundant include.
(virDomainObjParseFile): Make static.
* src/libvirt.c (virDomainGetXMLDesc, virSecretGetValue): Update
clients.
(virDomainMemoryPeek, virInterfaceGetXMLDesc)
(virDomainMemoryStats, virDomainBlockPeek, virNetworkGetXMLDesc)
(virStoragePoolGetXMLDesc, virStorageVolGetXMLDesc)
(virNodeNumOfDevices, virNodeListDevices, virNWFilterGetXMLDesc):
Don't mask unknown flags.
* src/interface/netcf_driver.c (interfaceGetXMLDesc): Reject
unknown flags.
* src/secret/secret_driver.c (secretGetValue): Update clients.
* src/remote/remote_driver.c (remoteSecretGetValue)
(remoteDomainMemoryStats): Likewise.
* src/qemu/qemu_process.c (qemuProcessGetVolumeQcowPassphrase):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainMemoryStats): Likewise.
* daemon/remote.c (remoteDispatchDomainMemoryStats): Likewise.
2011-07-13 21:31:56 +00:00
|
|
|
args.flags = flags;
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2009-12-20 12:43:19 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_STATS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_memory_stats_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_memory_stats_ret,
|
|
|
|
(char *) &ret) == -1)
|
2009-12-20 12:43:19 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.stats.stats_len; i++) {
|
|
|
|
stats[i].tag = ret.stats.stats_val[i].tag;
|
|
|
|
stats[i].val = ret.stats.stats_val[i].val;
|
|
|
|
}
|
|
|
|
rv = ret.stats.stats_len;
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_memory_stats_ret, (char *) &ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-12-20 12:43:19 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2008-06-05 21:12:26 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainBlockPeek(virDomainPtr domain,
|
|
|
|
const char *path,
|
|
|
|
unsigned long long offset,
|
|
|
|
size_t size,
|
|
|
|
void *buffer,
|
|
|
|
unsigned int flags)
|
2008-06-05 21:12:26 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2008-06-05 21:12:26 +00:00
|
|
|
remote_domain_block_peek_args args;
|
|
|
|
remote_domain_block_peek_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
2008-06-05 21:12:26 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2008-06-05 21:12:26 +00:00
|
|
|
if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("block peek request too large for remote protocol, %zi > %d"),
|
|
|
|
size, REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2008-06-05 21:12:26 +00:00
|
|
|
args.path = (char *) path;
|
|
|
|
args.offset = offset;
|
|
|
|
args.size = size;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_PEEK,
|
|
|
|
(xdrproc_t) xdr_remote_domain_block_peek_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_block_peek_ret,
|
|
|
|
(char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-06-05 21:12:26 +00:00
|
|
|
|
|
|
|
if (ret.buffer.buffer_len != size) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("returned buffer is not same size as requested"));
|
2009-01-15 20:07:10 +00:00
|
|
|
goto cleanup;
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(buffer, ret.buffer.buffer_val, size);
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2009-12-09 23:00:50 +00:00
|
|
|
VIR_FREE(ret.buffer.buffer_val);
|
2008-06-05 21:12:26 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2008-06-05 21:12:26 +00:00
|
|
|
}
|
|
|
|
|
2008-06-10 10:43:28 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainMemoryPeek(virDomainPtr domain,
|
|
|
|
unsigned long long offset,
|
|
|
|
size_t size,
|
|
|
|
void *buffer,
|
|
|
|
unsigned int flags)
|
2008-06-10 10:43:28 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2008-06-10 10:43:28 +00:00
|
|
|
remote_domain_memory_peek_args args;
|
|
|
|
remote_domain_memory_peek_ret ret;
|
2009-01-15 20:04:44 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
2008-06-10 10:43:28 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2008-06-10 10:43:28 +00:00
|
|
|
if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("memory peek request too large for remote protocol, %zi > %d"),
|
|
|
|
size, REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX);
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2008-06-10 10:43:28 +00:00
|
|
|
args.offset = offset;
|
|
|
|
args.size = size;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_PEEK,
|
|
|
|
(xdrproc_t) xdr_remote_domain_memory_peek_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_memory_peek_ret,
|
|
|
|
(char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-06-10 10:43:28 +00:00
|
|
|
|
|
|
|
if (ret.buffer.buffer_len != size) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("returned buffer is not same size as requested"));
|
2009-01-15 20:07:10 +00:00
|
|
|
goto cleanup;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(buffer, ret.buffer.buffer_val, size);
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2009-12-09 23:00:50 +00:00
|
|
|
VIR_FREE(ret.buffer.buffer_val);
|
2008-06-10 10:43:28 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2008-06-10 10:43:28 +00:00
|
|
|
}
|
|
|
|
|
2011-07-22 05:31:16 +00:00
|
|
|
static int remoteDomainGetBlockJobInfo(virDomainPtr domain,
|
|
|
|
const char *path,
|
|
|
|
virDomainBlockJobInfoPtr info,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_block_job_info_args args;
|
|
|
|
remote_domain_get_block_job_info_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.path = (char *)path;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO,
|
|
|
|
(xdrproc_t)xdr_remote_domain_get_block_job_info_args,
|
|
|
|
(char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_domain_get_block_job_info_ret,
|
|
|
|
(char *)&ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.found) {
|
|
|
|
info->type = ret.type;
|
|
|
|
info->bandwidth = ret.bandwidth;
|
|
|
|
info->cur = ret.cur;
|
|
|
|
info->end = ret.end;
|
|
|
|
rv = 1;
|
|
|
|
} else {
|
|
|
|
rv = 0;
|
|
|
|
}
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-07-22 05:31:16 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-11-15 09:02:44 +00:00
|
|
|
static int remoteDomainGetBlockIoTune(virDomainPtr domain,
|
|
|
|
const char *disk,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_block_io_tune_args args;
|
|
|
|
remote_domain_get_block_io_tune_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.disk = disk ? (char **)&disk : NULL;
|
|
|
|
args.nparams = *nparams;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_IO_TUNE,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_block_io_tune_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_block_io_tune_ret,
|
|
|
|
(char *) &ret) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of parameters
|
|
|
|
* and is asking for the number of parameters supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
2016-10-04 11:05:20 +00:00
|
|
|
REMOTE_DOMAIN_BLOCK_IO_TUNE_PARAMETERS_MAX,
|
2016-01-28 16:27:42 +00:00
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2011-11-15 09:02:44 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_block_io_tune_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-11-15 09:02:44 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-01-28 06:21:31 +00:00
|
|
|
static int remoteDomainGetCPUStats(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
unsigned int nparams,
|
|
|
|
int start_cpu,
|
|
|
|
unsigned int ncpus,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
remote_domain_get_cpu_stats_args args;
|
|
|
|
remote_domain_get_cpu_stats_ret ret;
|
|
|
|
int rv = -1;
|
|
|
|
int cpu;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (nparams > REMOTE_NODE_CPU_STATS_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("nparams count exceeds maximum: %u > %u"),
|
|
|
|
nparams, REMOTE_NODE_CPU_STATS_MAX);
|
2012-01-28 06:21:31 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (ncpus > REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("ncpus count exceeds maximum: %u > %u"),
|
|
|
|
ncpus, REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX);
|
2012-01-28 06:21:31 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.nparams = nparams;
|
|
|
|
args.start_cpu = start_cpu;
|
|
|
|
args.ncpus = ncpus;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_CPU_STATS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_cpu_stats_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Check the length of the returned list carefully. */
|
|
|
|
if (ret.params.params_len > nparams * ncpus ||
|
|
|
|
(ret.params.params_len &&
|
rpc: allow truncated return for virDomainGetCPUStats
The RPC code assumed that the array returned by the driver would be
fully populated; that is, ncpus on entry resulted in ncpus * return
value on exit. However, while we don't support holes in the middle
of ncpus, we do want to permit the case of ncpus on entry being
longer than the array returned by the driver (that is, it should be
safe for the caller to pass ncpus=128 on entry, and the driver will
stop populating the array when it hits max_id).
Additionally, a successful return implies that the caller will then
use virTypedParamArrayClear on the entire array; for this to not
free uninitialized memory, the driver must ensure that all skipped
entries are explicitly zeroed (the RPC driver did this, but not
the qemu driver).
There are now three cases:
server 0.9.10 and client 0.9.10 or newer: No impact - there were no
hypervisor drivers that supported cpu stats
server 0.9.11 or newer and client 0.9.10: if the client calls with
ncpus beyond the max, then the rpc call will fail on the client side
and disconnect the client, but the server is no worse for the wear
server 0.9.11 or newer and client 0.9.11: the server can return a
truncated array and the client will do just fine
I reproduced the problem by using a host with 2 CPUs, and doing:
virsh cpu-stats $dom --start 1 --count 2
* daemon/remote.c (remoteDispatchDomainGetCPUStats): Allow driver
to omit tail of array.
* src/remote/remote_driver.c (remoteDomainGetCPUStats):
Accommodate driver that omits tail of array.
* src/libvirt.c (virDomainGetCPUStats): Document this.
* src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Clear all
unpopulated entries.
2012-03-07 04:36:53 +00:00
|
|
|
((ret.params.params_len % ret.nparams) || ret.nparams > nparams))) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_RPC, "%s",
|
|
|
|
_("remoteDomainGetCPUStats: "
|
|
|
|
"returned number of stats exceeds limit"));
|
2012-01-28 06:21:31 +00:00
|
|
|
memset(params, 0, sizeof(*params) * nparams * ncpus);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of stats
|
|
|
|
* and is asking for the number of stats supported
|
|
|
|
*/
|
|
|
|
if (nparams == 0) {
|
|
|
|
rv = ret.nparams;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The remote side did not send back any zero entries, so we have
|
rpc: allow truncated return for virDomainGetCPUStats
The RPC code assumed that the array returned by the driver would be
fully populated; that is, ncpus on entry resulted in ncpus * return
value on exit. However, while we don't support holes in the middle
of ncpus, we do want to permit the case of ncpus on entry being
longer than the array returned by the driver (that is, it should be
safe for the caller to pass ncpus=128 on entry, and the driver will
stop populating the array when it hits max_id).
Additionally, a successful return implies that the caller will then
use virTypedParamArrayClear on the entire array; for this to not
free uninitialized memory, the driver must ensure that all skipped
entries are explicitly zeroed (the RPC driver did this, but not
the qemu driver).
There are now three cases:
server 0.9.10 and client 0.9.10 or newer: No impact - there were no
hypervisor drivers that supported cpu stats
server 0.9.11 or newer and client 0.9.10: if the client calls with
ncpus beyond the max, then the rpc call will fail on the client side
and disconnect the client, but the server is no worse for the wear
server 0.9.11 or newer and client 0.9.11: the server can return a
truncated array and the client will do just fine
I reproduced the problem by using a host with 2 CPUs, and doing:
virsh cpu-stats $dom --start 1 --count 2
* daemon/remote.c (remoteDispatchDomainGetCPUStats): Allow driver
to omit tail of array.
* src/remote/remote_driver.c (remoteDomainGetCPUStats):
Accommodate driver that omits tail of array.
* src/libvirt.c (virDomainGetCPUStats): Document this.
* src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Clear all
unpopulated entries.
2012-03-07 04:36:53 +00:00
|
|
|
* to expand things back into a possibly sparse array, where the
|
|
|
|
* tail of the array may be omitted.
|
2012-01-28 06:21:31 +00:00
|
|
|
*/
|
|
|
|
memset(params, 0, sizeof(*params) * nparams * ncpus);
|
rpc: allow truncated return for virDomainGetCPUStats
The RPC code assumed that the array returned by the driver would be
fully populated; that is, ncpus on entry resulted in ncpus * return
value on exit. However, while we don't support holes in the middle
of ncpus, we do want to permit the case of ncpus on entry being
longer than the array returned by the driver (that is, it should be
safe for the caller to pass ncpus=128 on entry, and the driver will
stop populating the array when it hits max_id).
Additionally, a successful return implies that the caller will then
use virTypedParamArrayClear on the entire array; for this to not
free uninitialized memory, the driver must ensure that all skipped
entries are explicitly zeroed (the RPC driver did this, but not
the qemu driver).
There are now three cases:
server 0.9.10 and client 0.9.10 or newer: No impact - there were no
hypervisor drivers that supported cpu stats
server 0.9.11 or newer and client 0.9.10: if the client calls with
ncpus beyond the max, then the rpc call will fail on the client side
and disconnect the client, but the server is no worse for the wear
server 0.9.11 or newer and client 0.9.11: the server can return a
truncated array and the client will do just fine
I reproduced the problem by using a host with 2 CPUs, and doing:
virsh cpu-stats $dom --start 1 --count 2
* daemon/remote.c (remoteDispatchDomainGetCPUStats): Allow driver
to omit tail of array.
* src/remote/remote_driver.c (remoteDomainGetCPUStats):
Accommodate driver that omits tail of array.
* src/libvirt.c (virDomainGetCPUStats): Document this.
* src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Clear all
unpopulated entries.
2012-03-07 04:36:53 +00:00
|
|
|
ncpus = ret.params.params_len / ret.nparams;
|
2012-01-28 06:21:31 +00:00
|
|
|
for (cpu = 0; cpu < ncpus; cpu++) {
|
|
|
|
int tmp = nparams;
|
2013-01-30 09:28:54 +00:00
|
|
|
virTypedParameterPtr cpu_params = ¶ms[cpu * nparams];
|
2012-01-28 06:21:31 +00:00
|
|
|
remote_typed_param *stride = &ret.params.params_val[cpu * ret.nparams];
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) stride,
|
|
|
|
ret.nparams,
|
|
|
|
REMOTE_NODE_CPU_STATS_MAX,
|
|
|
|
&cpu_params, &tmp) < 0)
|
2012-01-28 06:21:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.nparams;
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-01-31 03:20:40 +00:00
|
|
|
if (rv < 0)
|
2013-01-15 23:42:35 +00:00
|
|
|
virTypedParamsClear(params, nparams * ncpus);
|
2012-01-28 06:21:31 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-01-28 06:21:31 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2014-01-08 17:10:49 +00:00
|
|
|
|
2013-12-11 10:38:01 +00:00
|
|
|
static int
|
|
|
|
remoteConnectNetworkEventRegisterAny(virConnectPtr conn,
|
|
|
|
virNetworkPtr net,
|
|
|
|
int eventID,
|
|
|
|
virConnectNetworkEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_connect_network_event_register_any_args args;
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
remote_connect_network_event_register_any_ret ret;
|
2013-12-11 10:38:01 +00:00
|
|
|
int callbackID;
|
|
|
|
int count;
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
remote_nonnull_network network;
|
2013-12-11 10:38:01 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2014-01-06 12:32:55 +00:00
|
|
|
if ((count = virNetworkEventStateRegisterClient(conn, priv->eventState,
|
|
|
|
net, eventID, callback,
|
|
|
|
opaque, freecb,
|
|
|
|
&callbackID)) < 0)
|
2013-12-11 10:38:01 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If this is the first callback for this eventID, we need to enable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 1) {
|
|
|
|
args.eventID = eventID;
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
if (net) {
|
|
|
|
make_nonnull_network(&network, net);
|
|
|
|
args.net = &network;
|
|
|
|
} else {
|
|
|
|
args.net = NULL;
|
|
|
|
}
|
2013-12-11 10:38:01 +00:00
|
|
|
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-12-11 10:38:01 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_network_event_register_any_args, (char *) &args,
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
(xdrproc_t) xdr_remote_connect_network_event_register_any_ret, (char *) &ret) == -1) {
|
2014-01-04 13:14:33 +00:00
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2013-12-11 10:38:01 +00:00
|
|
|
goto done;
|
|
|
|
}
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
2013-12-11 10:38:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rv = callbackID;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-12-11 10:38:01 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteConnectNetworkEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
remote_connect_network_event_deregister_any_args args;
|
|
|
|
int eventID;
|
2014-01-06 12:32:55 +00:00
|
|
|
int remoteID;
|
2013-12-11 10:38:01 +00:00
|
|
|
int count;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2014-01-04 13:14:33 +00:00
|
|
|
if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
|
2014-01-06 12:32:55 +00:00
|
|
|
callbackID, &remoteID)) < 0)
|
2013-12-11 10:38:01 +00:00
|
|
|
goto done;
|
|
|
|
|
2014-01-04 13:14:33 +00:00
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2013-12-11 10:38:01 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If that was the last callback for this eventID, we need to disable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 0) {
|
event: wire up RPC for server-side network event filtering
We haven't had a release with network events yet, so we are free
to fix the RPC so that it actually does what we want. Doing
client-side filtering of per-network events is inefficient if a
connection is only interested in events on a single network out
of hundreds available on the server. But to do server-side
per-network filtering, the server needs to know which network
to filter on - so we need to pass an optional network over on
registration. Furthermore, it is possible to have a client with
both a global and per-network filter; in the existing code, the
server sends only one event and the client replicates to both
callbacks. But with server-side filtering, the server will send
the event twice, so we need a way for the client to know which
callbackID is sending an event, to ensure that the client can
filter out events from a registration that does not match the
callbackID from the server. Likewise, the existing style of
deregistering by eventID alone is fine; but in the new style,
we have to remember which callbackID to delete.
This patch fixes the RPC wire definition to contain all the
needed pieces of information, and hooks into the server and
client side improvements of the previous patches, in order to
switch over to full server-side filtering of network events.
Also, since we fixed this in time, all released versions of
libvirtd that support network events also support per-network
filtering, so we can hard-code that assumption into
network_event.c.
Converting domain events to server-side filtering will require
the introduction of new RPC numbers, as well as a server
feature bit that the client can use to tell whether to use
old-style (server only supports global events) or new-style
(server supports filtered events), so that is deferred to a
later set of patches.
* src/conf/network_event.c (virNetworkEventStateRegisterClient):
Assume server-side filtering.
* src/remote/remote_protocol.x
(remote_connect_network_event_register_any_args): Add network
argument.
(remote_connect_network_event_register_any_ret): Return callbackID
instead of count.
(remote_connect_network_event_deregister_any_args): Pass
callbackID instead of eventID.
(remote_connect_network_event_deregister_any_ret): Drop unused
type.
(remote_network_event_lifecycle_msg): Add callbackID.
* daemon/remote.c
(remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
and deal with callbackID from client.
(remoteRelayNetworkEventLifecycle): Pass callbackID.
(remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
recognize non-NULL network.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny): Pass network, and track
server side id.
(remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
(remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-08 20:24:22 +00:00
|
|
|
args.callbackID = remoteID;
|
2013-12-11 10:38:01 +00:00
|
|
|
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NETWORK_EVENT_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_network_event_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-12-11 10:38:01 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-06-15 18:35:45 +00:00
|
|
|
static int
|
|
|
|
remoteConnectStoragePoolEventRegisterAny(virConnectPtr conn,
|
|
|
|
virStoragePoolPtr pool,
|
|
|
|
int eventID,
|
|
|
|
virConnectStoragePoolEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_connect_storage_pool_event_register_any_args args;
|
|
|
|
remote_connect_storage_pool_event_register_any_ret ret;
|
|
|
|
int callbackID;
|
|
|
|
int count;
|
|
|
|
remote_nonnull_storage_pool storage_pool;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((count = virStoragePoolEventStateRegisterClient(conn, priv->eventState,
|
|
|
|
pool, eventID, callback,
|
|
|
|
opaque, freecb,
|
|
|
|
&callbackID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If this is the first callback for this eventID, we need to enable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 1) {
|
|
|
|
args.eventID = eventID;
|
|
|
|
if (pool) {
|
|
|
|
make_nonnull_storage_pool(&storage_pool, pool);
|
|
|
|
args.pool = &storage_pool;
|
|
|
|
} else {
|
|
|
|
args.pool = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_STORAGE_POOL_EVENT_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_storage_pool_event_register_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_storage_pool_event_register_any_ret, (char *) &ret) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2016-06-15 18:35:45 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = callbackID;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
remote_connect_storage_pool_event_deregister_any_args args;
|
|
|
|
int eventID;
|
|
|
|
int remoteID;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
|
|
|
|
callbackID, &remoteID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2016-06-15 18:35:45 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If that was the last callback for this eventID, we need to disable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 0) {
|
|
|
|
args.callbackID = remoteID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_STORAGE_POOL_EVENT_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_storage_pool_event_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2014-01-08 17:10:49 +00:00
|
|
|
|
2016-07-28 12:02:53 +00:00
|
|
|
static int
|
|
|
|
remoteConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
|
|
|
virNodeDevicePtr dev,
|
|
|
|
int eventID,
|
|
|
|
virConnectNodeDeviceEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_connect_node_device_event_register_any_args args;
|
|
|
|
remote_connect_node_device_event_register_any_ret ret;
|
|
|
|
int callbackID;
|
|
|
|
int count;
|
|
|
|
remote_nonnull_node_device node_device;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((count = virNodeDeviceEventStateRegisterClient(conn, priv->eventState,
|
|
|
|
dev, eventID, callback,
|
|
|
|
opaque, freecb,
|
|
|
|
&callbackID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If this is the first callback for this eventID, we need to enable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 1) {
|
|
|
|
args.eventID = eventID;
|
|
|
|
if (dev) {
|
|
|
|
make_nonnull_node_device(&node_device, dev);
|
|
|
|
args.dev = &node_device;
|
|
|
|
} else {
|
|
|
|
args.dev = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_node_device_event_register_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_node_device_event_register_any_ret, (char *) &ret) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2016-07-28 12:02:53 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = callbackID;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
remote_connect_node_device_event_deregister_any_args args;
|
|
|
|
int eventID;
|
|
|
|
int remoteID;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
|
|
|
|
callbackID, &remoteID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2016-07-28 12:02:53 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If that was the last callback for this eventID, we need to disable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 0) {
|
|
|
|
args.callbackID = remoteID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_node_device_event_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-22 16:11:06 +00:00
|
|
|
static int
|
|
|
|
remoteConnectSecretEventRegisterAny(virConnectPtr conn,
|
|
|
|
virSecretPtr secret,
|
|
|
|
int eventID,
|
|
|
|
virConnectSecretEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_connect_secret_event_register_any_args args;
|
|
|
|
remote_connect_secret_event_register_any_ret ret;
|
|
|
|
int callbackID;
|
|
|
|
int count;
|
|
|
|
remote_nonnull_secret sec;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((count = virSecretEventStateRegisterClient(conn, priv->eventState,
|
|
|
|
secret, eventID, callback,
|
|
|
|
opaque, freecb,
|
|
|
|
&callbackID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If this is the first callback for this eventID, we need to enable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 1) {
|
|
|
|
args.eventID = eventID;
|
|
|
|
if (secret) {
|
|
|
|
make_nonnull_secret(&sec, secret);
|
|
|
|
args.secret = &sec;
|
|
|
|
} else {
|
|
|
|
args.secret = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_SECRET_EVENT_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_secret_event_register_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_secret_event_register_any_ret, (char *) &ret) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2016-12-22 16:11:06 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = callbackID;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteConnectSecretEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
remote_connect_secret_event_deregister_any_args args;
|
|
|
|
int eventID;
|
|
|
|
int remoteID;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
|
|
|
|
callbackID, &remoteID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2016-12-22 16:11:06 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If that was the last callback for this eventID, we need to disable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 0) {
|
|
|
|
args.callbackID = remoteID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_SECRET_EVENT_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_secret_event_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-29 22:30:44 +00:00
|
|
|
static int
|
|
|
|
remoteConnectDomainQemuMonitorEventRegister(virConnectPtr conn,
|
|
|
|
virDomainPtr dom,
|
|
|
|
const char *event,
|
|
|
|
virConnectDomainQemuMonitorEventCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
qemu_connect_domain_monitor_event_register_args args;
|
|
|
|
qemu_connect_domain_monitor_event_register_ret ret;
|
|
|
|
int callbackID;
|
|
|
|
int count;
|
|
|
|
remote_nonnull_domain domain;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if ((count = virDomainQemuMonitorEventStateRegisterID(conn,
|
|
|
|
priv->eventState,
|
|
|
|
dom, event, callback,
|
|
|
|
opaque, freecb, -1,
|
|
|
|
&callbackID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If this is the first callback for this event, we need to enable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 1) {
|
|
|
|
if (dom) {
|
|
|
|
make_nonnull_domain(&domain, dom);
|
|
|
|
args.dom = &domain;
|
|
|
|
} else {
|
|
|
|
args.dom = NULL;
|
|
|
|
}
|
|
|
|
args.event = event ? (char **) &event : NULL;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_REGISTER,
|
|
|
|
(xdrproc_t) xdr_qemu_connect_domain_monitor_event_register_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_qemu_connect_domain_monitor_event_register_ret, (char *) &ret) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2014-01-29 22:30:44 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = callbackID;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2014-01-29 22:30:44 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteConnectDomainQemuMonitorEventDeregister(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
qemu_connect_domain_monitor_event_deregister_args args;
|
|
|
|
int remoteID;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (virObjectEventStateEventID(conn, priv->eventState,
|
|
|
|
callbackID, &remoteID) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2014-01-29 22:30:44 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* If that was the last callback for this event, we need to disable
|
|
|
|
* events on the server */
|
|
|
|
if (count == 0) {
|
|
|
|
args.callbackID = remoteID;
|
|
|
|
|
|
|
|
if (call(conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_DEREGISTER,
|
|
|
|
(xdrproc_t) xdr_qemu_connect_domain_monitor_event_deregister_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2014-01-29 22:30:44 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
2008-08-27 20:05:58 +00:00
|
|
|
static char *
|
2013-04-18 11:07:23 +00:00
|
|
|
remoteConnectFindStoragePoolSources(virConnectPtr conn,
|
|
|
|
const char *type,
|
|
|
|
const char *srcSpec,
|
|
|
|
unsigned int flags)
|
2008-08-27 20:05:58 +00:00
|
|
|
{
|
2009-01-15 20:07:10 +00:00
|
|
|
char *rv = NULL;
|
2013-04-18 11:07:23 +00:00
|
|
|
remote_connect_find_storage_pool_sources_args args;
|
|
|
|
remote_connect_find_storage_pool_sources_ret ret;
|
2014-10-23 13:33:11 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2008-08-27 20:05:58 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2008-08-27 20:05:58 +00:00
|
|
|
args.type = (char*)type;
|
2012-07-31 08:56:41 +00:00
|
|
|
args.srcSpec = srcSpec ? (char **)&srcSpec : NULL;
|
2008-08-27 20:05:58 +00:00
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_FIND_STORAGE_POOL_SOURCES,
|
|
|
|
(xdrproc_t) xdr_remote_connect_find_storage_pool_sources_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_find_storage_pool_sources_ret, (char *) &ret) == -1)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-02-20 15:23:36 +00:00
|
|
|
|
2011-04-23 17:03:14 +00:00
|
|
|
rv = ret.xml;
|
|
|
|
ret.xml = NULL; /* To stop xdr_free free'ing it */
|
|
|
|
|
2013-04-18 11:07:23 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_connect_find_storage_pool_sources_ret, (char *) &ret);
|
2009-01-15 20:07:10 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2011-04-23 17:03:14 +00:00
|
|
|
return rv;
|
2008-02-20 15:23:36 +00:00
|
|
|
}
|
|
|
|
|
2008-11-21 12:31:04 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
2009-03-02 16:30:59 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteNodeDeviceDettach(virNodeDevicePtr dev)
|
2009-03-02 16:30:59 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_device_dettach_args args;
|
|
|
|
struct private_data *priv = dev->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.name = dev->name;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DETTACH,
|
|
|
|
(xdrproc_t) xdr_remote_node_device_dettach_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
2009-03-02 16:30:59 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-03-02 16:30:59 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-04-24 17:42:04 +00:00
|
|
|
static int
|
|
|
|
remoteNodeDeviceDetachFlags(virNodeDevicePtr dev,
|
|
|
|
const char *driverName,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_device_detach_flags_args args;
|
|
|
|
struct private_data *priv = dev->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.name = dev->name;
|
|
|
|
args.driverName = driverName ? (char**)&driverName : NULL;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DETACH_FLAGS,
|
|
|
|
(xdrproc_t) xdr_remote_node_device_detach_flags_args,
|
|
|
|
(char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-04-24 17:42:04 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-03-02 16:30:59 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteNodeDeviceReAttach(virNodeDevicePtr dev)
|
2009-03-02 16:30:59 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_device_re_attach_args args;
|
|
|
|
struct private_data *priv = dev->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.name = dev->name;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RE_ATTACH,
|
|
|
|
(xdrproc_t) xdr_remote_node_device_re_attach_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
2009-03-02 16:30:59 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-03-02 16:30:59 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteNodeDeviceReset(virNodeDevicePtr dev)
|
2009-03-02 16:30:59 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_device_reset_args args;
|
2010-08-09 12:16:04 +00:00
|
|
|
/* This method is unusual in that it uses the HV driver, not the devMon driver
|
2013-04-23 10:15:48 +00:00
|
|
|
* hence its use of privateData, instead of nodeDevicePrivateData */
|
2009-03-02 16:30:59 +00:00
|
|
|
struct private_data *priv = dev->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.name = dev->name;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RESET,
|
|
|
|
(xdrproc_t) xdr_remote_node_device_reset_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
2009-03-02 16:30:59 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-03-02 16:30:59 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-03-25 17:46:03 +00:00
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteAuthenticate(virConnectPtr conn, struct private_data *priv,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
|
|
const char *authtype)
|
2007-12-05 15:24:15 +00:00
|
|
|
{
|
|
|
|
struct remote_auth_list_ret ret;
|
2007-12-05 18:55:04 +00:00
|
|
|
int err, type = REMOTE_AUTH_NONE;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2012-03-29 09:52:04 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2012-10-17 09:23:12 +00:00
|
|
|
err = call(conn, priv, 0,
|
|
|
|
REMOTE_PROC_AUTH_LIST,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
|
|
|
(xdrproc_t) xdr_remote_auth_list_ret, (char *) &ret);
|
2010-12-01 16:46:36 +00:00
|
|
|
if (err < 0) {
|
2018-05-05 12:04:21 +00:00
|
|
|
if (virGetLastErrorCode() == VIR_ERR_NO_SUPPORT) {
|
2010-12-01 16:46:36 +00:00
|
|
|
/* Missing RPC - old server - ignore */
|
|
|
|
virResetLastError();
|
|
|
|
return 0;
|
|
|
|
}
|
2007-12-05 15:24:15 +00:00
|
|
|
return -1;
|
2010-12-01 16:46:36 +00:00
|
|
|
}
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
if (ret.types.types_len == 0)
|
|
|
|
return 0;
|
|
|
|
|
2007-12-05 18:55:04 +00:00
|
|
|
if (authtype) {
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int want;
|
|
|
|
size_t i;
|
2007-12-05 18:55:04 +00:00
|
|
|
if (STRCASEEQ(authtype, "sasl") ||
|
|
|
|
STRCASEEQLEN(authtype, "sasl.", 5)) {
|
|
|
|
want = REMOTE_AUTH_SASL;
|
|
|
|
} else if (STRCASEEQ(authtype, "polkit")) {
|
|
|
|
want = REMOTE_AUTH_POLKIT;
|
|
|
|
} else {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED,
|
|
|
|
_("unknown authentication type %s"), authtype);
|
2007-12-05 18:55:04 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0; i < ret.types.types_len; i++) {
|
2007-12-05 18:55:04 +00:00
|
|
|
if (ret.types.types_val[i] == want)
|
|
|
|
type = want;
|
|
|
|
}
|
|
|
|
if (type == REMOTE_AUTH_NONE) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED,
|
|
|
|
_("requested authentication type %s rejected"),
|
|
|
|
authtype);
|
2007-12-05 18:55:04 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
type = ret.types.types_val[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type) {
|
2012-09-20 11:58:29 +00:00
|
|
|
#if WITH_SASL
|
2007-12-05 18:55:04 +00:00
|
|
|
case REMOTE_AUTH_SASL: {
|
|
|
|
const char *mech = NULL;
|
|
|
|
if (authtype &&
|
|
|
|
STRCASEEQLEN(authtype, "sasl.", 5))
|
|
|
|
mech = authtype + 5;
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (remoteAuthSASL(conn, priv, auth, mech) < 0) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(ret.types.types_val);
|
2007-12-05 15:24:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break;
|
2007-12-05 18:55:04 +00:00
|
|
|
}
|
2007-12-05 15:24:15 +00:00
|
|
|
#endif
|
|
|
|
|
2007-12-05 18:21:27 +00:00
|
|
|
case REMOTE_AUTH_POLKIT:
|
2010-12-01 16:46:36 +00:00
|
|
|
if (remoteAuthPolkit(conn, priv, auth) < 0) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(ret.types.types_val);
|
2007-12-05 18:21:27 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
case REMOTE_AUTH_NONE:
|
|
|
|
/* Nothing todo, hurrah ! */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED,
|
|
|
|
_("unsupported authentication type %d"),
|
|
|
|
ret.types.types_val[0]);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(ret.types.types_val);
|
2007-12-05 15:24:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(ret.types.types_val);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-09-20 11:58:29 +00:00
|
|
|
#if WITH_SASL
|
2007-12-05 18:55:04 +00:00
|
|
|
static int remoteAuthCredVir2SASL(int vircred)
|
|
|
|
{
|
|
|
|
switch (vircred) {
|
|
|
|
case VIR_CRED_USERNAME:
|
|
|
|
return SASL_CB_USER;
|
|
|
|
|
|
|
|
case VIR_CRED_AUTHNAME:
|
|
|
|
return SASL_CB_AUTHNAME;
|
|
|
|
|
|
|
|
case VIR_CRED_LANGUAGE:
|
|
|
|
return SASL_CB_LANGUAGE;
|
|
|
|
|
|
|
|
case VIR_CRED_CNONCE:
|
|
|
|
return SASL_CB_CNONCE;
|
|
|
|
|
|
|
|
case VIR_CRED_PASSPHRASE:
|
|
|
|
return SASL_CB_PASS;
|
|
|
|
|
|
|
|
case VIR_CRED_ECHOPROMPT:
|
|
|
|
return SASL_CB_ECHOPROMPT;
|
|
|
|
|
|
|
|
case VIR_CRED_NOECHOPROMPT:
|
|
|
|
return SASL_CB_NOECHOPROMPT;
|
|
|
|
|
|
|
|
case VIR_CRED_REALM:
|
|
|
|
return SASL_CB_GETREALM;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int remoteAuthCredSASL2Vir(int vircred)
|
|
|
|
{
|
|
|
|
switch (vircred) {
|
|
|
|
case SASL_CB_USER:
|
|
|
|
return VIR_CRED_USERNAME;
|
|
|
|
|
|
|
|
case SASL_CB_AUTHNAME:
|
|
|
|
return VIR_CRED_AUTHNAME;
|
|
|
|
|
|
|
|
case SASL_CB_LANGUAGE:
|
|
|
|
return VIR_CRED_LANGUAGE;
|
|
|
|
|
|
|
|
case SASL_CB_CNONCE:
|
|
|
|
return VIR_CRED_CNONCE;
|
|
|
|
|
|
|
|
case SASL_CB_PASS:
|
|
|
|
return VIR_CRED_PASSPHRASE;
|
|
|
|
|
|
|
|
case SASL_CB_ECHOPROMPT:
|
|
|
|
return VIR_CRED_ECHOPROMPT;
|
|
|
|
|
|
|
|
case SASL_CB_NOECHOPROMPT:
|
|
|
|
return VIR_CRED_NOECHOPROMPT;
|
|
|
|
|
|
|
|
case SASL_CB_GETREALM:
|
|
|
|
return VIR_CRED_REALM;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @param credtype array of credential types client supports
|
|
|
|
* @param ncredtype size of credtype array
|
|
|
|
* @return the SASL callback structure, or NULL on error
|
|
|
|
*
|
|
|
|
* Build up the SASL callback structure. We register one callback for
|
|
|
|
* each credential type that the libvirt client indicated they support.
|
2013-10-16 15:26:18 +00:00
|
|
|
* We explicitly leave the callback function pointer at NULL though,
|
2007-12-05 18:55:04 +00:00
|
|
|
* because we don't actually want to get SASL callbacks triggered.
|
|
|
|
* Instead, we want the start/step functions to return SASL_INTERACT.
|
|
|
|
* This lets us give the libvirt client a list of all required
|
|
|
|
* credentials in one go, rather than triggering the callback one
|
|
|
|
* credential at a time,
|
|
|
|
*/
|
|
|
|
static sasl_callback_t *remoteAuthMakeCallbacks(int *credtype, int ncredtype)
|
|
|
|
{
|
2008-06-06 11:09:57 +00:00
|
|
|
sasl_callback_t *cbs;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int n;
|
2014-11-13 14:29:21 +00:00
|
|
|
if (VIR_ALLOC_N(cbs, ncredtype+1) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
return NULL;
|
|
|
|
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0, n = 0; i < ncredtype; i++) {
|
2007-12-05 18:55:04 +00:00
|
|
|
int id = remoteAuthCredVir2SASL(credtype[i]);
|
|
|
|
if (id != 0)
|
|
|
|
cbs[n++].id = id;
|
|
|
|
/* Don't fill proc or context fields of sasl_callback_t
|
|
|
|
* because we want to use interactions instead */
|
|
|
|
}
|
|
|
|
cbs[n].id = 0;
|
|
|
|
return cbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @param interact SASL interactions required
|
|
|
|
* @param cred populated with libvirt credential metadata
|
|
|
|
* @return the size of the cred array returned
|
2007-12-05 15:24:15 +00:00
|
|
|
*
|
2007-12-05 18:55:04 +00:00
|
|
|
* Builds up an array of libvirt credential structs, populating
|
|
|
|
* with data from the SASL interaction struct. These two structs
|
|
|
|
* are basically a 1-to-1 copy of each other.
|
|
|
|
*/
|
|
|
|
static int remoteAuthMakeCredentials(sasl_interact_t *interact,
|
2012-03-19 17:26:21 +00:00
|
|
|
virConnectCredentialPtr *cred,
|
|
|
|
size_t *ncred)
|
2007-12-05 18:55:04 +00:00
|
|
|
{
|
|
|
|
int ninteract;
|
|
|
|
if (!cred)
|
|
|
|
return -1;
|
|
|
|
|
2013-05-21 08:01:50 +00:00
|
|
|
for (ninteract = 0, *ncred = 0; interact[ninteract].id != 0; ninteract++) {
|
2012-03-20 11:11:10 +00:00
|
|
|
if (interact[ninteract].result)
|
|
|
|
continue;
|
|
|
|
(*ncred)++;
|
|
|
|
}
|
2007-12-05 18:55:04 +00:00
|
|
|
|
2012-03-20 11:11:10 +00:00
|
|
|
if (VIR_ALLOC_N(*cred, *ncred) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
return -1;
|
|
|
|
|
2013-05-21 08:01:50 +00:00
|
|
|
for (ninteract = 0, *ncred = 0; interact[ninteract].id != 0; ninteract++) {
|
2012-03-20 11:11:10 +00:00
|
|
|
if (interact[ninteract].result)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
(*cred)[*ncred].type = remoteAuthCredSASL2Vir(interact[ninteract].id);
|
|
|
|
if (!(*cred)[*ncred].type) {
|
|
|
|
*ncred = 0;
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(*cred);
|
2007-12-05 18:55:04 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2012-03-20 11:11:10 +00:00
|
|
|
if (interact[*ncred].challenge)
|
|
|
|
(*cred)[*ncred].challenge = interact[ninteract].challenge;
|
|
|
|
(*cred)[*ncred].prompt = interact[ninteract].prompt;
|
|
|
|
if (interact[*ncred].defresult)
|
|
|
|
(*cred)[*ncred].defresult = interact[ninteract].defresult;
|
|
|
|
(*cred)[*ncred].result = NULL;
|
|
|
|
|
|
|
|
(*ncred)++;
|
2007-12-05 18:55:04 +00:00
|
|
|
}
|
|
|
|
|
2012-03-19 17:26:21 +00:00
|
|
|
return 0;
|
2007-12-05 18:55:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @param cred the populated libvirt credentials
|
|
|
|
* @param interact the SASL interactions to fill in results for
|
|
|
|
*
|
|
|
|
* Fills the SASL interactions with the result from the libvirt
|
|
|
|
* callbacks
|
|
|
|
*/
|
|
|
|
static void remoteAuthFillInteract(virConnectCredentialPtr cred,
|
|
|
|
sasl_interact_t *interact)
|
|
|
|
{
|
2012-03-20 11:11:10 +00:00
|
|
|
int ninteract, ncred;
|
2013-05-21 08:01:50 +00:00
|
|
|
for (ninteract = 0, ncred = 0; interact[ninteract].id != 0; ninteract++) {
|
2012-03-20 11:11:10 +00:00
|
|
|
if (interact[ninteract].result)
|
|
|
|
continue;
|
|
|
|
interact[ninteract].result = cred[ncred].result;
|
|
|
|
interact[ninteract].len = cred[ncred].resultlen;
|
|
|
|
ncred++;
|
2007-12-05 18:55:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-19 17:26:21 +00:00
|
|
|
struct remoteAuthInteractState {
|
|
|
|
sasl_interact_t *interact;
|
|
|
|
virConnectCredentialPtr cred;
|
|
|
|
size_t ncred;
|
2012-03-20 11:11:10 +00:00
|
|
|
virAuthConfigPtr config;
|
2012-03-19 17:26:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-03-20 11:11:10 +00:00
|
|
|
|
|
|
|
static int remoteAuthFillFromConfig(virConnectPtr conn,
|
|
|
|
struct remoteAuthInteractState *state)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int ninteract;
|
|
|
|
const char *credname;
|
|
|
|
char *path = NULL;
|
|
|
|
|
|
|
|
VIR_DEBUG("Trying to fill auth parameters from config file");
|
|
|
|
|
|
|
|
if (!state->config) {
|
|
|
|
if (virAuthGetConfigFilePath(conn, &path) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (path == NULL) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(state->config = virAuthConfigNew(path)))
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-21 08:01:50 +00:00
|
|
|
for (ninteract = 0; state->interact[ninteract].id != 0; ninteract++) {
|
2012-03-20 11:11:10 +00:00
|
|
|
const char *value = NULL;
|
|
|
|
|
|
|
|
switch (state->interact[ninteract].id) {
|
|
|
|
case SASL_CB_USER:
|
|
|
|
credname = "username";
|
|
|
|
break;
|
|
|
|
case SASL_CB_AUTHNAME:
|
|
|
|
credname = "authname";
|
|
|
|
break;
|
|
|
|
case SASL_CB_PASS:
|
|
|
|
credname = "password";
|
|
|
|
break;
|
|
|
|
case SASL_CB_GETREALM:
|
|
|
|
credname = "realm";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
credname = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-01-07 17:09:31 +00:00
|
|
|
if (credname &&
|
|
|
|
virAuthConfigLookup(state->config,
|
2012-03-20 11:11:10 +00:00
|
|
|
"libvirt",
|
2012-09-12 15:40:08 +00:00
|
|
|
VIR_URI_SERVER(conn->uri),
|
2012-03-20 11:11:10 +00:00
|
|
|
credname,
|
|
|
|
&value) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
state->interact[ninteract].result = value;
|
|
|
|
state->interact[ninteract].len = strlen(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-03-20 11:11:10 +00:00
|
|
|
VIR_FREE(path);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void remoteAuthInteractStateClear(struct remoteAuthInteractState *state,
|
|
|
|
bool final)
|
2012-03-19 17:26:21 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
if (!state)
|
|
|
|
return;
|
|
|
|
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0; i < state->ncred; i++)
|
2012-03-19 17:26:21 +00:00
|
|
|
VIR_FREE(state->cred[i].result);
|
|
|
|
VIR_FREE(state->cred);
|
|
|
|
state->ncred = 0;
|
2012-03-20 11:11:10 +00:00
|
|
|
|
|
|
|
if (final)
|
|
|
|
virAuthConfigFree(state->config);
|
2012-03-19 17:26:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-20 11:11:10 +00:00
|
|
|
static int remoteAuthInteract(virConnectPtr conn,
|
|
|
|
struct remoteAuthInteractState *state,
|
2012-03-19 17:26:21 +00:00
|
|
|
virConnectAuthPtr auth)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
|
2012-03-20 11:11:10 +00:00
|
|
|
VIR_DEBUG("Starting SASL interaction");
|
|
|
|
remoteAuthInteractStateClear(state, false);
|
|
|
|
|
2012-09-10 15:47:58 +00:00
|
|
|
/* Fills state->interact with any values from the auth config file */
|
2012-03-20 11:11:10 +00:00
|
|
|
if (remoteAuthFillFromConfig(conn, state) < 0)
|
|
|
|
goto cleanup;
|
2012-03-19 17:26:21 +00:00
|
|
|
|
2012-09-10 15:47:58 +00:00
|
|
|
/* Populates state->cred for anything not found in the auth config */
|
2012-03-19 17:26:21 +00:00
|
|
|
if (remoteAuthMakeCredentials(state->interact, &state->cred, &state->ncred) < 0) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED, "%s",
|
|
|
|
_("Failed to make auth credentials"));
|
2012-03-19 17:26:21 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-09-10 15:47:58 +00:00
|
|
|
/* If there was anything not in the auth config, we need to
|
|
|
|
* run the interactive callback
|
|
|
|
*/
|
|
|
|
if (state->ncred) {
|
|
|
|
/* Run the authentication callback */
|
|
|
|
if (!auth || !auth->cb) {
|
|
|
|
virReportError(VIR_ERR_AUTH_FAILED, "%s",
|
|
|
|
_("No authentication callback available"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-03-19 17:26:21 +00:00
|
|
|
|
2012-09-10 15:47:58 +00:00
|
|
|
if ((*(auth->cb))(state->cred, state->ncred, auth->cbdata) < 0) {
|
|
|
|
virReportError(VIR_ERR_AUTH_FAILED, "%s",
|
|
|
|
_("Failed to collect auth credentials"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy user's responses from cred into interact */
|
|
|
|
remoteAuthFillInteract(state->cred, state->interact);
|
2012-03-19 17:26:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'interact' now has pointers to strings in 'state->cred'
|
|
|
|
* so we must not free state->cred until the *next*
|
|
|
|
* sasl_start/step function is complete. Hence we
|
|
|
|
* call remoteAuthInteractStateClear() at the *start*
|
|
|
|
* of this method, rather than the end.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-03-19 17:26:21 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-05 18:55:04 +00:00
|
|
|
/* Perform the SASL authentication process
|
2007-12-05 15:24:15 +00:00
|
|
|
*/
|
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
|
|
|
|
virConnectAuthPtr auth, const char *wantmech)
|
2007-12-05 15:24:15 +00:00
|
|
|
{
|
|
|
|
remote_auth_sasl_init_ret iret;
|
|
|
|
remote_auth_sasl_start_args sargs;
|
|
|
|
remote_auth_sasl_start_ret sret;
|
|
|
|
remote_auth_sasl_step_args pargs;
|
|
|
|
remote_auth_sasl_step_ret pret;
|
|
|
|
const char *clientout;
|
2007-12-05 18:55:04 +00:00
|
|
|
char *serverin = NULL;
|
2010-12-01 16:46:36 +00:00
|
|
|
size_t clientoutlen, serverinlen;
|
2007-12-05 15:24:15 +00:00
|
|
|
const char *mech;
|
|
|
|
int err, complete;
|
2010-12-01 16:46:36 +00:00
|
|
|
int ssf;
|
2007-12-05 18:55:04 +00:00
|
|
|
sasl_callback_t *saslcb = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
const char *mechlist;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetSASLContextPtr saslCtxt;
|
2011-06-28 18:17:00 +00:00
|
|
|
virNetSASLSessionPtr sasl = NULL;
|
2012-03-19 17:26:21 +00:00
|
|
|
struct remoteAuthInteractState state;
|
|
|
|
|
|
|
|
memset(&state, 0, sizeof(state));
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Client initialize SASL authentication");
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!(saslCtxt = virNetSASLContextNewClient()))
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2008-01-14 04:00:34 +00:00
|
|
|
if (auth) {
|
|
|
|
if ((saslcb = remoteAuthMakeCallbacks(auth->credtype, auth->ncredtype)) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
saslcb = NULL;
|
|
|
|
}
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
/* Setup a handle for being a client */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (!(sasl = virNetSASLSessionNewClient(saslCtxt,
|
|
|
|
"libvirt",
|
|
|
|
priv->hostname,
|
2016-06-23 20:31:20 +00:00
|
|
|
virNetClientLocalAddrStringSASL(priv->client),
|
|
|
|
virNetClientRemoteAddrStringSASL(priv->client),
|
2010-12-01 16:46:36 +00:00
|
|
|
saslcb)))
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2013-11-22 16:27:21 +00:00
|
|
|
/* saslcb is now owned by sasl */
|
|
|
|
saslcb = NULL;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2013-01-08 21:02:05 +00:00
|
|
|
# ifdef WITH_GNUTLS
|
2007-12-05 15:27:08 +00:00
|
|
|
/* Initialize some connection props we care about */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (priv->tls) {
|
|
|
|
if ((ssf = virNetClientGetTLSKeySize(priv->client)) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2007-12-05 15:27:08 +00:00
|
|
|
ssf *= 8; /* key size is bytes, sasl wants bits */
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Setting external SSF %d", ssf);
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetSASLSessionExtKeySize(sasl, ssf) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:27:08 +00:00
|
|
|
}
|
2013-01-07 14:54:18 +00:00
|
|
|
# endif
|
2007-12-05 15:27:08 +00:00
|
|
|
|
2010-09-14 18:17:25 +00:00
|
|
|
/* If we've got a secure channel (TLS or UNIX sock), we don't care about SSF */
|
|
|
|
/* If we're not secure, then forbid any anonymous or trivially crackable auth */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetSASLSessionSecProps(sasl,
|
|
|
|
priv->is_secure ? 0 : 56, /* Equiv to DES supported by all Kerberos */
|
|
|
|
priv->is_secure ? 0 : 100000, /* Very strong ! AES == 256 */
|
|
|
|
priv->is_secure ? true : false) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:27:08 +00:00
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
/* First call is to inquire about supported mechanisms in the server */
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&iret, 0, sizeof(iret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_AUTH_SASL_INIT,
|
|
|
|
(xdrproc_t) xdr_void, (char *)NULL,
|
|
|
|
(xdrproc_t) xdr_remote_auth_sasl_init_ret, (char *) &iret) != 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
|
2007-12-05 18:55:04 +00:00
|
|
|
mechlist = iret.mechlist;
|
|
|
|
if (wantmech) {
|
|
|
|
if (strstr(mechlist, wantmech) == NULL) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED,
|
|
|
|
_("SASL mechanism %s not supported by server"),
|
|
|
|
wantmech);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(iret.mechlist);
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
mechlist = wantmech;
|
|
|
|
}
|
|
|
|
restart:
|
2007-12-05 15:24:15 +00:00
|
|
|
/* Start the auth negotiation on the client end first */
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Client start negotiation mechlist '%s'", mechlist);
|
2010-12-01 16:46:36 +00:00
|
|
|
if ((err = virNetSASLSessionClientStart(sasl,
|
|
|
|
mechlist,
|
2012-03-19 17:26:21 +00:00
|
|
|
&state.interact,
|
2010-12-01 16:46:36 +00:00
|
|
|
&clientout,
|
|
|
|
&clientoutlen,
|
|
|
|
&mech)) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* Need to gather some credentials from the client */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (err == VIR_NET_SASL_INTERACT) {
|
2012-03-20 11:11:10 +00:00
|
|
|
if (remoteAuthInteract(conn, &state, auth) < 0) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(iret.mechlist);
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-03-19 17:26:21 +00:00
|
|
|
goto restart;
|
2007-12-05 15:24:15 +00:00
|
|
|
}
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(iret.mechlist);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
if (clientoutlen > REMOTE_AUTH_SASL_DATA_MAX) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED,
|
|
|
|
_("SASL negotiation data too long: %zu bytes"),
|
|
|
|
clientoutlen);
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:24:15 +00:00
|
|
|
}
|
|
|
|
/* NB, distinction of NULL vs "" is *critical* in SASL */
|
2012-03-29 09:52:04 +00:00
|
|
|
memset(&sargs, 0, sizeof(sargs));
|
2007-12-05 15:24:15 +00:00
|
|
|
sargs.nil = clientout ? 0 : 1;
|
|
|
|
sargs.data.data_val = (char*)clientout;
|
|
|
|
sargs.data.data_len = clientoutlen;
|
|
|
|
sargs.mech = (char*)mech;
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Server start negotiation with mech %s. Data %zu bytes %p",
|
|
|
|
mech, clientoutlen, clientout);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
/* Now send the initial auth data to the server */
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&sret, 0, sizeof(sret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_AUTH_SASL_START,
|
|
|
|
(xdrproc_t) xdr_remote_auth_sasl_start_args, (char *) &sargs,
|
|
|
|
(xdrproc_t) xdr_remote_auth_sasl_start_ret, (char *) &sret) != 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
complete = sret.complete;
|
|
|
|
/* NB, distinction of NULL vs "" is *critical* in SASL */
|
|
|
|
serverin = sret.nil ? NULL : sret.data.data_val;
|
|
|
|
serverinlen = sret.data.data_len;
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
|
|
|
|
complete, serverinlen, serverin);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2013-11-21 17:40:52 +00:00
|
|
|
/* Previous server call showed completion & sasl_client_start() told us
|
|
|
|
* we are locally complete too */
|
|
|
|
if (complete && err == VIR_NET_SASL_COMPLETE)
|
|
|
|
goto done;
|
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
/* Loop-the-loop...
|
|
|
|
* Even if the server has completed, the client must *always* do at least one step
|
2008-04-04 07:58:29 +00:00
|
|
|
* in this loop to verify the server isn't lying about something. Mutual auth */
|
2007-12-05 15:24:15 +00:00
|
|
|
for (;;) {
|
2010-12-01 16:46:36 +00:00
|
|
|
if ((err = virNetSASLSessionClientStep(sasl,
|
|
|
|
serverin,
|
|
|
|
serverinlen,
|
2012-03-19 17:26:21 +00:00
|
|
|
&state.interact,
|
2010-12-01 16:46:36 +00:00
|
|
|
&clientout,
|
|
|
|
&clientoutlen)) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2007-12-05 18:55:04 +00:00
|
|
|
/* Need to gather some credentials from the client */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (err == VIR_NET_SASL_INTERACT) {
|
2012-03-20 11:11:10 +00:00
|
|
|
if (remoteAuthInteract(conn, &state, auth) < 0) {
|
2012-03-19 17:26:21 +00:00
|
|
|
VIR_FREE(iret.mechlist);
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-11-26 10:34:46 +00:00
|
|
|
continue;
|
2007-12-05 18:55:04 +00:00
|
|
|
}
|
|
|
|
|
2009-02-03 13:08:07 +00:00
|
|
|
VIR_FREE(serverin);
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Client step result %d. Data %zu bytes %p",
|
|
|
|
err, clientoutlen, clientout);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
/* Previous server call showed completion & we're now locally complete too */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (complete && err == VIR_NET_SASL_COMPLETE)
|
2007-12-05 15:24:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* Not done, prepare to talk with the server for another iteration */
|
|
|
|
/* NB, distinction of NULL vs "" is *critical* in SASL */
|
2012-03-29 09:52:04 +00:00
|
|
|
memset(&pargs, 0, sizeof(pargs));
|
2007-12-05 15:24:15 +00:00
|
|
|
pargs.nil = clientout ? 0 : 1;
|
|
|
|
pargs.data.data_val = (char*)clientout;
|
|
|
|
pargs.data.data_len = clientoutlen;
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Server step with %zu bytes %p",
|
|
|
|
clientoutlen, clientout);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&pret, 0, sizeof(pret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_AUTH_SASL_STEP,
|
|
|
|
(xdrproc_t) xdr_remote_auth_sasl_step_args, (char *) &pargs,
|
|
|
|
(xdrproc_t) xdr_remote_auth_sasl_step_ret, (char *) &pret) != 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
complete = pret.complete;
|
|
|
|
/* NB, distinction of NULL vs "" is *critical* in SASL */
|
|
|
|
serverin = pret.nil ? NULL : pret.data.data_val;
|
|
|
|
serverinlen = pret.data.data_len;
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
|
|
|
|
complete, serverinlen, serverin);
|
2007-12-05 15:24:15 +00:00
|
|
|
|
|
|
|
/* This server call shows complete, and earlier client step was OK */
|
2010-12-01 16:46:36 +00:00
|
|
|
if (complete && err == VIR_NET_SASL_COMPLETE) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(serverin);
|
2007-12-05 15:24:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-14 18:17:25 +00:00
|
|
|
/* Check for suitable SSF if not already secure (TLS or UNIX sock) */
|
|
|
|
if (!priv->is_secure) {
|
2010-12-01 16:46:36 +00:00
|
|
|
if ((ssf = virNetSASLSessionGetKeySize(sasl)) < 0)
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("SASL SSF value %d", ssf);
|
2007-12-05 15:27:08 +00:00
|
|
|
if (ssf < 56) { /* 56 == DES level, good for Kerberos */
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_AUTH_FAILED,
|
|
|
|
_("negotiation SSF %d was not strong enough"), ssf);
|
2007-12-05 18:55:04 +00:00
|
|
|
goto cleanup;
|
2007-12-05 15:27:08 +00: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 14:12:03 +00:00
|
|
|
priv->is_secure = 1;
|
2007-12-05 15:27:08 +00:00
|
|
|
}
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("SASL authentication complete");
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientSetSASLSession(priv->client, sasl);
|
2007-12-05 18:55:04 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(serverin);
|
2007-12-05 18:55:04 +00:00
|
|
|
|
2012-03-20 11:11:10 +00:00
|
|
|
remoteAuthInteractStateClear(&state, true);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(saslcb);
|
2012-07-11 13:35:49 +00:00
|
|
|
virObjectUnref(sasl);
|
|
|
|
virObjectUnref(saslCtxt);
|
2009-01-15 20:07:10 +00:00
|
|
|
|
2007-12-05 18:55:04 +00:00
|
|
|
return ret;
|
2007-12-05 15:24:15 +00:00
|
|
|
}
|
2012-09-20 11:58:29 +00:00
|
|
|
#endif /* WITH_SASL */
|
2007-12-05 15:24:15 +00:00
|
|
|
|
2007-12-05 18:55:04 +00:00
|
|
|
|
2016-04-14 18:58:40 +00:00
|
|
|
static int
|
|
|
|
remoteAuthPolkit(virConnectPtr conn, struct private_data *priv,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
remote_auth_polkit_ret ret;
|
|
|
|
VIR_DEBUG("Client initialize PolicyKit authentication");
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_AUTH_POLKIT,
|
|
|
|
(xdrproc_t) xdr_void, (char *)NULL,
|
|
|
|
(xdrproc_t) xdr_remote_auth_polkit_ret, (char *) &ret) != 0) {
|
|
|
|
return -1; /* virError already set by call */
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_DEBUG("PolicyKit authentication complete");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-10-23 13:18:18 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
2014-01-08 17:10:49 +00:00
|
|
|
static int
|
|
|
|
remoteConnectDomainEventRegister(virConnectPtr conn,
|
|
|
|
virConnectDomainEventCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
2008-10-23 13:18:18 +00:00
|
|
|
{
|
2014-01-08 04:00:54 +00:00
|
|
|
int callbackID;
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2008-10-23 13:18:18 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
int count;
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2014-01-08 04:00:54 +00:00
|
|
|
if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
|
|
|
|
NULL,
|
|
|
|
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
|
|
|
VIR_DOMAIN_EVENT_CALLBACK(callback),
|
|
|
|
opaque, freecb, true,
|
2014-01-08 14:57:25 +00:00
|
|
|
&callbackID,
|
|
|
|
priv->serverEventFilter)) < 0)
|
2009-01-15 20:07:10 +00:00
|
|
|
goto done;
|
2008-10-23 13:18:18 +00:00
|
|
|
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
if (count == 1) {
|
2014-01-08 17:10:49 +00:00
|
|
|
/* Tell the server when we are the first callback registering */
|
2014-01-08 14:57:25 +00:00
|
|
|
if (priv->serverEventFilter) {
|
|
|
|
remote_connect_domain_event_callback_register_any_args args;
|
|
|
|
remote_connect_domain_event_callback_register_any_ret ret;
|
|
|
|
|
|
|
|
args.eventID = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
|
|
|
|
args.dom = NULL;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0,
|
|
|
|
REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_ret, (char *) &ret) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2014-01-08 14:57:25 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
|
|
|
} else {
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2014-01-08 14:57:25 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2014-01-08 17:10:49 +00:00
|
|
|
}
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
|
|
|
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
|
|
|
|
2014-01-08 14:57:25 +00:00
|
|
|
|
2014-01-08 17:10:49 +00:00
|
|
|
static int
|
|
|
|
remoteConnectDomainEventDeregister(virConnectPtr conn,
|
|
|
|
virConnectDomainEventCallback callback)
|
2008-10-23 13:18:18 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
2009-01-15 20:07:10 +00:00
|
|
|
int rv = -1;
|
2014-01-08 14:57:25 +00:00
|
|
|
remote_connect_domain_event_callback_deregister_any_args args;
|
|
|
|
int callbackID;
|
|
|
|
int remoteID;
|
2011-12-13 11:14:46 +00:00
|
|
|
int count;
|
2008-10-23 13:18:18 +00:00
|
|
|
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2014-01-08 14:57:25 +00:00
|
|
|
if ((callbackID = virDomainEventStateCallbackID(conn, priv->eventState,
|
|
|
|
callback,
|
|
|
|
&remoteID)) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2011-05-13 15:00:10 +00:00
|
|
|
goto done;
|
2009-07-28 16:45:19 +00:00
|
|
|
|
2011-12-13 11:14:46 +00:00
|
|
|
if (count == 0) {
|
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 14:56:56 +00:00
|
|
|
/* Tell the server when we are the last callback deregistering */
|
2014-01-08 14:57:25 +00:00
|
|
|
if (priv->serverEventFilter) {
|
|
|
|
args.callbackID = remoteID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0,
|
|
|
|
REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_callback_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_DEREGISTER,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
}
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
|
|
|
|
2009-01-15 20:07:10 +00:00
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2009-01-20 11:41:24 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-01-15 20:07:10 +00:00
|
|
|
return rv;
|
2008-10-23 13:18:18 +00:00
|
|
|
}
|
2007-12-05 18:55:04 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
|
|
|
|
static void
|
2014-01-08 14:57:25 +00:00
|
|
|
remoteDomainBuildEventLifecycleHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_lifecycle_msg *msg,
|
|
|
|
int 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 14:56:56 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
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 14:56:56 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
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 14:56:56 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->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 14:56:56 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 14:56:56 +00:00
|
|
|
|
2013-11-21 17:03:26 +00:00
|
|
|
event = virDomainEventLifecycleNewFromDom(dom, msg->event, msg->detail);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2014-01-08 14:57:25 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_lifecycle_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventLifecycleHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_lifecycle_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventLifecycleHelper(conn, &msg->msg, msg->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 14:56:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventRebootHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_reboot_msg *msg,
|
|
|
|
int callbackID)
|
2010-03-18 15:25:38 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2010-03-18 15:25:38 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2010-03-18 15:25:38 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
2010-03-18 15:25:38 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
2010-03-18 15:25:38 +00:00
|
|
|
|
|
|
|
event = virDomainEventRebootNewFromDom(dom);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2010-03-18 15:25:38 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_reboot_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventRebootHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
2010-03-18 18:28:15 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_callback_reboot_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventRebootHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventRTCChangeHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_rtc_change_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2010-03-18 18:28:15 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2010-03-18 18:28:15 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
2010-03-18 18:28:15 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
2010-03-18 18:28:15 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
event = virDomainEventRTCChangeNewFromDom(dom, msg->offset);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2010-03-18 18:28:15 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *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 19:07:48 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_rtc_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventRTCChangeHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackRTCChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_rtc_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventRTCChangeHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventWatchdogHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_watchdog_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
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 19:07:48 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
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 19:07:48 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->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 19:07:48 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 19:07:48 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
event = virDomainEventWatchdogNewFromDom(dom, msg->action);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
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 19:07:48 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_watchdog_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventWatchdogHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackWatchdog(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *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 19:37:44 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_callback_watchdog_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventWatchdogHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventIOErrorHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_io_error_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
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 19:37:44 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
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 19:37:44 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->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 19:37:44 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 19:37:44 +00:00
|
|
|
|
|
|
|
event = virDomainEventIOErrorNewFromDom(dom,
|
2010-12-01 16:46:36 +00:00
|
|
|
msg->srcPath,
|
|
|
|
msg->devAlias,
|
|
|
|
msg->action);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
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 19:37:44 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventIOError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_io_error_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventIOErrorHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackIOError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *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 19:37:44 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_callback_io_error_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventIOErrorHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventIOErrorReasonHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_io_error_reason_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
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 19:37:44 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
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 19:37:44 +00:00
|
|
|
|
2013-11-19 23:04:25 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->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 19:37:44 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 19:37:44 +00:00
|
|
|
|
|
|
|
event = virDomainEventIOErrorReasonNewFromDom(dom,
|
2010-12-01 16:46:36 +00:00
|
|
|
msg->srcPath,
|
|
|
|
msg->devAlias,
|
|
|
|
msg->action,
|
|
|
|
msg->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 19:37:44 +00:00
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
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 19:37:44 +00:00
|
|
|
}
|
2011-07-22 05:57:42 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
2011-07-22 05:57:42 +00:00
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_io_error_reason_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventIOErrorReasonHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_io_error_reason_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventIOErrorReasonHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventBlockJobHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_block_job_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2011-07-22 05:57:42 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2011-07-22 05:57:42 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventBlockJobNewFromDom(dom, msg->path, msg->type,
|
|
|
|
msg->status);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2011-07-22 05:57:42 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2011-07-22 05:57:42 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *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 13:27:45 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_block_job_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventBlockJobHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_block_job_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventBlockJobHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
blockjob: use stable disk string in job event
When the block job event was first added, it was for block pull,
where the active layer of the disk remains the same name. It was
also in a day where we only cared about local files, and so we
always had a canonical absolute file name. But two things have
changed since then: we now have network disks, where determining
a single absolute string does not really make sense; and we have
two-phase jobs (copy and active commit) where the name of the
active layer changes between the first event (ready, on the old
name) and second (complete, on the pivoted name).
Adam Litke reported that having an unstable string between events
makes life harder for clients. Furthermore, all of our API that
operate on a particular disk of a domain accept multiple strings:
not only the absolute name of the active layer, but also the
destination device name (such as 'vda'). As this latter name is
stable, even for network sources, it serves as a better string
to supply in block job events.
But backwards-compatibility demands that we should not change the
name handed to users unless they explicitly request it. Therefore,
this patch adds a new event, BLOCK_JOB_2 (alas, I couldn't think of
any nicer name - but at least Migrate2 and Migrate3 are precedent
for a number suffix). We must double up on emitting both old-style
and new-style events according to what clients have registered for
(see also how IOError and IOErrorReason emits double events, but
there the difference was a larger struct rather than changed
meaning of one of the struct members).
Unfortunately, adding a new event isn't something that can easily
be broken into pieces, so the commit is rather large.
* include/libvirt/libvirt.h.in (virDomainEventID): Add a new id
for VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2.
(virConnectDomainEventBlockJobCallback): Document new semantics.
* src/conf/domain_event.c (_virDomainEventBlockJob): Rename field,
to ensure we catch all clients.
(virDomainEventBlockJobNew): Add parameter.
(virDomainEventBlockJobDispose)
(virDomainEventBlockJobNewFromObj)
(virDomainEventBlockJobNewFromDom)
(virDomainEventDispatchDefaultFunc): Adjust clients.
(virDomainEventBlockJob2NewFromObj)
(virDomainEventBlockJob2NewFromDom): New functions.
* src/conf/domain_event.h: Add new prototypes.
* src/libvirt_private.syms (domain_event.h): Export new functions.
* src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Generate two
different events.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Likewise.
* src/remote/remote_protocol.x
(remote_domain_event_block_job_2_msg): New struct.
(REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2): New RPC.
* src/remote/remote_driver.c
(remoteDomainBuildEventBlockJob2): New handler.
(remoteEvents): Register new event.
* daemon/remote.c (remoteRelayDomainEventBlockJob2): New handler.
(domainEventCallbacks): Register new event.
* tools/virsh-domain.c (vshEventCallbacks): Likewise.
(vshEventBlockJobPrint): Adjust client.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-06-14 13:18:04 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_block_job_2_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventBlockJob2NewFromDom(dom, msg->dst, msg->type,
|
|
|
|
msg->status);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
blockjob: use stable disk string in job event
When the block job event was first added, it was for block pull,
where the active layer of the disk remains the same name. It was
also in a day where we only cared about local files, and so we
always had a canonical absolute file name. But two things have
changed since then: we now have network disks, where determining
a single absolute string does not really make sense; and we have
two-phase jobs (copy and active commit) where the name of the
active layer changes between the first event (ready, on the old
name) and second (complete, on the pivoted name).
Adam Litke reported that having an unstable string between events
makes life harder for clients. Furthermore, all of our API that
operate on a particular disk of a domain accept multiple strings:
not only the absolute name of the active layer, but also the
destination device name (such as 'vda'). As this latter name is
stable, even for network sources, it serves as a better string
to supply in block job events.
But backwards-compatibility demands that we should not change the
name handed to users unless they explicitly request it. Therefore,
this patch adds a new event, BLOCK_JOB_2 (alas, I couldn't think of
any nicer name - but at least Migrate2 and Migrate3 are precedent
for a number suffix). We must double up on emitting both old-style
and new-style events according to what clients have registered for
(see also how IOError and IOErrorReason emits double events, but
there the difference was a larger struct rather than changed
meaning of one of the struct members).
Unfortunately, adding a new event isn't something that can easily
be broken into pieces, so the commit is rather large.
* include/libvirt/libvirt.h.in (virDomainEventID): Add a new id
for VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2.
(virConnectDomainEventBlockJobCallback): Document new semantics.
* src/conf/domain_event.c (_virDomainEventBlockJob): Rename field,
to ensure we catch all clients.
(virDomainEventBlockJobNew): Add parameter.
(virDomainEventBlockJobDispose)
(virDomainEventBlockJobNewFromObj)
(virDomainEventBlockJobNewFromDom)
(virDomainEventDispatchDefaultFunc): Adjust clients.
(virDomainEventBlockJob2NewFromObj)
(virDomainEventBlockJob2NewFromDom): New functions.
* src/conf/domain_event.h: Add new prototypes.
* src/libvirt_private.syms (domain_event.h): Export new functions.
* src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Generate two
different events.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Likewise.
* src/remote/remote_protocol.x
(remote_domain_event_block_job_2_msg): New struct.
(REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2): New RPC.
* src/remote/remote_driver.c
(remoteDomainBuildEventBlockJob2): New handler.
(remoteEvents): Register new event.
* daemon/remote.c (remoteRelayDomainEventBlockJob2): New handler.
(domainEventCallbacks): Register new event.
* tools/virsh-domain.c (vshEventCallbacks): Likewise.
(vshEventBlockJobPrint): Adjust client.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-06-14 13:18:04 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
blockjob: use stable disk string in job event
When the block job event was first added, it was for block pull,
where the active layer of the disk remains the same name. It was
also in a day where we only cared about local files, and so we
always had a canonical absolute file name. But two things have
changed since then: we now have network disks, where determining
a single absolute string does not really make sense; and we have
two-phase jobs (copy and active commit) where the name of the
active layer changes between the first event (ready, on the old
name) and second (complete, on the pivoted name).
Adam Litke reported that having an unstable string between events
makes life harder for clients. Furthermore, all of our API that
operate on a particular disk of a domain accept multiple strings:
not only the absolute name of the active layer, but also the
destination device name (such as 'vda'). As this latter name is
stable, even for network sources, it serves as a better string
to supply in block job events.
But backwards-compatibility demands that we should not change the
name handed to users unless they explicitly request it. Therefore,
this patch adds a new event, BLOCK_JOB_2 (alas, I couldn't think of
any nicer name - but at least Migrate2 and Migrate3 are precedent
for a number suffix). We must double up on emitting both old-style
and new-style events according to what clients have registered for
(see also how IOError and IOErrorReason emits double events, but
there the difference was a larger struct rather than changed
meaning of one of the struct members).
Unfortunately, adding a new event isn't something that can easily
be broken into pieces, so the commit is rather large.
* include/libvirt/libvirt.h.in (virDomainEventID): Add a new id
for VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2.
(virConnectDomainEventBlockJobCallback): Document new semantics.
* src/conf/domain_event.c (_virDomainEventBlockJob): Rename field,
to ensure we catch all clients.
(virDomainEventBlockJobNew): Add parameter.
(virDomainEventBlockJobDispose)
(virDomainEventBlockJobNewFromObj)
(virDomainEventBlockJobNewFromDom)
(virDomainEventDispatchDefaultFunc): Adjust clients.
(virDomainEventBlockJob2NewFromObj)
(virDomainEventBlockJob2NewFromDom): New functions.
* src/conf/domain_event.h: Add new prototypes.
* src/libvirt_private.syms (domain_event.h): Export new functions.
* src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Generate two
different events.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Likewise.
* src/remote/remote_protocol.x
(remote_domain_event_block_job_2_msg): New struct.
(REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2): New RPC.
* src/remote/remote_driver.c
(remoteDomainBuildEventBlockJob2): New handler.
(remoteEvents): Register new event.
* daemon/remote.c (remoteRelayDomainEventBlockJob2): New handler.
(domainEventCallbacks): Register new event.
* tools/virsh-domain.c (vshEventCallbacks): Likewise.
(vshEventBlockJobPrint): Adjust client.
* src/remote_protocol-structs: Regenerate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-06-14 13:18:04 +00:00
|
|
|
}
|
2014-01-09 18:22:53 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventGraphicsHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_graphics_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
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 13:27:45 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
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 13:27:45 +00:00
|
|
|
virDomainEventGraphicsAddressPtr localAddr = NULL;
|
|
|
|
virDomainEventGraphicsAddressPtr remoteAddr = NULL;
|
|
|
|
virDomainEventGraphicsSubjectPtr subject = NULL;
|
Convert 'int i' to 'size_t i' in src/remote/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
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 13:27:45 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->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 13:27:45 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 13:27:45 +00:00
|
|
|
|
|
|
|
if (VIR_ALLOC(localAddr) < 0)
|
2013-05-03 12:47:37 +00:00
|
|
|
goto error;
|
2010-12-01 16:46:36 +00:00
|
|
|
localAddr->family = msg->local.family;
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(localAddr->service, msg->local.service) < 0 ||
|
|
|
|
VIR_STRDUP(localAddr->node, msg->local.node) < 0)
|
|
|
|
goto error;
|
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 13:27:45 +00:00
|
|
|
|
|
|
|
if (VIR_ALLOC(remoteAddr) < 0)
|
2013-05-03 12:47:37 +00:00
|
|
|
goto error;
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteAddr->family = msg->remote.family;
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(remoteAddr->service, msg->remote.service) < 0 ||
|
|
|
|
VIR_STRDUP(remoteAddr->node, msg->remote.node) < 0)
|
|
|
|
goto error;
|
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 13:27:45 +00:00
|
|
|
|
|
|
|
if (VIR_ALLOC(subject) < 0)
|
2013-05-03 12:47:37 +00:00
|
|
|
goto error;
|
2010-12-01 16:46:36 +00:00
|
|
|
if (VIR_ALLOC_N(subject->identities, msg->subject.subject_len) < 0)
|
2013-05-03 12:47:37 +00:00
|
|
|
goto error;
|
2010-12-01 16:46:36 +00:00
|
|
|
subject->nidentity = msg->subject.subject_len;
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0; i < subject->nidentity; i++) {
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(subject->identities[i].type, msg->subject.subject_val[i].type) < 0 ||
|
|
|
|
VIR_STRDUP(subject->identities[i].name, msg->subject.subject_val[i].name) < 0)
|
|
|
|
goto error;
|
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 13:27:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
event = virDomainEventGraphicsNewFromDom(dom,
|
2010-12-01 16:46:36 +00:00
|
|
|
msg->phase,
|
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 13:27:45 +00:00
|
|
|
localAddr,
|
|
|
|
remoteAddr,
|
2010-12-01 16:46:36 +00:00
|
|
|
msg->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 13:27:45 +00:00
|
|
|
subject);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(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 13:27:45 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 13:27:45 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
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 13:27:45 +00:00
|
|
|
if (localAddr) {
|
|
|
|
VIR_FREE(localAddr->service);
|
|
|
|
VIR_FREE(localAddr->node);
|
|
|
|
VIR_FREE(localAddr);
|
|
|
|
}
|
|
|
|
if (remoteAddr) {
|
|
|
|
VIR_FREE(remoteAddr->service);
|
|
|
|
VIR_FREE(remoteAddr->node);
|
|
|
|
VIR_FREE(remoteAddr);
|
|
|
|
}
|
|
|
|
if (subject) {
|
2013-05-21 08:01:50 +00:00
|
|
|
for (i = 0; i < subject->nidentity; i++) {
|
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 13:27:45 +00:00
|
|
|
VIR_FREE(subject->identities[i].type);
|
|
|
|
VIR_FREE(subject->identities[i].name);
|
|
|
|
}
|
|
|
|
VIR_FREE(subject->identities);
|
|
|
|
VIR_FREE(subject);
|
|
|
|
}
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
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 13:27:45 +00:00
|
|
|
}
|
2010-12-01 16:46:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
2011-05-29 12:21:53 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_graphics_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventGraphicsHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_graphics_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventGraphicsHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventControlErrorHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_control_error_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2011-05-29 12:21:53 +00:00
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2011-05-29 12:21:53 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
2011-05-29 12:21:53 +00:00
|
|
|
if (!dom)
|
2010-12-01 16:46:36 +00:00
|
|
|
return;
|
2011-05-29 12:21:53 +00:00
|
|
|
|
|
|
|
event = virDomainEventControlErrorNewFromDom(dom);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventControlError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_control_error_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventControlErrorHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackControlError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_control_error_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventControlErrorHelper(conn, &msg->msg, msg->callbackID);
|
2011-05-29 12:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-18 14:15:42 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventDiskChangeHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_disk_change_msg *msg,
|
|
|
|
int callbackID)
|
2011-10-18 14:15:42 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2011-10-18 14:15:42 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventDiskChangeNewFromDom(dom,
|
|
|
|
msg->oldSrcPath ? *msg->oldSrcPath : NULL,
|
|
|
|
msg->newSrcPath ? *msg->newSrcPath : NULL,
|
|
|
|
msg->devAlias,
|
|
|
|
msg->reason);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2011-10-18 14:15:42 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2011-10-18 14:15:42 +00:00
|
|
|
}
|
2012-03-23 13:44:50 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
2012-03-23 13:44:50 +00:00
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_disk_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventDiskChangeHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_disk_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventDiskChangeHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventTrayChangeHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_tray_change_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2012-03-23 13:44:50 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2012-03-23 13:44:50 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventTrayChangeNewFromDom(dom,
|
|
|
|
msg->devAlias,
|
|
|
|
msg->reason);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2012-03-23 13:44:50 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2012-03-23 13:44:50 +00:00
|
|
|
}
|
2012-03-23 14:43:14 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_tray_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventTrayChangeHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
2012-03-23 14:43:14 +00:00
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_callback_tray_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventTrayChangeHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventPMWakeupHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_pmwakeup_msg *msg,
|
2014-01-29 00:41:34 +00:00
|
|
|
int callbackID,
|
|
|
|
int reason)
|
2014-01-09 18:22:53 +00:00
|
|
|
{
|
2012-03-23 14:43:14 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2012-03-23 14:43:14 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
2014-01-29 00:41:34 +00:00
|
|
|
event = virDomainEventPMWakeupNewFromDom(dom, reason);
|
2012-03-23 14:43:14 +00:00
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2012-03-23 14:43:14 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2012-03-23 14:43:14 +00:00
|
|
|
}
|
2012-03-23 14:50:36 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_pmwakeup_msg *msg = evdata;
|
2014-01-29 00:41:34 +00:00
|
|
|
remoteDomainBuildEventPMWakeupHelper(conn, msg, -1, 0);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
2012-03-23 14:50:36 +00:00
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_callback_pmwakeup_msg *msg = evdata;
|
2014-01-29 00:41:34 +00:00
|
|
|
remoteDomainBuildEventPMWakeupHelper(conn, &msg->msg, msg->callbackID,
|
|
|
|
msg->reason);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventPMSuspendHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_pmsuspend_msg *msg,
|
2014-01-29 00:41:34 +00:00
|
|
|
int callbackID,
|
|
|
|
int reason)
|
2014-01-09 18:22:53 +00:00
|
|
|
{
|
2012-03-23 14:50:36 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2012-03-23 14:50:36 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
2014-01-29 00:41:34 +00:00
|
|
|
event = virDomainEventPMSuspendNewFromDom(dom, reason);
|
2012-03-23 14:50:36 +00:00
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2012-03-23 14:50:36 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_pmsuspend_msg *msg = evdata;
|
2014-01-29 00:41:34 +00:00
|
|
|
remoteDomainBuildEventPMSuspendHelper(conn, msg, -1, 0);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_pmsuspend_msg *msg = evdata;
|
2014-01-29 00:41:34 +00:00
|
|
|
remoteDomainBuildEventPMSuspendHelper(conn, &msg->msg, msg->callbackID,
|
|
|
|
msg->reason);
|
2012-03-23 14:50:36 +00:00
|
|
|
}
|
|
|
|
|
2012-07-13 09:05:17 +00:00
|
|
|
|
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventBalloonChangeHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_balloon_change_msg *msg,
|
|
|
|
int callbackID)
|
2012-07-13 09:05:17 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2012-07-13 09:05:17 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventBalloonChangeNewFromDom(dom, msg->actual);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2012-07-13 09:05:17 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2012-07-13 09:05:17 +00:00
|
|
|
}
|
2012-10-12 19:13:39 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
2012-10-12 19:13:39 +00:00
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_balloon_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventBalloonChangeHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_balloon_change_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventBalloonChangeHelper(conn, &msg->msg, msg->callbackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventPMSuspendDiskHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_pmsuspend_disk_msg *msg,
|
2014-01-29 00:41:34 +00:00
|
|
|
int callbackID,
|
|
|
|
int reason)
|
2014-01-09 18:22:53 +00:00
|
|
|
{
|
2012-10-12 19:13:39 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2012-10-12 19:13:39 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
2014-01-29 00:41:34 +00:00
|
|
|
event = virDomainEventPMSuspendDiskNewFromDom(dom, reason);
|
2012-10-12 19:13:39 +00:00
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2012-10-12 19:13:39 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2012-10-12 19:13:39 +00:00
|
|
|
}
|
2013-06-19 13:27:29 +00:00
|
|
|
static void
|
2014-01-09 18:22:53 +00:00
|
|
|
remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
2013-06-19 13:27:29 +00:00
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2014-01-09 18:22:53 +00:00
|
|
|
remote_domain_event_pmsuspend_disk_msg *msg = evdata;
|
2014-01-29 00:41:34 +00:00
|
|
|
remoteDomainBuildEventPMSuspendDiskHelper(conn, msg, -1, 0);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_pmsuspend_disk_msg *msg = evdata;
|
2014-01-29 00:41:34 +00:00
|
|
|
remoteDomainBuildEventPMSuspendDiskHelper(conn, &msg->msg, msg->callbackID,
|
|
|
|
msg->reason);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventDeviceRemovedHelper(virConnectPtr conn,
|
|
|
|
remote_domain_event_device_removed_msg *msg,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2013-06-19 13:27:29 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event = NULL;
|
2013-06-19 13:27:29 +00:00
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventDeviceRemovedNewFromDom(dom, msg->devAlias);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2013-06-19 13:27:29 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
|
2014-01-09 18:22:53 +00:00
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_device_removed_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventDeviceRemovedHelper(conn, msg, -1);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_device_removed_msg *msg = evdata;
|
|
|
|
remoteDomainBuildEventDeviceRemovedHelper(conn, &msg->msg, msg->callbackID);
|
2013-06-19 13:27:29 +00:00
|
|
|
}
|
|
|
|
|
2015-03-30 16:46:21 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_device_added_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventDeviceAddedNewFromDom(dom, msg->devAlias);
|
|
|
|
|
|
|
|
virObjectUnref(dom);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2015-03-30 16:46:21 +00:00
|
|
|
}
|
2013-06-19 13:27:29 +00:00
|
|
|
|
2016-03-30 16:09:45 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
2017-01-09 15:53:07 +00:00
|
|
|
remote_domain_event_callback_device_removal_failed_msg *msg = evdata;
|
2016-03-30 16:09:45 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
if (!(dom = get_nonnull_domain(conn, msg->dom)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventDeviceRemovalFailedNewFromDom(dom, msg->devAlias);
|
|
|
|
|
|
|
|
virObjectUnref(dom);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-03-30 16:09:45 +00:00
|
|
|
}
|
|
|
|
|
2014-09-10 11:28:24 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_tunable_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virTypedParameterPtr params = NULL;
|
|
|
|
int nparams = 0;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) msg->params.params_val,
|
|
|
|
msg->params.params_len,
|
|
|
|
REMOTE_DOMAIN_EVENT_TUNABLE_MAX,
|
|
|
|
¶ms, &nparams) < 0)
|
2014-09-10 11:28:24 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom) {
|
|
|
|
virTypedParamsFree(params, nparams);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
event = virDomainEventTunableNewFromDom(dom, params, nparams);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2014-09-10 11:28:24 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2014-09-10 11:28:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-19 09:32:20 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_agent_lifecycle_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
if (!(dom = get_nonnull_domain(conn, msg->dom)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventAgentLifecycleNewFromDom(dom, msg->state,
|
|
|
|
msg->reason);
|
|
|
|
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2014-11-19 09:32:20 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2014-11-19 09:32:20 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 15:09:09 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_migration_iteration_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
if (!(dom = get_nonnull_domain(conn, msg->dom)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventMigrationIterationNewFromDom(dom, msg->iteration);
|
|
|
|
|
|
|
|
virObjectUnref(dom);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2015-12-10 15:09:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-17 20:20:11 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackJobCompleted(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_job_completed_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
virTypedParameterPtr params = NULL;
|
|
|
|
int nparams = 0;
|
|
|
|
|
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) msg->params.params_val,
|
|
|
|
msg->params.params_len,
|
|
|
|
REMOTE_DOMAIN_JOB_STATS_MAX,
|
|
|
|
¶ms, &nparams) < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(dom = get_nonnull_domain(conn, msg->dom))) {
|
|
|
|
virTypedParamsFree(params, nparams);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
event = virDomainEventJobCompletedNewFromDom(dom, params, nparams);
|
|
|
|
|
|
|
|
virObjectUnref(dom);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-02-17 20:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-22 14:41:30 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventCallbackMetadataChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_callback_metadata_change_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
if (!(dom = get_nonnull_domain(conn, msg->dom)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventMetadataChangeNewFromDom(dom, msg->type, msg->nsuri ? *msg->nsuri : NULL);
|
|
|
|
|
|
|
|
virObjectUnref(dom);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-12-22 14:41:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-11 10:38:01 +00:00
|
|
|
static void
|
|
|
|
remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_network_event_lifecycle_msg *msg = evdata;
|
|
|
|
virNetworkPtr net;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
net = get_nonnull_network(conn, msg->net);
|
|
|
|
if (!net)
|
|
|
|
return;
|
|
|
|
|
2014-01-06 12:32:55 +00:00
|
|
|
event = virNetworkEventLifecycleNew(net->name, net->uuid, msg->event,
|
|
|
|
msg->detail);
|
2014-11-25 12:42:58 +00:00
|
|
|
virObjectUnref(net);
|
2013-12-11 10:38:01 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2013-12-11 10:38:01 +00:00
|
|
|
}
|
|
|
|
|
2016-06-15 18:35:45 +00:00
|
|
|
static void
|
|
|
|
remoteStoragePoolBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_storage_pool_event_lifecycle_msg *msg = evdata;
|
|
|
|
virStoragePoolPtr pool;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
pool = get_nonnull_storage_pool(conn, msg->pool);
|
|
|
|
if (!pool)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virStoragePoolEventLifecycleNew(pool->name, pool->uuid, msg->event,
|
|
|
|
msg->detail);
|
|
|
|
virObjectUnref(pool);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-06-15 18:35:45 +00:00
|
|
|
}
|
2013-12-11 10:38:01 +00:00
|
|
|
|
2016-06-24 16:35:51 +00:00
|
|
|
static void
|
|
|
|
remoteStoragePoolBuildEventRefresh(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_storage_pool_event_refresh_msg *msg = evdata;
|
|
|
|
virStoragePoolPtr pool;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
pool = get_nonnull_storage_pool(conn, msg->pool);
|
|
|
|
if (!pool)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virStoragePoolEventRefreshNew(pool->name, pool->uuid);
|
|
|
|
virObjectUnref(pool);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-06-24 16:35:51 +00:00
|
|
|
}
|
|
|
|
|
2016-07-28 12:02:53 +00:00
|
|
|
static void
|
|
|
|
remoteNodeDeviceBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_node_device_event_lifecycle_msg *msg = evdata;
|
|
|
|
virNodeDevicePtr dev;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
dev = get_nonnull_node_device(conn, msg->dev);
|
|
|
|
if (!dev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virNodeDeviceEventLifecycleNew(dev->name, msg->event,
|
|
|
|
msg->detail);
|
|
|
|
virObjectUnref(dev);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-07-28 12:02:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-11 15:15:23 +00:00
|
|
|
static void
|
|
|
|
remoteNodeDeviceBuildEventUpdate(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_node_device_event_update_msg *msg = evdata;
|
|
|
|
virNodeDevicePtr dev;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
dev = get_nonnull_node_device(conn, msg->dev);
|
|
|
|
if (!dev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virNodeDeviceEventUpdateNew(dev->name);
|
|
|
|
virObjectUnref(dev);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-08-11 15:15:23 +00:00
|
|
|
}
|
|
|
|
|
2016-12-22 16:11:06 +00:00
|
|
|
static void
|
|
|
|
remoteSecretBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_secret_event_lifecycle_msg *msg = evdata;
|
|
|
|
virSecretPtr secret;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
secret = get_nonnull_secret(conn, msg->secret);
|
|
|
|
if (!secret)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virSecretEventLifecycleNew(secret->uuid, secret->usageType, secret->usageID,
|
|
|
|
msg->event, msg->detail);
|
|
|
|
virObjectUnref(secret);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2016-12-22 16:11:06 +00:00
|
|
|
}
|
|
|
|
|
2017-01-05 13:51:07 +00:00
|
|
|
static void
|
|
|
|
remoteSecretBuildEventValueChanged(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_secret_event_value_changed_msg *msg = evdata;
|
|
|
|
virSecretPtr secret;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
secret = get_nonnull_secret(conn, msg->secret);
|
|
|
|
if (!secret)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virSecretEventValueChangedNew(secret->uuid, secret->usageType, secret->usageID);
|
|
|
|
virObjectUnref(secret);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2017-01-05 13:51:07 +00:00
|
|
|
}
|
|
|
|
|
2014-01-29 22:30:44 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
qemu_domain_monitor_event_msg *msg = evdata;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
dom = get_nonnull_domain(conn, msg->dom);
|
|
|
|
if (!dom)
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainQemuMonitorEventNew(dom->id, dom->name, dom->uuid,
|
|
|
|
msg->event, msg->seconds,
|
|
|
|
msg->micros,
|
|
|
|
msg->details ? *msg->details : NULL);
|
2014-11-30 14:57:02 +00:00
|
|
|
virObjectUnref(dom);
|
2014-01-29 22:30:44 +00:00
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2014-01-29 22:30:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-28 02:46:01 +00:00
|
|
|
static unsigned char *
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteSecretGetValue(virSecretPtr secret, size_t *value_size,
|
|
|
|
unsigned int flags, unsigned int internalFlags)
|
2009-07-28 02:46:01 +00:00
|
|
|
{
|
|
|
|
unsigned char *rv = NULL;
|
|
|
|
remote_secret_get_value_args args;
|
|
|
|
remote_secret_get_value_ret ret;
|
2014-10-23 13:33:11 +00:00
|
|
|
struct private_data *priv = secret->conn->privateData;
|
2009-07-28 02:46:01 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDriverLock(priv);
|
2009-07-28 02:46:01 +00:00
|
|
|
|
libvirt: do not mix internal flags into public API
There were two API in driver.c that were silently masking flags
bits prior to calling out to the drivers, and several others
that were explicitly masking flags bits. This is not
forward-compatible - if we ever have that many flags in the
future, then talking to an old server that masks out the
flags would be indistinguishable from talking to a new server
that can honor the flag. In general, libvirt.c should forward
_all_ flags on to drivers, and only the drivers should reject
unknown flags.
In the case of virDrvSecretGetValue, the solution is to separate
the internal driver callback function to have two parameters
instead of one, with only one parameter affected by the public
API. In the case of virDomainGetXMLDesc, it turns out that
no one was ever mixing VIR_DOMAIN_XML_INTERNAL_STATUS with
the dumpxml path in the first place; that internal flag was
only used in saving and restoring state files, which happened
to be in functions internal to a single file, so there is no
mixing of the internal flag with a public flags argument.
Additionally, virDomainMemoryStats passed a flags argument
over RPC, but not to the driver.
* src/driver.h (VIR_DOMAIN_XML_FLAGS_MASK)
(VIR_SECRET_GET_VALUE_FLAGS_MASK): Delete.
(virDrvSecretGetValue): Separate out internal flags.
(virDrvDomainMemoryStats): Provide missing flags argument.
* src/driver.c (verify): Drop unused check.
* src/conf/domain_conf.h (virDomainObjParseFile): Delete
declaration.
(virDomainXMLInternalFlags): Move...
* src/conf/domain_conf.c: ...here. Delete redundant include.
(virDomainObjParseFile): Make static.
* src/libvirt.c (virDomainGetXMLDesc, virSecretGetValue): Update
clients.
(virDomainMemoryPeek, virInterfaceGetXMLDesc)
(virDomainMemoryStats, virDomainBlockPeek, virNetworkGetXMLDesc)
(virStoragePoolGetXMLDesc, virStorageVolGetXMLDesc)
(virNodeNumOfDevices, virNodeListDevices, virNWFilterGetXMLDesc):
Don't mask unknown flags.
* src/interface/netcf_driver.c (interfaceGetXMLDesc): Reject
unknown flags.
* src/secret/secret_driver.c (secretGetValue): Update clients.
* src/remote/remote_driver.c (remoteSecretGetValue)
(remoteDomainMemoryStats): Likewise.
* src/qemu/qemu_process.c (qemuProcessGetVolumeQcowPassphrase):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainMemoryStats): Likewise.
* daemon/remote.c (remoteDispatchDomainMemoryStats): Likewise.
2011-07-13 21:31:56 +00:00
|
|
|
/* internalFlags intentionally do not go over the wire */
|
|
|
|
if (internalFlags) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no internalFlags support"));
|
libvirt: do not mix internal flags into public API
There were two API in driver.c that were silently masking flags
bits prior to calling out to the drivers, and several others
that were explicitly masking flags bits. This is not
forward-compatible - if we ever have that many flags in the
future, then talking to an old server that masks out the
flags would be indistinguishable from talking to a new server
that can honor the flag. In general, libvirt.c should forward
_all_ flags on to drivers, and only the drivers should reject
unknown flags.
In the case of virDrvSecretGetValue, the solution is to separate
the internal driver callback function to have two parameters
instead of one, with only one parameter affected by the public
API. In the case of virDomainGetXMLDesc, it turns out that
no one was ever mixing VIR_DOMAIN_XML_INTERNAL_STATUS with
the dumpxml path in the first place; that internal flag was
only used in saving and restoring state files, which happened
to be in functions internal to a single file, so there is no
mixing of the internal flag with a public flags argument.
Additionally, virDomainMemoryStats passed a flags argument
over RPC, but not to the driver.
* src/driver.h (VIR_DOMAIN_XML_FLAGS_MASK)
(VIR_SECRET_GET_VALUE_FLAGS_MASK): Delete.
(virDrvSecretGetValue): Separate out internal flags.
(virDrvDomainMemoryStats): Provide missing flags argument.
* src/driver.c (verify): Drop unused check.
* src/conf/domain_conf.h (virDomainObjParseFile): Delete
declaration.
(virDomainXMLInternalFlags): Move...
* src/conf/domain_conf.c: ...here. Delete redundant include.
(virDomainObjParseFile): Make static.
* src/libvirt.c (virDomainGetXMLDesc, virSecretGetValue): Update
clients.
(virDomainMemoryPeek, virInterfaceGetXMLDesc)
(virDomainMemoryStats, virDomainBlockPeek, virNetworkGetXMLDesc)
(virStoragePoolGetXMLDesc, virStorageVolGetXMLDesc)
(virNodeNumOfDevices, virNodeListDevices, virNWFilterGetXMLDesc):
Don't mask unknown flags.
* src/interface/netcf_driver.c (interfaceGetXMLDesc): Reject
unknown flags.
* src/secret/secret_driver.c (secretGetValue): Update clients.
* src/remote/remote_driver.c (remoteSecretGetValue)
(remoteDomainMemoryStats): Likewise.
* src/qemu/qemu_process.c (qemuProcessGetVolumeQcowPassphrase):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainMemoryStats): Likewise.
* daemon/remote.c (remoteDispatchDomainMemoryStats): Likewise.
2011-07-13 21:31:56 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_secret(&args.secret, secret);
|
2009-07-28 02:46:01 +00:00
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_VALUE,
|
|
|
|
(xdrproc_t) xdr_remote_secret_get_value_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_secret_get_value_ret, (char *) &ret) == -1)
|
2009-07-28 02:46:01 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
*value_size = ret.value.value_len;
|
|
|
|
rv = (unsigned char *) ret.value.value_val; /* Caller frees. */
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2009-07-28 02:46:01 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2017-02-21 14:03:07 +00:00
|
|
|
static void
|
|
|
|
remoteDomainBuildEventBlockThreshold(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|
|
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
|
|
|
void *evdata, void *opaque)
|
|
|
|
{
|
|
|
|
virConnectPtr conn = opaque;
|
|
|
|
remote_domain_event_block_threshold_msg *msg = evdata;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virObjectEventPtr event = NULL;
|
|
|
|
|
|
|
|
if (!(dom = get_nonnull_domain(conn, msg->dom)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event = virDomainEventBlockThresholdNewFromDom(dom, msg->dev,
|
|
|
|
msg->path ? *msg->path : NULL,
|
|
|
|
msg->threshold, msg->excess);
|
|
|
|
|
|
|
|
virObjectUnref(dom);
|
|
|
|
|
2018-06-11 19:38:19 +00:00
|
|
|
virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
|
2017-02-21 14:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
static int
|
|
|
|
remoteStreamSend(virStreamPtr st,
|
|
|
|
const char *data,
|
|
|
|
size_t nbytes)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
|
2009-08-07 14:13:46 +00:00
|
|
|
struct private_data *priv = st->conn->privateData;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
2012-07-17 14:36:23 +00:00
|
|
|
int rv;
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetClientStreamRaiseError(privst))
|
2012-07-17 14:36:23 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses++;
|
|
|
|
remoteDriverUnlock(priv);
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
rv = virNetClientStreamSendPacket(privst,
|
|
|
|
priv->client,
|
|
|
|
VIR_NET_CONTINUE,
|
|
|
|
data,
|
|
|
|
nbytes);
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2012-07-17 14:36:23 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
2009-08-07 14:13:46 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2016-05-19 15:34:23 +00:00
|
|
|
remoteStreamRecvFlags(virStreamPtr st,
|
|
|
|
char *data,
|
|
|
|
size_t nbytes,
|
|
|
|
unsigned int flags)
|
2009-08-07 14:13:46 +00:00
|
|
|
{
|
2017-09-25 10:43:33 +00:00
|
|
|
VIR_DEBUG("st=%p data=%p nbytes=%zu flags=0x%x",
|
2016-05-19 15:34:23 +00:00
|
|
|
st, data, nbytes, flags);
|
2009-08-07 14:13:46 +00:00
|
|
|
struct private_data *priv = st->conn->privateData;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
2012-07-17 14:36:23 +00:00
|
|
|
int rv;
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2016-05-20 14:44:22 +00:00
|
|
|
virCheckFlags(VIR_STREAM_RECV_STOP_AT_HOLE, -1);
|
2016-05-19 15:34:23 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetClientStreamRaiseError(privst))
|
2012-07-17 14:36:23 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses++;
|
|
|
|
remoteDriverUnlock(priv);
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
rv = virNetClientStreamRecvPacket(privst,
|
|
|
|
priv->client,
|
|
|
|
data,
|
|
|
|
nbytes,
|
2016-05-20 11:04:29 +00:00
|
|
|
(st->flags & VIR_STREAM_NONBLOCK),
|
|
|
|
flags);
|
2010-07-23 12:24:37 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Done %d", rv);
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2012-07-17 14:36:23 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
2009-08-07 14:13:46 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-05-19 15:34:23 +00:00
|
|
|
static int
|
|
|
|
remoteStreamRecv(virStreamPtr st,
|
|
|
|
char *data,
|
|
|
|
size_t nbytes)
|
|
|
|
{
|
|
|
|
return remoteStreamRecvFlags(st, data, nbytes, 0);
|
|
|
|
}
|
|
|
|
|
2016-04-10 13:48:27 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
remoteStreamSendHole(virStreamPtr st,
|
|
|
|
long long length,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2017-09-25 10:43:33 +00:00
|
|
|
VIR_DEBUG("st=%p length=%lld flags=0x%x",
|
2016-04-10 13:48:27 +00:00
|
|
|
st, length, flags);
|
|
|
|
struct private_data *priv = st->conn->privateData;
|
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
if (virNetClientStreamRaiseError(privst))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses++;
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
rv = virNetClientStreamSendHole(privst,
|
|
|
|
priv->client,
|
|
|
|
length,
|
|
|
|
flags);
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-20 13:28:42 +00:00
|
|
|
static int
|
|
|
|
remoteStreamRecvHole(virStreamPtr st,
|
|
|
|
long long *length,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
struct private_data *priv = st->conn->privateData;
|
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
|
|
|
int rv;
|
|
|
|
|
2017-09-25 10:43:33 +00:00
|
|
|
VIR_DEBUG("st=%p length=%p flags=0x%x",
|
2016-05-20 13:28:42 +00:00
|
|
|
st, length, flags);
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
if (virNetClientStreamRaiseError(privst))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses++;
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
rv = virNetClientStreamRecvHole(priv->client, privst, length);
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
struct remoteStreamCallbackData {
|
|
|
|
virStreamPtr st;
|
|
|
|
virStreamEventCallback cb;
|
|
|
|
void *opaque;
|
|
|
|
virFreeCallback ff;
|
|
|
|
};
|
2010-07-23 12:24:37 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
static void remoteStreamEventCallback(virNetClientStreamPtr stream ATTRIBUTE_UNUSED,
|
|
|
|
int events,
|
|
|
|
void *opaque)
|
2010-07-23 12:24:37 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct remoteStreamCallbackData *cbdata = opaque;
|
2010-07-23 12:57:14 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
(cbdata->cb)(cbdata->st, events, cbdata->opaque);
|
2010-07-23 12:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
static void remoteStreamCallbackFree(void *opaque)
|
2010-07-23 12:24:37 +00:00
|
|
|
{
|
2010-12-01 16:46:36 +00:00
|
|
|
struct remoteStreamCallbackData *cbdata = opaque;
|
|
|
|
|
|
|
|
if (!cbdata->cb && cbdata->ff)
|
|
|
|
(cbdata->ff)(cbdata->opaque);
|
|
|
|
|
2014-11-30 15:19:38 +00:00
|
|
|
virObjectUnref(cbdata->st);
|
2010-12-01 16:46:36 +00:00
|
|
|
VIR_FREE(opaque);
|
2010-07-23 12:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
static int
|
2010-07-23 12:24:37 +00:00
|
|
|
remoteStreamEventAddCallback(virStreamPtr st,
|
|
|
|
int events,
|
|
|
|
virStreamEventCallback cb,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback ff)
|
2009-08-07 14:13:46 +00:00
|
|
|
{
|
2010-07-23 12:24:37 +00:00
|
|
|
struct private_data *priv = st->conn->privateData;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
2010-07-23 12:24:37 +00:00
|
|
|
int ret = -1;
|
2010-12-01 16:46:36 +00:00
|
|
|
struct remoteStreamCallbackData *cbdata;
|
2010-07-23 12:24:37 +00:00
|
|
|
|
2013-07-04 10:14:34 +00:00
|
|
|
if (VIR_ALLOC(cbdata) < 0)
|
2010-12-01 16:46:36 +00:00
|
|
|
return -1;
|
|
|
|
cbdata->cb = cb;
|
|
|
|
cbdata->opaque = opaque;
|
|
|
|
cbdata->ff = ff;
|
|
|
|
cbdata->st = st;
|
2010-07-23 12:24:37 +00:00
|
|
|
virStreamRef(st);
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverLock(priv);
|
2010-07-23 12:57:14 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if ((ret = virNetClientStreamEventAddCallback(privst,
|
|
|
|
events,
|
|
|
|
remoteStreamEventCallback,
|
|
|
|
cbdata,
|
|
|
|
remoteStreamCallbackFree)) < 0) {
|
|
|
|
VIR_FREE(cbdata);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-07-23 12:24:37 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2010-07-23 12:24:37 +00:00
|
|
|
remoteDriverUnlock(priv);
|
2013-01-22 14:41:02 +00:00
|
|
|
/* coverity[leaked_storage] - cbdata is not leaked */
|
2010-07-23 12:24:37 +00:00
|
|
|
return ret;
|
2009-08-07 14:13:46 +00:00
|
|
|
}
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
static int
|
2010-07-23 12:24:37 +00:00
|
|
|
remoteStreamEventUpdateCallback(virStreamPtr st,
|
|
|
|
int events)
|
2009-08-07 14:13:46 +00:00
|
|
|
{
|
2010-07-23 12:24:37 +00:00
|
|
|
struct private_data *priv = st->conn->privateData;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
2010-07-23 12:24:37 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
ret = virNetClientStreamEventUpdateCallback(privst, events);
|
2010-07-23 12:24:37 +00:00
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return ret;
|
|
|
|
}
|
2009-08-07 14:13:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
static int
|
2010-07-23 12:24:37 +00:00
|
|
|
remoteStreamEventRemoveCallback(virStreamPtr st)
|
2009-08-07 14:13:46 +00:00
|
|
|
{
|
2010-07-23 12:24:37 +00:00
|
|
|
struct private_data *priv = st->conn->privateData;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
2010-07-23 12:24:37 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
ret = virNetClientStreamEventRemoveCallback(privst);
|
2010-07-23 12:24:37 +00:00
|
|
|
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return ret;
|
2009-08-07 14:13:46 +00:00
|
|
|
}
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
static int
|
2017-05-31 14:58:49 +00:00
|
|
|
remoteStreamCloseInt(virStreamPtr st, bool streamAbort)
|
2009-08-07 14:13:46 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = st->conn->privateData;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr privst = st->privateData;
|
2009-08-07 14:13:46 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetClientStreamRaiseError(privst))
|
2009-08-07 14:13:46 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2012-07-17 14:36:23 +00:00
|
|
|
priv->localUses++;
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
ret = virNetClientStreamSendPacket(privst,
|
|
|
|
priv->client,
|
2017-05-31 14:58:49 +00:00
|
|
|
streamAbort ? VIR_NET_ERROR : VIR_NET_OK,
|
2010-12-01 16:46:36 +00:00
|
|
|
NULL,
|
|
|
|
0);
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2012-07-17 14:36:23 +00:00
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientRemoveStream(priv->client, privst);
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(privst);
|
2010-12-01 16:46:36 +00:00
|
|
|
st->privateData = NULL;
|
|
|
|
st->driver = NULL;
|
2009-08-07 14:13:46 +00:00
|
|
|
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
static int
|
2017-05-31 14:58:49 +00:00
|
|
|
remoteStreamFinish(virStreamPtr st)
|
2009-08-07 14:13:46 +00:00
|
|
|
{
|
2017-05-31 14:58:49 +00:00
|
|
|
return remoteStreamCloseInt(st, false);
|
|
|
|
}
|
2012-07-17 14:36:23 +00:00
|
|
|
|
2009-08-07 14:13:46 +00:00
|
|
|
|
2017-05-31 14:58:49 +00:00
|
|
|
static int
|
|
|
|
remoteStreamAbort(virStreamPtr st)
|
|
|
|
{
|
|
|
|
return remoteStreamCloseInt(st, true);
|
2009-08-07 14:13:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static virStreamDriver remoteStreamDrv = {
|
|
|
|
.streamRecv = remoteStreamRecv,
|
2016-05-19 15:34:23 +00:00
|
|
|
.streamRecvFlags = remoteStreamRecvFlags,
|
2009-08-07 14:13:46 +00:00
|
|
|
.streamSend = remoteStreamSend,
|
2016-04-10 13:48:27 +00:00
|
|
|
.streamSendHole = remoteStreamSendHole,
|
2016-05-20 13:28:42 +00:00
|
|
|
.streamRecvHole = remoteStreamRecvHole,
|
2009-08-07 14:13:46 +00:00
|
|
|
.streamFinish = remoteStreamFinish,
|
|
|
|
.streamAbort = remoteStreamAbort,
|
2013-04-22 17:26:01 +00:00
|
|
|
.streamEventAddCallback = remoteStreamEventAddCallback,
|
|
|
|
.streamEventUpdateCallback = remoteStreamEventUpdateCallback,
|
|
|
|
.streamEventRemoveCallback = remoteStreamEventRemoveCallback,
|
2009-08-07 14:13:46 +00:00
|
|
|
};
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2014-01-08 17:10:49 +00:00
|
|
|
static int
|
|
|
|
remoteConnectDomainEventRegisterAny(virConnectPtr conn,
|
|
|
|
virDomainPtr dom,
|
|
|
|
int eventID,
|
|
|
|
virConnectDomainEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
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 14:56:56 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int callbackID;
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
int count;
|
2014-01-08 14:57:25 +00:00
|
|
|
remote_nonnull_domain domain;
|
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 14:56:56 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2014-01-08 04:00:54 +00:00
|
|
|
if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
|
|
|
|
dom, eventID, callback,
|
|
|
|
opaque, freecb, false,
|
2014-01-08 14:57:25 +00:00
|
|
|
&callbackID,
|
2014-01-09 18:22:53 +00:00
|
|
|
priv->serverEventFilter)) < 0)
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
goto done;
|
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 14:56:56 +00:00
|
|
|
|
|
|
|
/* If this is the first callback for this eventID, we need to enable
|
|
|
|
* events on the server */
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
if (count == 1) {
|
2014-01-09 18:22:53 +00:00
|
|
|
if (priv->serverEventFilter) {
|
2014-01-08 14:57:25 +00:00
|
|
|
remote_connect_domain_event_callback_register_any_args args;
|
|
|
|
remote_connect_domain_event_callback_register_any_ret ret;
|
|
|
|
|
|
|
|
args.eventID = eventID;
|
|
|
|
if (dom) {
|
|
|
|
make_nonnull_domain(&domain, dom);
|
|
|
|
args.dom = &domain;
|
|
|
|
} else {
|
|
|
|
args.dom = NULL;
|
|
|
|
}
|
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 14:56:56 +00:00
|
|
|
|
2014-01-08 14:57:25 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_ret, (char *) &ret) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2014-01-08 14:57:25 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
|
|
|
ret.callbackID);
|
|
|
|
} else {
|
|
|
|
remote_connect_domain_event_register_any_args args;
|
|
|
|
|
|
|
|
args.eventID = eventID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_register_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *)NULL) == -1) {
|
|
|
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, false);
|
2014-01-08 14:57:25 +00:00
|
|
|
goto done;
|
|
|
|
}
|
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 14:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = callbackID;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
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 14:56:56 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-08 17:10:49 +00:00
|
|
|
static int
|
|
|
|
remoteConnectDomainEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int 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 14:56:56 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
int eventID;
|
2014-01-08 14:57:25 +00:00
|
|
|
int remoteID;
|
2011-12-13 11:14:46 +00:00
|
|
|
int count;
|
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 14:56:56 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2014-01-04 13:14:33 +00:00
|
|
|
if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
|
2014-01-08 14:57:25 +00:00
|
|
|
callbackID, &remoteID)) < 0)
|
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 14:56:56 +00:00
|
|
|
goto done;
|
|
|
|
|
2014-01-04 13:14:33 +00:00
|
|
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true)) < 0)
|
2011-05-13 15:00:10 +00:00
|
|
|
goto done;
|
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 14:56:56 +00:00
|
|
|
|
|
|
|
/* If that was the last callback for this eventID, we need to disable
|
|
|
|
* events on the server */
|
2011-12-13 11:14:46 +00:00
|
|
|
if (count == 0) {
|
2014-01-09 18:22:53 +00:00
|
|
|
if (priv->serverEventFilter) {
|
2014-01-08 14:57:25 +00:00
|
|
|
remote_connect_domain_event_callback_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 14:56:56 +00:00
|
|
|
|
2014-01-08 14:57:25 +00:00
|
|
|
args.callbackID = remoteID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0,
|
|
|
|
REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_callback_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
remote_connect_domain_event_deregister_any_args args;
|
|
|
|
|
|
|
|
args.eventID = eventID;
|
|
|
|
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_DEREGISTER_ANY,
|
|
|
|
(xdrproc_t) xdr_remote_connect_domain_event_deregister_any_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
}
|
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 14:56:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
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 14:56:56 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
|
2007-12-05 15:24:15 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
2010-04-17 02:09:25 +00:00
|
|
|
static int
|
2013-04-23 12:50:18 +00:00
|
|
|
remoteDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
|
2012-10-17 09:23:12 +00:00
|
|
|
char **result, unsigned int flags)
|
2010-04-17 02:09:25 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
2013-04-18 11:07:23 +00:00
|
|
|
qemu_domain_monitor_command_args args;
|
|
|
|
qemu_domain_monitor_command_ret ret;
|
2010-04-17 02:09:25 +00:00
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2011-04-22 13:40:31 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2010-04-17 02:09:25 +00:00
|
|
|
args.cmd = (char *)cmd;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2013-04-18 11:07:23 +00:00
|
|
|
if (call(domain->conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_DOMAIN_MONITOR_COMMAND,
|
|
|
|
(xdrproc_t) xdr_qemu_domain_monitor_command_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_qemu_domain_monitor_command_ret, (char *) &ret) == -1)
|
2010-04-17 02:09:25 +00:00
|
|
|
goto done;
|
|
|
|
|
2013-05-03 12:47:37 +00:00
|
|
|
if (VIR_STRDUP(*result, ret.result) < 0)
|
2010-04-17 02:09:25 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2013-04-18 11:07:23 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_qemu_domain_monitor_command_ret, (char *) &ret);
|
2010-04-17 02:09:25 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2010-04-17 02:09:25 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-02-01 14:23:40 +00:00
|
|
|
|
|
|
|
static char *
|
|
|
|
remoteDomainMigrateBegin3(virDomainPtr domain,
|
2011-05-18 09:26:30 +00:00
|
|
|
const char *xmlin,
|
2011-02-01 14:23:40 +00:00
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned long flags,
|
|
|
|
const char *dname,
|
|
|
|
unsigned long resource)
|
|
|
|
{
|
|
|
|
char *rv = NULL;
|
|
|
|
remote_domain_migrate_begin3_args args;
|
|
|
|
remote_domain_migrate_begin3_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-05-18 09:26:30 +00:00
|
|
|
args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
|
2011-02-01 14:23:40 +00:00
|
|
|
args.flags = flags;
|
|
|
|
args.dname = dname == NULL ? NULL : (char **) &dname;
|
|
|
|
args.resource = resource;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_begin3_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_begin3_ret, (char *) &ret) == -1)
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
2011-02-01 14:23:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.xml; /* caller frees */
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2011-02-01 14:23:40 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigratePrepare3(virConnectPtr dconn,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
const char *uri_in,
|
|
|
|
char **uri_out,
|
|
|
|
unsigned long flags,
|
|
|
|
const char *dname,
|
|
|
|
unsigned long resource,
|
|
|
|
const char *dom_xml)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_prepare3_args args;
|
|
|
|
remote_domain_migrate_prepare3_ret ret;
|
|
|
|
struct private_data *priv = dconn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
|
|
|
|
args.flags = flags;
|
|
|
|
args.dname = dname == NULL ? NULL : (char **) &dname;
|
|
|
|
args.resource = resource;
|
|
|
|
args.dom_xml = (char *) dom_xml;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare3_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare3_ret, (char *) &ret) == -1)
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
2011-02-01 14:23:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
if (ret.uri_out) {
|
|
|
|
if (!uri_out) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores uri_out"));
|
2011-02-01 14:23:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*uri_out = *ret.uri_out; /* Caller frees. */
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-03-16 11:37:05 +00:00
|
|
|
VIR_FREE(ret.uri_out);
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2011-02-01 14:23:40 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
if (ret.uri_out)
|
|
|
|
VIR_FREE(*ret.uri_out);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigratePrepareTunnel3(virConnectPtr dconn,
|
|
|
|
virStreamPtr st,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned long flags,
|
|
|
|
const char *dname,
|
|
|
|
unsigned long resource,
|
|
|
|
const char *dom_xml)
|
|
|
|
{
|
|
|
|
struct private_data *priv = dconn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_prepare_tunnel3_args args;
|
|
|
|
remote_domain_migrate_prepare_tunnel3_ret ret;
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientStreamPtr netst;
|
2011-02-01 14:23:40 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2016-04-12 09:38:12 +00:00
|
|
|
if (!(netst = virNetClientStreamNew(st,
|
|
|
|
priv->remoteProgram,
|
2011-06-30 15:52:13 +00:00
|
|
|
REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
|
2016-04-11 14:50:04 +00:00
|
|
|
priv->counter,
|
|
|
|
false)))
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
if (virNetClientAddStream(priv->client, netst) < 0) {
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(netst);
|
2010-12-01 16:46:36 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2011-02-01 14:23:40 +00:00
|
|
|
st->driver = &remoteStreamDrv;
|
2010-12-01 16:46:36 +00:00
|
|
|
st->privateData = netst;
|
2011-02-01 14:23:40 +00:00
|
|
|
|
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.flags = flags;
|
|
|
|
args.dname = dname == NULL ? NULL : (char **) &dname;
|
|
|
|
args.resource = resource;
|
|
|
|
args.dom_xml = (char *) dom_xml;
|
|
|
|
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_ret, (char *) &ret) == -1) {
|
2010-12-01 16:46:36 +00:00
|
|
|
virNetClientRemoveStream(priv->client, netst);
|
2012-07-30 09:14:56 +00:00
|
|
|
virObjectUnref(netst);
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
2011-02-01 14:23:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2011-02-01 14:23:40 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigratePerform3(virDomainPtr dom,
|
2011-05-18 09:26:30 +00:00
|
|
|
const char *xmlin,
|
2011-02-01 14:23:40 +00:00
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *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 13:18:53 +00:00
|
|
|
const char *dconnuri,
|
2011-02-01 14:23:40 +00:00
|
|
|
const char *uri,
|
|
|
|
unsigned long flags,
|
|
|
|
const char *dname,
|
|
|
|
unsigned long resource)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_perform3_args args;
|
|
|
|
remote_domain_migrate_perform3_ret ret;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
|
2011-05-18 09:26:30 +00:00
|
|
|
args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
|
2011-02-01 14:23:40 +00:00
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.flags = flags;
|
|
|
|
args.dname = dname == NULL ? NULL : (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 13:18:53 +00:00
|
|
|
args.uri = uri == NULL ? NULL : (char **) &uri;
|
|
|
|
args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
|
2011-02-01 14:23:40 +00:00
|
|
|
args.resource = resource;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_perform3_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_perform3_ret, (char *) &ret) == -1)
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
2011-02-01 14:23:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2011-02-01 14:23:40 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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 12:05:33 +00:00
|
|
|
static virDomainPtr
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDomainMigrateFinish3(virConnectPtr dconn,
|
|
|
|
const char *dname,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *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 13:18:53 +00:00
|
|
|
const char *dconnuri,
|
2011-02-01 14:23:40 +00:00
|
|
|
const char *uri,
|
|
|
|
unsigned long flags,
|
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 12:05:33 +00:00
|
|
|
int cancelled)
|
2011-02-01 14:23:40 +00:00
|
|
|
{
|
|
|
|
remote_domain_migrate_finish3_args args;
|
|
|
|
remote_domain_migrate_finish3_ret ret;
|
|
|
|
struct private_data *priv = dconn->privateData;
|
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 12:05:33 +00:00
|
|
|
virDomainPtr rv = NULL;
|
2011-02-01 14:23:40 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.dname = (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 13:18:53 +00:00
|
|
|
args.uri = uri == NULL ? NULL : (char **) &uri;
|
|
|
|
args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
|
2011-02-01 14:23:40 +00:00
|
|
|
args.flags = flags;
|
|
|
|
args.cancelled = cancelled;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH3,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_finish3_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_finish3_ret, (char *) &ret) == -1)
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
|
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 12:05:33 +00:00
|
|
|
rv = get_nonnull_domain(dconn, ret.dom);
|
2011-02-01 14:23:40 +00:00
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
2011-02-01 14:23:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
ret.cookie_out.cookie_out_val = NULL;
|
|
|
|
ret.cookie_out.cookie_out_len = 0;
|
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) &xdr_remote_domain_migrate_finish3_ret, (char *) &ret);
|
2011-02-01 14:23:40 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2011-02-01 14:23:40 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigrateConfirm3(virDomainPtr domain,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
unsigned long flags,
|
|
|
|
int cancelled)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_confirm3_args args;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-02-01 14:23:40 +00:00
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.cookie_in.cookie_in_val = (char *) cookiein;
|
|
|
|
args.flags = flags;
|
|
|
|
args.cancelled = cancelled;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_confirm3_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
2011-02-01 14:23:40 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-02-01 14:23:40 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-23 09:46:00 +00:00
|
|
|
static int
|
|
|
|
remoteConnectGetCPUModelNames(virConnectPtr conn,
|
|
|
|
const char *arch,
|
|
|
|
char ***models,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
size_t i;
|
|
|
|
char **retmodels = NULL;
|
|
|
|
remote_connect_get_cpu_model_names_args args;
|
|
|
|
remote_connect_get_cpu_model_names_ret ret;
|
|
|
|
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.arch = (char *) arch;
|
|
|
|
args.need_results = !!models;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_CPU_MODEL_NAMES,
|
|
|
|
(xdrproc_t) xdr_remote_connect_get_cpu_model_names_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret,
|
|
|
|
(char *) &ret) < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Check the length of the returned list carefully. */
|
|
|
|
if (ret.models.models_len > REMOTE_CONNECT_CPU_MODELS_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many model names '%d' for limit '%d'"),
|
|
|
|
ret.models.models_len,
|
|
|
|
REMOTE_CONNECT_CPU_MODELS_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (models) {
|
|
|
|
if (VIR_ALLOC_N(retmodels, ret.models.models_len + 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.models.models_len; i++) {
|
|
|
|
retmodels[i] = ret.models.models_val[i];
|
|
|
|
ret.models.models_val[i] = NULL;
|
|
|
|
}
|
|
|
|
*models = retmodels;
|
|
|
|
retmodels = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-11-25 08:18:35 +00:00
|
|
|
virStringListFree(retmodels);
|
2013-09-23 09:46:00 +00:00
|
|
|
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret, (char *) &ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-09-23 09:46:00 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-21 11:49:23 +00:00
|
|
|
static int
|
|
|
|
remoteDomainOpenGraphics(virDomainPtr dom,
|
|
|
|
unsigned int idx,
|
|
|
|
int fd,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_open_graphics_args args;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
2012-12-21 14:20:04 +00:00
|
|
|
int fdin[] = { fd };
|
|
|
|
size_t fdinlen = ARRAY_CARDINALITY(fdin);
|
2011-10-21 11:49:23 +00:00
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, dom);
|
2011-10-21 11:49:23 +00:00
|
|
|
args.idx = idx;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-12-21 14:20:04 +00:00
|
|
|
if (callFull(dom->conn, priv, 0,
|
|
|
|
fdin, fdinlen,
|
|
|
|
NULL, NULL,
|
|
|
|
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_open_graphics_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, NULL) == -1)
|
2011-10-21 11:49:23 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-10-21 11:49:23 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-25 16:55:20 +00:00
|
|
|
static int
|
|
|
|
remoteDomainOpenGraphicsFD(virDomainPtr dom,
|
|
|
|
unsigned int idx,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
2015-07-27 09:29:59 +00:00
|
|
|
remote_domain_open_graphics_fd_args args;
|
2014-08-25 16:55:20 +00:00
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
int *fdout = NULL;
|
|
|
|
size_t fdoutlen = 0;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.idx = idx;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
if (callFull(dom->conn, priv, 0,
|
|
|
|
NULL, 0,
|
|
|
|
&fdout, &fdoutlen,
|
|
|
|
REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD,
|
|
|
|
(xdrproc_t) xdr_remote_domain_open_graphics_fd_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (fdoutlen != 1) {
|
2014-08-26 22:04:37 +00:00
|
|
|
if (fdoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("too many file descriptors received"));
|
|
|
|
while (fdoutlen)
|
|
|
|
VIR_FORCE_CLOSE(fdout[--fdoutlen]);
|
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("no file descriptor received"));
|
|
|
|
}
|
2014-08-25 16:55:20 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2014-08-26 22:04:37 +00:00
|
|
|
rv = fdout[0];
|
2014-08-25 16:55:20 +00:00
|
|
|
|
|
|
|
done:
|
2014-08-26 22:04:37 +00:00
|
|
|
VIR_FREE(fdout);
|
2014-08-25 16:55:20 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-22 12:59:06 +00:00
|
|
|
static int
|
2013-04-23 12:50:18 +00:00
|
|
|
remoteConnectSetKeepAlive(virConnectPtr conn, int interval, unsigned int count)
|
2011-09-22 12:59:06 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
if (!virNetClientKeepAliveIsSupported(priv->client)) {
|
2012-07-18 13:35:21 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("the caller doesn't support keepalive protocol;"
|
|
|
|
" perhaps it's missing event loop implementation"));
|
2011-09-22 12:59:06 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!priv->serverKeepAlive) {
|
|
|
|
ret = 1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-04-24 14:38:41 +00:00
|
|
|
if (interval > 0) {
|
|
|
|
ret = virNetClientKeepAliveStart(priv->client, interval, count);
|
|
|
|
} else {
|
|
|
|
virNetClientKeepAliveStop(priv->client);
|
|
|
|
ret = 0;
|
|
|
|
}
|
2011-09-22 12:59:06 +00:00
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2011-09-22 12:59:06 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-23 06:56:13 +00:00
|
|
|
static int
|
2013-04-23 12:50:18 +00:00
|
|
|
remoteConnectIsAlive(virConnectPtr conn)
|
2011-09-23 06:56:13 +00:00
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
bool ret;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
ret = virNetClientIsOpen(priv->client);
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-31 06:42:31 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetDiskErrors(virDomainPtr dom,
|
|
|
|
virDomainDiskErrorPtr errors,
|
|
|
|
unsigned int maxerrors,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
remote_domain_get_disk_errors_args args;
|
|
|
|
remote_domain_get_disk_errors_ret ret;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.maxerrors = maxerrors;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-03-29 09:52:04 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2012-01-31 06:42:31 +00:00
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_DISK_ERRORS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_disk_errors_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_disk_errors_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (remoteDeserializeDomainDiskErrors(ret.errors.errors_val,
|
|
|
|
ret.errors.errors_len,
|
|
|
|
REMOTE_DOMAIN_DISK_ERRORS_MAX,
|
|
|
|
errors,
|
|
|
|
maxerrors) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = ret.nerrors;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-01-31 06:42:31 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_disk_errors_ret, (char *) &ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-01-31 06:42:31 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-06 19:54:32 +00:00
|
|
|
#include "remote_client_bodies.h"
|
2012-12-21 14:20:04 +00:00
|
|
|
#include "lxc_client_bodies.h"
|
2011-05-06 19:54:32 +00:00
|
|
|
#include "qemu_client_bodies.h"
|
2011-04-23 10:53:57 +00:00
|
|
|
|
2009-07-10 15:10:56 +00:00
|
|
|
/*
|
|
|
|
* Serial a set of arguments into a method call message,
|
|
|
|
* send that to the server and wait for reply
|
|
|
|
*/
|
|
|
|
static int
|
2012-12-21 14:20:04 +00:00
|
|
|
callFull(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
struct private_data *priv,
|
|
|
|
unsigned int flags,
|
|
|
|
int *fdin,
|
|
|
|
size_t fdinlen,
|
|
|
|
int **fdout,
|
|
|
|
size_t *fdoutlen,
|
|
|
|
int proc_nr,
|
|
|
|
xdrproc_t args_filter, char *args,
|
|
|
|
xdrproc_t ret_filter, char *ret)
|
2009-07-10 15:10:56 +00:00
|
|
|
{
|
2010-07-23 11:05:46 +00:00
|
|
|
int rv;
|
2012-12-21 14:20:04 +00:00
|
|
|
virNetClientProgramPtr prog;
|
2010-12-01 16:46:36 +00:00
|
|
|
int counter = priv->counter++;
|
|
|
|
virNetClientPtr client = priv->client;
|
|
|
|
priv->localUses++;
|
|
|
|
|
2012-12-21 14:20:04 +00:00
|
|
|
if (flags & REMOTE_CALL_QEMU)
|
|
|
|
prog = priv->qemuProgram;
|
|
|
|
else if (flags & REMOTE_CALL_LXC)
|
|
|
|
prog = priv->lxcProgram;
|
|
|
|
else
|
|
|
|
prog = priv->remoteProgram;
|
|
|
|
|
2010-12-01 16:46:36 +00:00
|
|
|
/* Unlock, so that if we get any async events/stream data
|
|
|
|
* while processing the RPC, we don't deadlock when our
|
|
|
|
* callbacks for those are invoked
|
|
|
|
*/
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
rv = virNetClientProgramCall(prog,
|
|
|
|
client,
|
|
|
|
counter,
|
|
|
|
proc_nr,
|
2012-12-21 14:20:04 +00:00
|
|
|
fdinlen, fdin,
|
|
|
|
fdoutlen, fdout,
|
2010-12-01 16:46:36 +00:00
|
|
|
args_filter, args,
|
|
|
|
ret_filter, ret);
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
priv->localUses--;
|
2009-07-10 15:10:56 +00:00
|
|
|
|
2010-07-23 11:05:46 +00:00
|
|
|
return rv;
|
2009-07-10 15:10:56 +00:00
|
|
|
}
|
|
|
|
|
2011-10-21 11:49:23 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
call(virConnectPtr conn,
|
|
|
|
struct private_data *priv,
|
|
|
|
unsigned int flags,
|
|
|
|
int proc_nr,
|
|
|
|
xdrproc_t args_filter, char *args,
|
|
|
|
xdrproc_t ret_filter, char *ret)
|
2011-10-21 11:49:23 +00:00
|
|
|
{
|
2012-12-21 14:20:04 +00:00
|
|
|
return callFull(conn, priv, flags,
|
|
|
|
NULL, 0,
|
|
|
|
NULL, NULL,
|
|
|
|
proc_nr,
|
|
|
|
args_filter, args,
|
|
|
|
ret_filter, ret);
|
2011-10-21 11:49:23 +00:00
|
|
|
}
|
|
|
|
|
2009-07-10 15:10:56 +00:00
|
|
|
|
2011-12-29 07:33:18 +00:00
|
|
|
static int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteDomainGetInterfaceParameters(virDomainPtr domain,
|
|
|
|
const char *device,
|
|
|
|
virTypedParameterPtr params, int *nparams,
|
|
|
|
unsigned int flags)
|
2011-12-29 07:33:18 +00:00
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_interface_parameters_args args;
|
|
|
|
remote_domain_get_interface_parameters_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
2011-12-29 07:33:18 +00:00
|
|
|
args.device = (char *)device;
|
|
|
|
args.nparams = *nparams;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_interface_parameters_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_interface_parameters_ret, (char *) &ret) == -1)
|
2011-12-29 07:33:18 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of parameters
|
|
|
|
* and is asking for the number of parameters supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_INTERFACE_PARAMETERS_MAX,
|
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2011-12-29 07:33:18 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_interface_parameters_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2011-12-29 07:33:18 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-06-10 03:24:57 +00:00
|
|
|
|
2012-09-14 14:42:15 +00:00
|
|
|
static int
|
|
|
|
remoteNodeGetMemoryParameters(virConnectPtr conn,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_get_memory_parameters_args args;
|
|
|
|
remote_node_get_memory_parameters_ret ret;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.nparams = *nparams;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_MEMORY_PARAMETERS,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_memory_parameters_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_memory_parameters_ret, (char *) &ret) == -1)
|
2012-09-14 14:42:15 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Handle the case when the caller does not know the number of parameters
|
|
|
|
* and is asking for the number of parameters supported
|
|
|
|
*/
|
|
|
|
if (*nparams == 0) {
|
|
|
|
*nparams = ret.nparams;
|
|
|
|
rv = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_NODE_MEMORY_PARAMETERS_MAX,
|
|
|
|
¶ms,
|
|
|
|
nparams) < 0)
|
2012-09-14 14:42:15 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-17 09:23:12 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_memory_parameters_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-09-14 14:42:15 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2018-06-08 14:40:54 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
remoteNodeGetSEVInfo(virConnectPtr conn,
|
|
|
|
virTypedParameterPtr *params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_get_sev_info_args args;
|
|
|
|
remote_node_get_sev_info_ret ret;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_SEV_INFO,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_sev_info_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_sev_info_ret, (char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_NODE_SEV_INFO_MAX,
|
|
|
|
params,
|
|
|
|
nparams) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_sev_info_ret, (char *) &ret);
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-16 14:05:11 +00:00
|
|
|
static int
|
|
|
|
remoteNodeGetCPUMap(virConnectPtr conn,
|
|
|
|
unsigned char **cpumap,
|
|
|
|
unsigned int *online,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_get_cpu_map_args args;
|
|
|
|
remote_node_get_cpu_map_ret ret;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
2012-11-01 23:55:43 +00:00
|
|
|
args.need_map = !!cpumap;
|
|
|
|
args.need_online = !!online;
|
2012-10-16 14:05:11 +00:00
|
|
|
args.flags = flags;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
memset(&ret, 0, sizeof(ret));
|
2012-10-16 14:05:11 +00:00
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_CPU_MAP,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_cpu_map_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_cpu_map_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.ret < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (cpumap) {
|
2013-07-04 10:14:34 +00:00
|
|
|
if (VIR_ALLOC_N(*cpumap, ret.cpumap.cpumap_len) < 0)
|
2012-10-16 14:05:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
memcpy(*cpumap, ret.cpumap.cpumap_val, ret.cpumap.cpumap_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (online)
|
|
|
|
*online = ret.online;
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2012-10-16 14:05:11 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_cpu_map_ret, (char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-10-16 14:05:11 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-12-21 14:20:04 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainLxcOpenNamespace(virDomainPtr domain,
|
|
|
|
int **fdlist,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
lxc_domain_open_namespace_args args;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
size_t nfds = 0;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
*fdlist = NULL;
|
|
|
|
|
|
|
|
if (callFull(domain->conn, priv, REMOTE_CALL_LXC,
|
|
|
|
NULL, 0,
|
|
|
|
fdlist, &nfds,
|
|
|
|
LXC_PROC_DOMAIN_OPEN_NAMESPACE,
|
|
|
|
(xdrproc_t) xdr_lxc_domain_open_namespace_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_void, NULL) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = nfds;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2012-12-21 14:20:04 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-01-30 09:49:28 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetJobStats(virDomainPtr domain,
|
|
|
|
int *type,
|
|
|
|
virTypedParameterPtr *params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_get_job_stats_args args;
|
|
|
|
remote_domain_get_job_stats_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_JOB_STATS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_job_stats_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_job_stats_ret, (char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
*type = ret.type;
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val,
|
|
|
|
ret.params.params_len,
|
|
|
|
REMOTE_DOMAIN_JOB_STATS_MAX,
|
|
|
|
params, nparams) < 0)
|
2013-01-30 09:49:28 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2013-01-30 09:49:28 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_get_job_stats_ret,
|
|
|
|
(char *) &ret);
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-01-30 09:49:28 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2012-12-21 14:20:04 +00:00
|
|
|
|
2013-05-29 07:47:13 +00:00
|
|
|
static char *
|
|
|
|
remoteDomainMigrateBegin3Params(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
char *rv = NULL;
|
|
|
|
remote_domain_migrate_begin3_params_args args;
|
|
|
|
remote_domain_migrate_begin3_params_ret ret;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.flags = flags;
|
|
|
|
|
2013-08-19 13:55:21 +00:00
|
|
|
if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many migration parameters '%d' for limit '%d'"),
|
|
|
|
nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-02-02 13:13:15 +00:00
|
|
|
if (virTypedParamsSerialize(params, nparams,
|
|
|
|
(virTypedParameterRemotePtr *) &args.params.params_val,
|
2016-02-05 19:24:05 +00:00
|
|
|
&args.params.params_len,
|
|
|
|
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
|
2013-05-29 07:47:13 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_migrate_begin3_params_args,
|
|
|
|
(char *) &args);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3_PARAMS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_begin3_params_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_begin3_params_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.xml; /* caller frees */
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-02-02 12:19:35 +00:00
|
|
|
virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val,
|
|
|
|
args.params.params_len);
|
2013-05-29 07:47:13 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2013-05-29 07:47:13 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigratePrepare3Params(virConnectPtr dconn,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
char **uri_out,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_prepare3_params_args args;
|
|
|
|
remote_domain_migrate_prepare3_params_ret ret;
|
|
|
|
struct private_data *priv = dconn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2013-08-19 13:55:21 +00:00
|
|
|
if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many migration parameters '%d' for limit '%d'"),
|
|
|
|
nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-02-02 13:13:15 +00:00
|
|
|
if (virTypedParamsSerialize(params, nparams,
|
|
|
|
(virTypedParameterRemotePtr *) &args.params.params_val,
|
2016-02-05 19:24:05 +00:00
|
|
|
&args.params.params_len,
|
|
|
|
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
|
2013-05-29 07:47:13 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare3_params_args,
|
|
|
|
(char *) &args);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3_PARAMS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare3_params_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare3_params_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
if (ret.uri_out) {
|
|
|
|
if (!uri_out) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores uri_out"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*uri_out = *ret.uri_out; /* Caller frees. */
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-02-02 12:19:35 +00:00
|
|
|
virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val,
|
|
|
|
args.params.params_len);
|
2013-05-29 07:47:13 +00:00
|
|
|
VIR_FREE(ret.uri_out);
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2013-05-29 07:47:13 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
if (ret.uri_out)
|
|
|
|
VIR_FREE(*ret.uri_out);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
|
|
|
|
virStreamPtr st,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
struct private_data *priv = dconn->privateData;
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_prepare_tunnel3_params_args args;
|
|
|
|
remote_domain_migrate_prepare_tunnel3_params_ret ret;
|
|
|
|
virNetClientStreamPtr netst;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2013-08-19 13:55:21 +00:00
|
|
|
if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many migration parameters '%d' for limit '%d'"),
|
|
|
|
nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-29 07:47:13 +00:00
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2016-02-02 13:13:15 +00:00
|
|
|
if (virTypedParamsSerialize(params, nparams,
|
|
|
|
(virTypedParameterRemotePtr *) &args.params.params_val,
|
2016-02-05 19:24:05 +00:00
|
|
|
&args.params.params_len,
|
|
|
|
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
|
2013-05-29 07:47:13 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_args,
|
|
|
|
(char *) &args);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-04-12 09:38:12 +00:00
|
|
|
if (!(netst = virNetClientStreamNew(st,
|
|
|
|
priv->remoteProgram,
|
2013-05-29 07:47:13 +00:00
|
|
|
REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3_PARAMS,
|
2016-04-11 14:50:04 +00:00
|
|
|
priv->counter,
|
|
|
|
false)))
|
2013-05-29 07:47:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetClientAddStream(priv->client, netst) < 0) {
|
|
|
|
virObjectUnref(netst);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
st->driver = &remoteStreamDrv;
|
|
|
|
st->privateData = netst;
|
|
|
|
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3_PARAMS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_ret,
|
|
|
|
(char *) &ret) == -1) {
|
|
|
|
virNetClientRemoveStream(priv->client, netst);
|
|
|
|
virObjectUnref(netst);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-02-02 12:19:35 +00:00
|
|
|
virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val,
|
|
|
|
args.params.params_len);
|
2013-05-29 07:47:13 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2013-05-29 07:47:13 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigratePerform3Params(virDomainPtr dom,
|
|
|
|
const char *dconnuri,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_perform3_params_args args;
|
|
|
|
remote_domain_migrate_perform3_params_ret ret;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2013-08-19 13:55:21 +00:00
|
|
|
if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many migration parameters '%d' for limit '%d'"),
|
|
|
|
nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-29 07:47:13 +00:00
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
|
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.flags = flags;
|
|
|
|
|
2016-02-02 13:13:15 +00:00
|
|
|
if (virTypedParamsSerialize(params, nparams,
|
|
|
|
(virTypedParameterRemotePtr *) &args.params.params_val,
|
2016-02-05 19:24:05 +00:00
|
|
|
&args.params.params_len,
|
|
|
|
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
|
2013-05-29 07:47:13 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_migrate_perform3_params_args,
|
|
|
|
(char *) &args);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3_PARAMS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_perform3_params_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_perform3_params_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-02-02 12:19:35 +00:00
|
|
|
virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val,
|
|
|
|
args.params.params_len);
|
2013-05-29 07:47:13 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2013-05-29 07:47:13 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static virDomainPtr
|
|
|
|
remoteDomainMigrateFinish3Params(virConnectPtr dconn,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned int flags,
|
|
|
|
int cancelled)
|
|
|
|
{
|
|
|
|
remote_domain_migrate_finish3_params_args args;
|
|
|
|
remote_domain_migrate_finish3_params_ret ret;
|
|
|
|
struct private_data *priv = dconn->privateData;
|
|
|
|
virDomainPtr rv = NULL;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
2013-08-19 13:55:21 +00:00
|
|
|
if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many migration parameters '%d' for limit '%d'"),
|
|
|
|
nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-29 07:47:13 +00:00
|
|
|
args.cookie_in.cookie_in_val = (char *)cookiein;
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.flags = flags;
|
|
|
|
args.cancelled = cancelled;
|
|
|
|
|
2016-02-02 13:13:15 +00:00
|
|
|
if (virTypedParamsSerialize(params, nparams,
|
|
|
|
(virTypedParameterRemotePtr *) &args.params.params_val,
|
2016-02-05 19:24:05 +00:00
|
|
|
&args.params.params_len,
|
|
|
|
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
|
2013-05-29 07:47:13 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_migrate_finish3_params_args,
|
|
|
|
(char *) &args);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH3_PARAMS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_finish3_params_args,
|
|
|
|
(char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_finish3_params_ret,
|
|
|
|
(char *) &ret) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = get_nonnull_domain(dconn, ret.dom);
|
|
|
|
|
|
|
|
if (ret.cookie_out.cookie_out_len > 0) {
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("caller ignores cookieout or cookieoutlen"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
|
|
|
|
*cookieoutlen = ret.cookie_out.cookie_out_len;
|
|
|
|
ret.cookie_out.cookie_out_val = NULL;
|
|
|
|
ret.cookie_out.cookie_out_len = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
xdr_free((xdrproc_t) &xdr_remote_domain_migrate_finish3_params_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-02-02 12:19:35 +00:00
|
|
|
virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val,
|
|
|
|
args.params.params_len);
|
2013-05-29 07:47:13 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
error:
|
2013-05-29 07:47:13 +00:00
|
|
|
VIR_FREE(ret.cookie_out.cookie_out_val);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainMigrateConfirm3Params(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
unsigned int flags,
|
|
|
|
int cancelled)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_domain_migrate_confirm3_params_args args;
|
|
|
|
struct private_data *priv = domain->conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
2013-08-19 13:55:21 +00:00
|
|
|
if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("Too many migration parameters '%d' for limit '%d'"),
|
|
|
|
nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-29 07:47:13 +00:00
|
|
|
make_nonnull_domain(&args.dom, domain);
|
|
|
|
args.cookie_in.cookie_in_len = cookieinlen;
|
|
|
|
args.cookie_in.cookie_in_val = (char *) cookiein;
|
|
|
|
args.flags = flags;
|
|
|
|
args.cancelled = cancelled;
|
|
|
|
|
2016-02-02 13:13:15 +00:00
|
|
|
if (virTypedParamsSerialize(params, nparams,
|
|
|
|
(virTypedParameterRemotePtr *) &args.params.params_val,
|
2016-02-05 19:24:05 +00:00
|
|
|
&args.params.params_len,
|
|
|
|
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
|
2013-05-29 07:47:13 +00:00
|
|
|
xdr_free((xdrproc_t) xdr_remote_domain_migrate_confirm3_params_args,
|
|
|
|
(char *) &args);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3_PARAMS,
|
|
|
|
(xdrproc_t) xdr_remote_domain_migrate_confirm3_params_args,
|
|
|
|
(char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
cleanup:
|
2016-02-02 12:19:35 +00:00
|
|
|
virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val,
|
|
|
|
args.params.params_len);
|
2013-05-29 07:47:13 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-09 17:03:18 +00:00
|
|
|
static virDomainPtr
|
|
|
|
remoteDomainCreateXMLWithFiles(virConnectPtr conn, const char *xml_desc,
|
|
|
|
unsigned int nfiles, int *files, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainPtr rv = NULL;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
remote_domain_create_xml_with_files_args args;
|
|
|
|
remote_domain_create_xml_with_files_ret ret;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
args.xml_desc = (char *)xml_desc;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (callFull(conn, priv, 0,
|
|
|
|
files, nfiles,
|
|
|
|
NULL, NULL,
|
|
|
|
REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES,
|
|
|
|
(xdrproc_t)xdr_remote_domain_create_xml_with_files_args, (char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_domain_create_xml_with_files_ret, (char *)&ret) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = get_nonnull_domain(conn, ret.dom);
|
|
|
|
xdr_free((xdrproc_t)xdr_remote_domain_create_xml_with_files_ret, (char *)&ret);
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-07-09 17:03:18 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteDomainCreateWithFiles(virDomainPtr dom,
|
|
|
|
unsigned int nfiles, int *files,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
remote_domain_create_with_files_args args;
|
|
|
|
remote_domain_create_with_files_ret ret;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (callFull(dom->conn, priv, 0,
|
|
|
|
files, nfiles,
|
|
|
|
NULL, NULL,
|
|
|
|
REMOTE_PROC_DOMAIN_CREATE_WITH_FILES,
|
|
|
|
(xdrproc_t)xdr_remote_domain_create_with_files_args, (char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_domain_create_with_files_ret, (char *)&ret) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
dom->id = ret.dom.id;
|
|
|
|
xdr_free((xdrproc_t) &xdr_remote_domain_create_with_files_ret, (char *) &ret);
|
|
|
|
rv = 0;
|
|
|
|
|
2014-03-25 06:54:27 +00:00
|
|
|
done:
|
2013-07-09 17:03:18 +00:00
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2014-04-02 16:25:07 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetTime(virDomainPtr dom,
|
|
|
|
long long *seconds,
|
|
|
|
unsigned int *nseconds,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
remote_domain_get_time_args args;
|
|
|
|
remote_domain_get_time_ret ret;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
*seconds = *nseconds = 0;
|
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_TIME,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_time_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_domain_get_time_ret, (char *) &ret) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
*seconds = ret.seconds;
|
|
|
|
*nseconds = ret.nseconds;
|
|
|
|
xdr_free((xdrproc_t) &xdr_remote_domain_get_time_ret, (char *) &ret);
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-01-20 16:36:34 +00:00
|
|
|
|
2014-06-09 15:14:47 +00:00
|
|
|
static int
|
|
|
|
remoteNodeGetFreePages(virConnectPtr conn,
|
|
|
|
unsigned int npages,
|
|
|
|
unsigned int *pages,
|
|
|
|
int startCell,
|
|
|
|
unsigned int cellCount,
|
|
|
|
unsigned long long *counts,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_get_free_pages_args args;
|
|
|
|
remote_node_get_free_pages_ret ret;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (npages * cellCount > REMOTE_NODE_MAX_CELLS) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("too many NUMA cells: %d > %d"),
|
|
|
|
npages * cellCount, REMOTE_NODE_MAX_CELLS);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2014-09-25 09:18:50 +00:00
|
|
|
args.pages.pages_val = (u_int *) pages;
|
2014-06-09 15:14:47 +00:00
|
|
|
args.pages.pages_len = npages;
|
|
|
|
args.startCell = startCell;
|
|
|
|
args.cellCount = cellCount;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_FREE_PAGES,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_free_pages_args, (char *)&args,
|
|
|
|
(xdrproc_t) xdr_remote_node_get_free_pages_ret, (char *)&ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
memcpy(counts, ret.counts.counts_val, ret.counts.counts_len * sizeof(*counts));
|
|
|
|
|
|
|
|
xdr_free((xdrproc_t) xdr_remote_node_get_free_pages_ret, (char *) &ret);
|
|
|
|
|
|
|
|
rv = ret.counts.counts_len;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-23 21:01:50 +00:00
|
|
|
/* Copy contents of remote_network_dhcp_lease to virNetworkDHCPLeasePtr */
|
|
|
|
static int
|
|
|
|
remoteSerializeDHCPLease(virNetworkDHCPLeasePtr lease_dst, remote_network_dhcp_lease *lease_src)
|
|
|
|
{
|
|
|
|
lease_dst->expirytime = lease_src->expirytime;
|
|
|
|
lease_dst->type = lease_src->type;
|
|
|
|
lease_dst->prefix = lease_src->prefix;
|
|
|
|
|
2014-06-24 12:23:59 +00:00
|
|
|
if (VIR_STRDUP(lease_dst->iface, lease_src->iface) < 0)
|
2014-06-23 21:01:50 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(lease_dst->ipaddr, lease_src->ipaddr) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (lease_src->mac) {
|
|
|
|
if (VIR_STRDUP(lease_dst->mac, *lease_src->mac) < 0)
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
lease_src->mac = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lease_src->iaid) {
|
|
|
|
if (VIR_STRDUP(lease_dst->iaid, *lease_src->iaid) < 0)
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
lease_src->iaid = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lease_src->hostname) {
|
|
|
|
if (VIR_STRDUP(lease_dst->hostname, *lease_src->hostname) < 0)
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
lease_src->hostname = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lease_src->clientid) {
|
|
|
|
if (VIR_STRDUP(lease_dst->clientid, *lease_src->clientid) < 0)
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
lease_src->clientid = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virNetworkDHCPLeaseFree(lease_dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteNetworkGetDHCPLeases(virNetworkPtr net,
|
2014-06-26 14:08:34 +00:00
|
|
|
const char *mac,
|
2014-06-23 21:01:50 +00:00
|
|
|
virNetworkDHCPLeasePtr **leases,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
size_t i;
|
2014-10-23 13:33:11 +00:00
|
|
|
struct private_data *priv = net->conn->privateData;
|
2014-06-23 21:01:50 +00:00
|
|
|
remote_network_get_dhcp_leases_args args;
|
|
|
|
remote_network_get_dhcp_leases_ret ret;
|
|
|
|
|
|
|
|
virNetworkDHCPLeasePtr *leases_ret = NULL;
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_network(&args.net, net);
|
2014-06-26 14:08:34 +00:00
|
|
|
args.mac = mac ? (char **) &mac : NULL;
|
2014-06-23 21:01:50 +00:00
|
|
|
args.flags = flags;
|
|
|
|
args.need_results = !!leases;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_DHCP_LEASES,
|
|
|
|
(xdrproc_t)xdr_remote_network_get_dhcp_leases_args, (char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_network_get_dhcp_leases_ret, (char *)&ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.leases.leases_len > REMOTE_NETWORK_DHCP_LEASES_MAX) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Number of leases is %d, which exceeds max limit: %d"),
|
|
|
|
ret.leases.leases_len, REMOTE_NETWORK_DHCP_LEASES_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (leases) {
|
|
|
|
if (ret.leases.leases_len &&
|
|
|
|
VIR_ALLOC_N(leases_ret, ret.leases.leases_len + 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.leases.leases_len; i++) {
|
|
|
|
if (VIR_ALLOC(leases_ret[i]) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (remoteSerializeDHCPLease(leases_ret[i], &ret.leases.leases_val[i]) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*leases = leases_ret;
|
|
|
|
leases_ret = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (leases_ret) {
|
|
|
|
for (i = 0; i < ret.leases.leases_len; i++)
|
|
|
|
virNetworkDHCPLeaseFree(leases_ret[i]);
|
|
|
|
VIR_FREE(leases_ret);
|
|
|
|
}
|
|
|
|
xdr_free((xdrproc_t)xdr_remote_network_get_dhcp_leases_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-25 11:22:13 +00:00
|
|
|
static int
|
|
|
|
remoteConnectGetAllDomainStats(virConnectPtr conn,
|
|
|
|
virDomainPtr *doms,
|
|
|
|
unsigned int ndoms,
|
|
|
|
unsigned int stats,
|
|
|
|
virDomainStatsRecordPtr **retStats,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2014-10-23 13:33:11 +00:00
|
|
|
struct private_data *priv = conn->privateData;
|
2014-08-25 11:22:13 +00:00
|
|
|
int rv = -1;
|
|
|
|
size_t i;
|
|
|
|
remote_connect_get_all_domain_stats_args args;
|
|
|
|
remote_connect_get_all_domain_stats_ret ret;
|
2014-09-02 13:16:47 +00:00
|
|
|
virDomainStatsRecordPtr elem = NULL;
|
2014-08-25 11:22:13 +00:00
|
|
|
virDomainStatsRecordPtr *tmpret = NULL;
|
|
|
|
|
2014-10-24 04:03:13 +00:00
|
|
|
memset(&args, 0, sizeof(args));
|
|
|
|
|
2014-08-25 11:22:13 +00:00
|
|
|
if (ndoms) {
|
|
|
|
if (VIR_ALLOC_N(args.doms.doms_val, ndoms) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ndoms; i++)
|
|
|
|
make_nonnull_domain(args.doms.doms_val + i, doms[i]);
|
|
|
|
}
|
|
|
|
args.doms.doms_len = ndoms;
|
|
|
|
|
|
|
|
args.stats = stats;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS,
|
|
|
|
(xdrproc_t)xdr_remote_connect_get_all_domain_stats_args, (char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_connect_get_all_domain_stats_ret, (char *)&ret) == -1) {
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
if (ret.retStats.retStats_len > REMOTE_DOMAIN_LIST_MAX) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Number of stats entries is %d, which exceeds max limit: %d"),
|
|
|
|
ret.retStats.retStats_len, REMOTE_DOMAIN_LIST_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*retStats = NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(tmpret, ret.retStats.retStats_len + 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.retStats.retStats_len; i++) {
|
|
|
|
remote_domain_stats_record *rec = ret.retStats.retStats_val + i;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(elem) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(elem->dom = get_nonnull_domain(conn, rec->dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-01-28 16:27:42 +00:00
|
|
|
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) rec->params.params_val,
|
|
|
|
rec->params.params_len,
|
|
|
|
REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX,
|
|
|
|
&elem->params,
|
|
|
|
&elem->nparams))
|
2014-08-25 11:22:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
tmpret[i] = elem;
|
2014-09-02 13:16:47 +00:00
|
|
|
elem = NULL;
|
2014-08-25 11:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*retStats = tmpret;
|
|
|
|
tmpret = NULL;
|
|
|
|
rv = ret.retStats.retStats_len;
|
|
|
|
|
|
|
|
cleanup:
|
2014-09-02 13:16:47 +00:00
|
|
|
if (elem) {
|
|
|
|
virObjectUnref(elem->dom);
|
|
|
|
VIR_FREE(elem);
|
|
|
|
}
|
2014-08-25 11:22:13 +00:00
|
|
|
virDomainStatsRecordListFree(tmpret);
|
2014-11-05 11:34:51 +00:00
|
|
|
VIR_FREE(args.doms.doms_val);
|
2014-08-25 11:22:13 +00:00
|
|
|
xdr_free((xdrproc_t)xdr_remote_connect_get_all_domain_stats_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2014-09-16 16:17:22 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
remoteNodeAllocPages(virConnectPtr conn,
|
|
|
|
unsigned int npages,
|
|
|
|
unsigned int *pageSizes,
|
|
|
|
unsigned long long *pageCounts,
|
|
|
|
int startCell,
|
|
|
|
unsigned int cellCount,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
remote_node_alloc_pages_args args;
|
|
|
|
remote_node_alloc_pages_ret ret;
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (npages > REMOTE_NODE_MAX_CELLS) {
|
|
|
|
virReportError(VIR_ERR_RPC,
|
|
|
|
_("too many NUMA cells: %d > %d"),
|
|
|
|
npages, REMOTE_NODE_MAX_CELLS);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
args.pageSizes.pageSizes_val = (u_int *) pageSizes;
|
|
|
|
args.pageSizes.pageSizes_len = npages;
|
|
|
|
args.pageCounts.pageCounts_val = (uint64_t *) pageCounts;
|
|
|
|
args.pageCounts.pageCounts_len = npages;
|
|
|
|
args.startCell = startCell;
|
|
|
|
args.cellCount = cellCount;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
if (call(conn, priv, 0, REMOTE_PROC_NODE_ALLOC_PAGES,
|
|
|
|
(xdrproc_t) xdr_remote_node_alloc_pages_args, (char *) &args,
|
|
|
|
(xdrproc_t) xdr_remote_node_alloc_pages_ret, (char *) &ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-22 01:27:31 +00:00
|
|
|
static int
|
|
|
|
remoteDomainGetFSInfo(virDomainPtr dom,
|
|
|
|
virDomainFSInfoPtr **info,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
size_t i, j, len;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
remote_domain_get_fsinfo_args args;
|
|
|
|
remote_domain_get_fsinfo_ret ret;
|
|
|
|
remote_domain_fsinfo *src;
|
|
|
|
virDomainFSInfoPtr *info_ret = NULL;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_FSINFO,
|
|
|
|
(xdrproc_t)xdr_remote_domain_get_fsinfo_args, (char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_domain_get_fsinfo_ret, (char *)&ret) == -1)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ret.info.info_len > REMOTE_DOMAIN_FSINFO_MAX) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Too many mountpoints in fsinfo: %d for limit %d"),
|
|
|
|
ret.info.info_len, REMOTE_DOMAIN_FSINFO_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info) {
|
|
|
|
if (!ret.info.info_len) {
|
|
|
|
*info = NULL;
|
|
|
|
rv = ret.ret;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(info_ret, ret.info.info_len) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.info.info_len; i++) {
|
|
|
|
src = &ret.info.info_val[i];
|
|
|
|
|
|
|
|
if (VIR_ALLOC(info_ret[i]) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(info_ret[i]->mountpoint, src->mountpoint) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(info_ret[i]->name, src->name) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(info_ret[i]->fstype, src->fstype) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
len = src->dev_aliases.dev_aliases_len;
|
|
|
|
info_ret[i]->ndevAlias = len;
|
|
|
|
if (len &&
|
|
|
|
VIR_ALLOC_N(info_ret[i]->devAlias, len) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (j = 0; j < len; j++) {
|
|
|
|
if (VIR_STRDUP(info_ret[i]->devAlias[j],
|
|
|
|
src->dev_aliases.dev_aliases_val[j]) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*info = info_ret;
|
|
|
|
info_ret = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.ret;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (info_ret) {
|
|
|
|
for (i = 0; i < ret.info.info_len; i++)
|
|
|
|
virDomainFSInfoFree(info_ret[i]);
|
|
|
|
VIR_FREE(info_ret);
|
|
|
|
}
|
|
|
|
xdr_free((xdrproc_t)xdr_remote_domain_get_fsinfo_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-25 18:38:47 +00:00
|
|
|
static int
|
|
|
|
remoteDomainInterfaceAddresses(virDomainPtr dom,
|
|
|
|
virDomainInterfacePtr **ifaces,
|
|
|
|
unsigned int source,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
size_t i, j;
|
|
|
|
|
|
|
|
virDomainInterfacePtr *ifaces_ret = NULL;
|
|
|
|
remote_domain_interface_addresses_args args;
|
|
|
|
remote_domain_interface_addresses_ret ret;
|
|
|
|
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
|
|
|
|
args.source = source;
|
|
|
|
args.flags = flags;
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES,
|
|
|
|
(xdrproc_t)xdr_remote_domain_interface_addresses_args,
|
|
|
|
(char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_domain_interface_addresses_ret,
|
|
|
|
(char *)&ret) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.ifaces.ifaces_len > REMOTE_DOMAIN_INTERFACE_MAX) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Number of interfaces, %d exceeds the max limit: %d"),
|
|
|
|
ret.ifaces.ifaces_len, REMOTE_DOMAIN_INTERFACE_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret.ifaces.ifaces_len &&
|
|
|
|
VIR_ALLOC_N(ifaces_ret, ret.ifaces.ifaces_len) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ret.ifaces.ifaces_len; i++) {
|
|
|
|
virDomainInterfacePtr iface;
|
|
|
|
remote_domain_interface *iface_ret = &(ret.ifaces.ifaces_val[i]);
|
|
|
|
|
|
|
|
if (VIR_ALLOC(ifaces_ret[i]) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
iface = ifaces_ret[i];
|
|
|
|
|
|
|
|
if (VIR_STRDUP(iface->name, iface_ret->name) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-03-17 16:18:02 +00:00
|
|
|
if (iface_ret->hwaddr &&
|
|
|
|
VIR_STRDUP(iface->hwaddr, *iface_ret->hwaddr) < 0)
|
2015-01-25 18:38:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (iface_ret->addrs.addrs_len > REMOTE_DOMAIN_IP_ADDR_MAX) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Number of interfaces, %d exceeds the max limit: %d"),
|
|
|
|
iface_ret->addrs.addrs_len, REMOTE_DOMAIN_IP_ADDR_MAX);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
iface->naddrs = iface_ret->addrs.addrs_len;
|
|
|
|
|
|
|
|
if (iface->naddrs) {
|
|
|
|
if (VIR_ALLOC_N(iface->addrs, iface->naddrs) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (j = 0; j < iface->naddrs; j++) {
|
|
|
|
virDomainIPAddressPtr ip_addr = &(iface->addrs[j]);
|
|
|
|
remote_domain_ip_addr *ip_addr_ret =
|
|
|
|
&(iface_ret->addrs.addrs_val[j]);
|
|
|
|
|
|
|
|
if (VIR_STRDUP(ip_addr->addr, ip_addr_ret->addr) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ip_addr->prefix = ip_addr_ret->prefix;
|
|
|
|
ip_addr->type = ip_addr_ret->type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*ifaces = ifaces_ret;
|
|
|
|
ifaces_ret = NULL;
|
|
|
|
|
|
|
|
rv = ret.ifaces.ifaces_len;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ifaces_ret) {
|
|
|
|
for (i = 0; i < ret.ifaces.ifaces_len; i++)
|
|
|
|
virDomainInterfaceFree(ifaces_ret[i]);
|
|
|
|
VIR_FREE(ifaces_ret);
|
|
|
|
}
|
|
|
|
xdr_free((xdrproc_t)xdr_remote_domain_interface_addresses_ret,
|
|
|
|
(char *) &ret);
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-03-01 14:17:38 +00:00
|
|
|
static int
|
|
|
|
remoteConnectRegisterCloseCallback(virConnectPtr conn,
|
|
|
|
virConnectCloseFunc cb,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != NULL) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("A close callback is already registered"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-02-17 12:15:02 +00:00
|
|
|
if (priv->serverCloseCallback &&
|
2016-06-24 14:32:37 +00:00
|
|
|
call(conn, priv, 0, REMOTE_PROC_CONNECT_REGISTER_CLOSE_CALLBACK,
|
2016-02-17 12:15:02 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-03-01 14:17:38 +00:00
|
|
|
virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb,
|
|
|
|
opaque, freecb);
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
remoteConnectUnregisterCloseCallback(virConnectPtr conn,
|
|
|
|
virConnectCloseFunc cb)
|
|
|
|
{
|
|
|
|
struct private_data *priv = conn->privateData;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != cb) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("A different callback was requested"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-02-17 12:15:02 +00:00
|
|
|
if (priv->serverCloseCallback &&
|
2016-06-24 14:32:37 +00:00
|
|
|
call(conn, priv, 0, REMOTE_PROC_CONNECT_UNREGISTER_CLOSE_CALLBACK,
|
2016-02-17 12:15:02 +00:00
|
|
|
(xdrproc_t) xdr_void, (char *) NULL,
|
|
|
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-03-01 14:17:38 +00:00
|
|
|
virConnectCloseCallbackDataUnregister(priv->closeCallback, cb);
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2015-01-25 18:38:47 +00:00
|
|
|
|
2015-08-27 10:43:15 +00:00
|
|
|
static int
|
|
|
|
remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = dom->conn->privateData;
|
|
|
|
remote_domain_rename_args args;
|
|
|
|
remote_domain_rename_ret ret;
|
|
|
|
char *tmp = NULL;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(tmp, new_name) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_domain(&args.dom, dom);
|
|
|
|
args.new_name = new_name ? (char **)&new_name : NULL;
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_RENAME,
|
|
|
|
(xdrproc_t)xdr_remote_domain_rename_args, (char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_domain_rename_ret, (char *)&ret) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ret.retcode;
|
|
|
|
|
|
|
|
if (rv == 0) {
|
|
|
|
VIR_FREE(dom->name);
|
|
|
|
dom->name = tmp;
|
|
|
|
tmp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-29 15:44:36 +00:00
|
|
|
static int
|
|
|
|
remoteStorageVolGetInfoFlags(virStorageVolPtr vol,
|
|
|
|
virStorageVolInfoPtr result,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int rv = -1;
|
|
|
|
struct private_data *priv = vol->conn->privateData;
|
|
|
|
remote_storage_vol_get_info_flags_args args;
|
|
|
|
remote_storage_vol_get_info_flags_ret ret;
|
|
|
|
|
|
|
|
remoteDriverLock(priv);
|
|
|
|
|
|
|
|
make_nonnull_storage_vol(&args.vol, vol);
|
|
|
|
args.flags = flags;
|
|
|
|
|
|
|
|
memset(&ret, 0, sizeof(ret));
|
|
|
|
|
|
|
|
if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_INFO_FLAGS,
|
|
|
|
(xdrproc_t)xdr_remote_storage_vol_get_info_flags_args,
|
|
|
|
(char *)&args,
|
|
|
|
(xdrproc_t)xdr_remote_storage_vol_get_info_flags_ret,
|
|
|
|
(char *)&ret) == -1) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
result->type = ret.type;
|
|
|
|
result->capacity = ret.capacity;
|
|
|
|
result->allocation = ret.allocation;
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
done:
|
|
|
|
remoteDriverUnlock(priv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-01 14:23:40 +00:00
|
|
|
/* get_nonnull_domain and get_nonnull_network turn an on-wire
|
|
|
|
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
|
|
|
|
* These can return NULL if underlying memory allocations fail,
|
|
|
|
* but if they do then virterror_internal.has been set.
|
|
|
|
*/
|
|
|
|
static virDomainPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_domain(virConnectPtr conn, remote_nonnull_domain domain)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2017-03-28 15:08:03 +00:00
|
|
|
return virGetDomain(conn, domain.name, BAD_CAST domain.uuid, domain.id);
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virNetworkPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_network(virConnectPtr conn, remote_nonnull_network network)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2012-10-17 09:23:12 +00:00
|
|
|
return virGetNetwork(conn, network.name, BAD_CAST network.uuid);
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2009-05-20 14:26:49 +00:00
|
|
|
static virInterfacePtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_interface(virConnectPtr conn, remote_nonnull_interface iface)
|
2009-05-20 14:26:49 +00:00
|
|
|
{
|
2012-10-17 09:23:12 +00:00
|
|
|
return virGetInterface(conn, iface.name, iface.mac);
|
2009-05-20 14:26:49 +00:00
|
|
|
}
|
|
|
|
|
2008-02-20 15:23:36 +00:00
|
|
|
static virStoragePoolPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_storage_pool(virConnectPtr conn, remote_nonnull_storage_pool pool)
|
2008-02-20 15:23:36 +00:00
|
|
|
{
|
2012-11-10 07:18:07 +00:00
|
|
|
return virGetStoragePool(conn, pool.name, BAD_CAST pool.uuid,
|
|
|
|
NULL, NULL);
|
2008-02-20 15:23:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageVolPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_storage_vol(virConnectPtr conn, remote_nonnull_storage_vol vol)
|
2008-02-20 15:23:36 +00:00
|
|
|
{
|
2012-11-10 07:18:07 +00:00
|
|
|
return virGetStorageVol(conn, vol.pool, vol.name, vol.key,
|
|
|
|
NULL, NULL);
|
2008-02-20 15:23:36 +00:00
|
|
|
}
|
|
|
|
|
2008-11-21 12:31:04 +00:00
|
|
|
static virNodeDevicePtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev)
|
2008-11-21 12:31:04 +00:00
|
|
|
{
|
|
|
|
return virGetNodeDevice(conn, dev.name);
|
|
|
|
}
|
|
|
|
|
2009-07-28 02:46:01 +00:00
|
|
|
static virSecretPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret)
|
2009-07-28 02:46:01 +00:00
|
|
|
{
|
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 13:06:15 +00:00
|
|
|
return virGetSecret(conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID);
|
2009-07-28 02:46:01 +00:00
|
|
|
}
|
|
|
|
|
2010-03-25 17:46:03 +00:00
|
|
|
static virNWFilterPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter)
|
2010-03-25 17:46:03 +00:00
|
|
|
{
|
2012-10-17 09:23:12 +00:00
|
|
|
return virGetNWFilter(conn, nwfilter.name, BAD_CAST nwfilter.uuid);
|
2010-03-25 17:46:03 +00:00
|
|
|
}
|
|
|
|
|
2010-03-31 20:33:13 +00:00
|
|
|
static virDomainSnapshotPtr
|
2012-10-17 09:23:12 +00:00
|
|
|
get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot)
|
2010-03-31 20:33:13 +00:00
|
|
|
{
|
|
|
|
return virGetDomainSnapshot(domain, snapshot.name);
|
|
|
|
}
|
|
|
|
|
2010-03-25 17:46:03 +00:00
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/* Make remote_nonnull_domain and remote_nonnull_network. */
|
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2007-06-21 15:38:20 +00:00
|
|
|
dom_dst->id = dom_src->id;
|
2007-06-11 11:43:41 +00:00
|
|
|
dom_dst->name = dom_src->name;
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(dom_dst->uuid, dom_src->uuid, VIR_UUID_BUFLEN);
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
|
|
|
net_dst->name = net_src->name;
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(net_dst->uuid, net_src->uuid, VIR_UUID_BUFLEN);
|
2007-06-11 11:43:41 +00:00
|
|
|
}
|
|
|
|
|
2009-05-20 14:26:49 +00:00
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_interface(remote_nonnull_interface *interface_dst,
|
2009-05-20 14:26:49 +00:00
|
|
|
virInterfacePtr interface_src)
|
|
|
|
{
|
|
|
|
interface_dst->name = interface_src->name;
|
|
|
|
interface_dst->mac = interface_src->mac;
|
|
|
|
}
|
|
|
|
|
2008-02-20 15:23:36 +00:00
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_storage_pool(remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src)
|
2008-02-20 15:23:36 +00:00
|
|
|
{
|
|
|
|
pool_dst->name = pool_src->name;
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(pool_dst->uuid, pool_src->uuid, VIR_UUID_BUFLEN);
|
2008-02-20 15:23:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src)
|
2008-02-20 15:23:36 +00:00
|
|
|
{
|
|
|
|
vol_dst->pool = vol_src->pool;
|
|
|
|
vol_dst->name = vol_src->name;
|
|
|
|
vol_dst->key = vol_src->key;
|
|
|
|
}
|
|
|
|
|
2009-07-28 02:46:01 +00:00
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
|
2009-07-28 02:46:01 +00:00
|
|
|
{
|
2012-10-17 09:23:12 +00: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 13:06:15 +00:00
|
|
|
secret_dst->usageType = secret_src->usageType;
|
|
|
|
secret_dst->usageID = secret_src->usageID;
|
2009-07-28 02:46:01 +00:00
|
|
|
}
|
|
|
|
|
2016-07-28 12:02:53 +00:00
|
|
|
static void
|
|
|
|
make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src)
|
|
|
|
{
|
|
|
|
dev_dst->name = dev_src->name;
|
|
|
|
}
|
|
|
|
|
2010-03-25 17:46:03 +00:00
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src)
|
2010-03-25 17:46:03 +00:00
|
|
|
{
|
|
|
|
nwfilter_dst->name = nwfilter_src->name;
|
2012-10-17 09:23:12 +00:00
|
|
|
memcpy(nwfilter_dst->uuid, nwfilter_src->uuid, VIR_UUID_BUFLEN);
|
2010-03-25 17:46:03 +00:00
|
|
|
}
|
|
|
|
|
2010-03-31 20:33:13 +00:00
|
|
|
static void
|
2012-10-17 09:23:12 +00:00
|
|
|
make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src)
|
2010-03-31 20:33:13 +00:00
|
|
|
{
|
|
|
|
snapshot_dst->name = snapshot_src->name;
|
2011-04-22 13:40:31 +00:00
|
|
|
make_nonnull_domain(&snapshot_dst->dom, snapshot_src->domain);
|
2010-03-31 20:33:13 +00:00
|
|
|
}
|
|
|
|
|
2007-06-11 11:43:41 +00:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
2008-11-28 12:03:20 +00:00
|
|
|
unsigned long remoteVersion(void)
|
|
|
|
{
|
|
|
|
return REMOTE_PROTOCOL_VERSION;
|
|
|
|
}
|
|
|
|
|
2014-10-16 09:25:59 +00:00
|
|
|
static virHypervisorDriver hypervisor_driver = {
|
Convert all driver struct intializers to C99 style
Change all the driver struct initializers to use the
C99 style, leaving out unused fields. This will make
it possible to add new APIs without changing every
driver. eg change:
qemudDomainResume, /* domainResume */
qemudDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
qemudDomainDestroy, /* domainDestroy */
to
.domainResume = qemudDomainResume,
.domainShutdown = qemudDomainShutdown,
.domainDestroy = qemudDomainDestroy,
And get rid of any existing C99 style initializersr which
set NULL, eg change
.listPools = vboxStorageListPools,
.numOfDefinedPools = NULL,
.listDefinedPools = NULL,
.findPoolSources = NULL,
.poolLookupByName = vboxStoragePoolLookupByName,
to
.listPools = vboxStorageListPools,
.poolLookupByName = vboxStoragePoolLookupByName,
2011-05-13 10:16:31 +00:00
|
|
|
.name = "remote",
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectOpen = remoteConnectOpen, /* 0.3.0 */
|
|
|
|
.connectClose = remoteConnectClose, /* 0.3.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectSupportsFeature = remoteConnectSupportsFeature, /* 0.3.0 */
|
|
|
|
.connectGetType = remoteConnectGetType, /* 0.3.0 */
|
|
|
|
.connectGetVersion = remoteConnectGetVersion, /* 0.3.0 */
|
|
|
|
.connectGetLibVersion = remoteConnectGetLibVersion, /* 0.7.3 */
|
|
|
|
.connectGetHostname = remoteConnectGetHostname, /* 0.3.0 */
|
|
|
|
.connectGetSysinfo = remoteConnectGetSysinfo, /* 0.8.8 */
|
|
|
|
.connectGetMaxVcpus = remoteConnectGetMaxVcpus, /* 0.3.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.nodeGetInfo = remoteNodeGetInfo, /* 0.3.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectGetCapabilities = remoteConnectGetCapabilities, /* 0.3.0 */
|
|
|
|
.connectListDomains = remoteConnectListDomains, /* 0.3.0 */
|
|
|
|
.connectNumOfDomains = remoteConnectNumOfDomains, /* 0.3.0 */
|
|
|
|
.connectListAllDomains = remoteConnectListAllDomains, /* 0.9.13 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainCreateXML = remoteDomainCreateXML, /* 0.3.0 */
|
2013-07-09 17:03:18 +00:00
|
|
|
.domainCreateXMLWithFiles = remoteDomainCreateXMLWithFiles, /* 1.1.1 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainLookupByID = remoteDomainLookupByID, /* 0.3.0 */
|
|
|
|
.domainLookupByUUID = remoteDomainLookupByUUID, /* 0.3.0 */
|
|
|
|
.domainLookupByName = remoteDomainLookupByName, /* 0.3.0 */
|
|
|
|
.domainSuspend = remoteDomainSuspend, /* 0.3.0 */
|
|
|
|
.domainResume = remoteDomainResume, /* 0.3.0 */
|
2012-01-26 18:05:46 +00:00
|
|
|
.domainPMSuspendForDuration = remoteDomainPMSuspendForDuration, /* 0.9.10 */
|
2012-02-10 11:40:52 +00:00
|
|
|
.domainPMWakeup = remoteDomainPMWakeup, /* 0.9.11 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainShutdown = remoteDomainShutdown, /* 0.3.0 */
|
2011-10-05 17:31:55 +00:00
|
|
|
.domainShutdownFlags = remoteDomainShutdownFlags, /* 0.9.10 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainReboot = remoteDomainReboot, /* 0.3.0 */
|
2011-09-29 08:56:24 +00:00
|
|
|
.domainReset = remoteDomainReset, /* 0.9.7 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainDestroy = remoteDomainDestroy, /* 0.3.0 */
|
2011-07-20 16:33:23 +00:00
|
|
|
.domainDestroyFlags = remoteDomainDestroyFlags, /* 0.9.4 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetOSType = remoteDomainGetOSType, /* 0.3.0 */
|
|
|
|
.domainGetMaxMemory = remoteDomainGetMaxMemory, /* 0.3.0 */
|
|
|
|
.domainSetMaxMemory = remoteDomainSetMaxMemory, /* 0.3.0 */
|
|
|
|
.domainSetMemory = remoteDomainSetMemory, /* 0.3.0 */
|
|
|
|
.domainSetMemoryFlags = remoteDomainSetMemoryFlags, /* 0.9.0 */
|
2013-07-08 16:42:57 +00:00
|
|
|
.domainSetMemoryStatsPeriod = remoteDomainSetMemoryStatsPeriod, /* 1.1.1 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSetMemoryParameters = remoteDomainSetMemoryParameters, /* 0.8.5 */
|
|
|
|
.domainGetMemoryParameters = remoteDomainGetMemoryParameters, /* 0.8.5 */
|
|
|
|
.domainSetBlkioParameters = remoteDomainSetBlkioParameters, /* 0.9.0 */
|
|
|
|
.domainGetBlkioParameters = remoteDomainGetBlkioParameters, /* 0.9.0 */
|
2016-03-28 13:30:27 +00:00
|
|
|
.domainGetPerfEvents = remoteDomainGetPerfEvents, /* 1.3.3 */
|
|
|
|
.domainSetPerfEvents = remoteDomainSetPerfEvents, /* 1.3.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetInfo = remoteDomainGetInfo, /* 0.3.0 */
|
|
|
|
.domainGetState = remoteDomainGetState, /* 0.9.2 */
|
2011-05-31 15:37:00 +00:00
|
|
|
.domainGetControlInfo = remoteDomainGetControlInfo, /* 0.9.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSave = remoteDomainSave, /* 0.3.0 */
|
2011-07-09 02:35:16 +00:00
|
|
|
.domainSaveFlags = remoteDomainSaveFlags, /* 0.9.4 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainRestore = remoteDomainRestore, /* 0.3.0 */
|
2011-07-09 02:35:16 +00:00
|
|
|
.domainRestoreFlags = remoteDomainRestoreFlags, /* 0.9.4 */
|
2011-07-20 15:00:38 +00:00
|
|
|
.domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */
|
|
|
|
.domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */
|
2014-03-23 03:51:12 +00:00
|
|
|
.domainCoreDumpWithFormat = remoteDomainCoreDumpWithFormat, /* 1.2.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */
|
|
|
|
.domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */
|
|
|
|
.domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */
|
|
|
|
.domainGetVcpusFlags = remoteDomainGetVcpusFlags, /* 0.8.5 */
|
|
|
|
.domainPinVcpu = remoteDomainPinVcpu, /* 0.3.0 */
|
2011-06-13 15:45:29 +00:00
|
|
|
.domainPinVcpuFlags = remoteDomainPinVcpuFlags, /* 0.9.3 */
|
2011-06-24 23:09:46 +00:00
|
|
|
.domainGetVcpuPinInfo = remoteDomainGetVcpuPinInfo, /* 0.9.3 */
|
2012-08-21 09:18:38 +00:00
|
|
|
.domainPinEmulator = remoteDomainPinEmulator, /* 0.10.0 */
|
|
|
|
.domainGetEmulatorPinInfo = remoteDomainGetEmulatorPinInfo, /* 0.10.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetVcpus = remoteDomainGetVcpus, /* 0.3.0 */
|
|
|
|
.domainGetMaxVcpus = remoteDomainGetMaxVcpus, /* 0.3.0 */
|
2015-03-25 16:02:26 +00:00
|
|
|
.domainGetIOThreadInfo = remoteDomainGetIOThreadInfo, /* 1.2.14 */
|
2015-03-05 19:28:39 +00:00
|
|
|
.domainPinIOThread = remoteDomainPinIOThread, /* 1.2.14 */
|
2015-03-25 21:13:07 +00:00
|
|
|
.domainAddIOThread = remoteDomainAddIOThread, /* 1.2.15 */
|
|
|
|
.domainDelIOThread = remoteDomainDelIOThread, /* 1.2.15 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetSecurityLabel = remoteDomainGetSecurityLabel, /* 0.6.1 */
|
2012-08-15 22:10:39 +00:00
|
|
|
.domainGetSecurityLabelList = remoteDomainGetSecurityLabelList, /* 0.10.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.nodeGetSecurityModel = remoteNodeGetSecurityModel, /* 0.6.1 */
|
|
|
|
.domainGetXMLDesc = remoteDomainGetXMLDesc, /* 0.3.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectDomainXMLFromNative = remoteConnectDomainXMLFromNative, /* 0.6.4 */
|
|
|
|
.connectDomainXMLToNative = remoteConnectDomainXMLToNative, /* 0.6.4 */
|
|
|
|
.connectListDefinedDomains = remoteConnectListDefinedDomains, /* 0.3.0 */
|
|
|
|
.connectNumOfDefinedDomains = remoteConnectNumOfDefinedDomains, /* 0.3.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainCreate = remoteDomainCreate, /* 0.3.0 */
|
|
|
|
.domainCreateWithFlags = remoteDomainCreateWithFlags, /* 0.8.2 */
|
2013-07-09 17:03:18 +00:00
|
|
|
.domainCreateWithFiles = remoteDomainCreateWithFiles, /* 1.1.1 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainDefineXML = remoteDomainDefineXML, /* 0.3.0 */
|
2014-11-18 13:56:20 +00:00
|
|
|
.domainDefineXMLFlags = remoteDomainDefineXMLFlags, /* 1.2.12 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainUndefine = remoteDomainUndefine, /* 0.3.0 */
|
2011-07-20 03:01:45 +00:00
|
|
|
.domainUndefineFlags = remoteDomainUndefineFlags, /* 0.9.4 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainAttachDevice = remoteDomainAttachDevice, /* 0.3.0 */
|
|
|
|
.domainAttachDeviceFlags = remoteDomainAttachDeviceFlags, /* 0.7.7 */
|
|
|
|
.domainDetachDevice = remoteDomainDetachDevice, /* 0.3.0 */
|
|
|
|
.domainDetachDeviceFlags = remoteDomainDetachDeviceFlags, /* 0.7.7 */
|
|
|
|
.domainUpdateDeviceFlags = remoteDomainUpdateDeviceFlags, /* 0.8.0 */
|
2018-05-21 11:24:23 +00:00
|
|
|
.domainDetachDeviceAlias = remoteDomainDetachDeviceAlias, /* 4.4.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetAutostart = remoteDomainGetAutostart, /* 0.3.0 */
|
|
|
|
.domainSetAutostart = remoteDomainSetAutostart, /* 0.3.0 */
|
|
|
|
.domainGetSchedulerType = remoteDomainGetSchedulerType, /* 0.3.0 */
|
|
|
|
.domainGetSchedulerParameters = remoteDomainGetSchedulerParameters, /* 0.3.0 */
|
2011-05-17 21:45:03 +00:00
|
|
|
.domainGetSchedulerParametersFlags = remoteDomainGetSchedulerParametersFlags, /* 0.9.2 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSetSchedulerParameters = remoteDomainSetSchedulerParameters, /* 0.3.0 */
|
2011-05-17 21:45:03 +00:00
|
|
|
.domainSetSchedulerParametersFlags = remoteDomainSetSchedulerParametersFlags, /* 0.9.2 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainMigratePrepare = remoteDomainMigratePrepare, /* 0.3.2 */
|
|
|
|
.domainMigratePerform = remoteDomainMigratePerform, /* 0.3.2 */
|
|
|
|
.domainMigrateFinish = remoteDomainMigrateFinish, /* 0.3.2 */
|
2011-11-29 13:44:36 +00:00
|
|
|
.domainBlockResize = remoteDomainBlockResize, /* 0.9.8 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainBlockStats = remoteDomainBlockStats, /* 0.3.2 */
|
2011-09-05 08:20:03 +00:00
|
|
|
.domainBlockStatsFlags = remoteDomainBlockStatsFlags, /* 0.9.5 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainInterfaceStats = remoteDomainInterfaceStats, /* 0.3.2 */
|
2011-12-29 07:33:18 +00:00
|
|
|
.domainSetInterfaceParameters = remoteDomainSetInterfaceParameters, /* 0.9.9 */
|
|
|
|
.domainGetInterfaceParameters = remoteDomainGetInterfaceParameters, /* 0.9.9 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainMemoryStats = remoteDomainMemoryStats, /* 0.7.5 */
|
|
|
|
.domainBlockPeek = remoteDomainBlockPeek, /* 0.4.2 */
|
|
|
|
.domainMemoryPeek = remoteDomainMemoryPeek, /* 0.4.2 */
|
|
|
|
.domainGetBlockInfo = remoteDomainGetBlockInfo, /* 0.8.1 */
|
2011-06-07 01:01:12 +00:00
|
|
|
.nodeGetCPUStats = remoteNodeGetCPUStats, /* 0.9.3 */
|
2011-06-07 01:05:40 +00:00
|
|
|
.nodeGetMemoryStats = remoteNodeGetMemoryStats, /* 0.9.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.nodeGetCellsFreeMemory = remoteNodeGetCellsFreeMemory, /* 0.3.3 */
|
|
|
|
.nodeGetFreeMemory = remoteNodeGetFreeMemory, /* 0.3.3 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectDomainEventRegister = remoteConnectDomainEventRegister, /* 0.5.0 */
|
|
|
|
.connectDomainEventDeregister = remoteConnectDomainEventDeregister, /* 0.5.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainMigratePrepare2 = remoteDomainMigratePrepare2, /* 0.5.0 */
|
|
|
|
.domainMigrateFinish2 = remoteDomainMigrateFinish2, /* 0.5.0 */
|
|
|
|
.nodeDeviceDettach = remoteNodeDeviceDettach, /* 0.6.1 */
|
2013-04-24 17:42:04 +00:00
|
|
|
.nodeDeviceDetachFlags = remoteNodeDeviceDetachFlags, /* 1.0.5 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.nodeDeviceReAttach = remoteNodeDeviceReAttach, /* 0.6.1 */
|
|
|
|
.nodeDeviceReset = remoteNodeDeviceReset, /* 0.6.1 */
|
|
|
|
.domainMigratePrepareTunnel = remoteDomainMigratePrepareTunnel, /* 0.7.2 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectIsEncrypted = remoteConnectIsEncrypted, /* 0.7.3 */
|
|
|
|
.connectIsSecure = remoteConnectIsSecure, /* 0.7.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainIsActive = remoteDomainIsActive, /* 0.7.3 */
|
|
|
|
.domainIsPersistent = remoteDomainIsPersistent, /* 0.7.3 */
|
|
|
|
.domainIsUpdated = remoteDomainIsUpdated, /* 0.8.6 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectCompareCPU = remoteConnectCompareCPU, /* 0.7.5 */
|
|
|
|
.connectBaselineCPU = remoteConnectBaselineCPU, /* 0.7.7 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetJobInfo = remoteDomainGetJobInfo, /* 0.7.7 */
|
2013-01-30 09:49:28 +00:00
|
|
|
.domainGetJobStats = remoteDomainGetJobStats, /* 1.0.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */
|
2017-08-17 22:17:20 +00:00
|
|
|
.domainMigrateGetMaxDowntime = remoteDomainMigrateGetMaxDowntime, /* 3.7.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */
|
2013-02-18 19:20:04 +00:00
|
|
|
.domainMigrateGetCompressionCache = remoteDomainMigrateGetCompressionCache, /* 1.0.3 */
|
|
|
|
.domainMigrateSetCompressionCache = remoteDomainMigrateSetCompressionCache, /* 1.0.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainMigrateSetMaxSpeed = remoteDomainMigrateSetMaxSpeed, /* 0.9.0 */
|
2011-08-26 18:10:21 +00:00
|
|
|
.domainMigrateGetMaxSpeed = remoteDomainMigrateGetMaxSpeed, /* 0.9.5 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectDomainEventRegisterAny = remoteConnectDomainEventRegisterAny, /* 0.8.0 */
|
|
|
|
.connectDomainEventDeregisterAny = remoteConnectDomainEventDeregisterAny, /* 0.8.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */
|
|
|
|
.domainHasManagedSaveImage = remoteDomainHasManagedSaveImage, /* 0.8.0 */
|
|
|
|
.domainManagedSaveRemove = remoteDomainManagedSaveRemove, /* 0.8.0 */
|
2017-08-08 08:02:49 +00:00
|
|
|
.domainManagedSaveGetXMLDesc = remoteDomainManagedSaveGetXMLDesc, /* 3.7.0 */
|
2017-08-08 08:02:50 +00:00
|
|
|
.domainManagedSaveDefineXML = remoteDomainManagedSaveDefineXML, /* 3.7.0 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSnapshotCreateXML = remoteDomainSnapshotCreateXML, /* 0.8.0 */
|
|
|
|
.domainSnapshotGetXMLDesc = remoteDomainSnapshotGetXMLDesc, /* 0.8.0 */
|
|
|
|
.domainSnapshotNum = remoteDomainSnapshotNum, /* 0.8.0 */
|
|
|
|
.domainSnapshotListNames = remoteDomainSnapshotListNames, /* 0.8.0 */
|
2012-06-10 03:24:57 +00:00
|
|
|
.domainListAllSnapshots = remoteDomainListAllSnapshots, /* 0.9.13 */
|
2011-09-29 18:06:49 +00:00
|
|
|
.domainSnapshotNumChildren = remoteDomainSnapshotNumChildren, /* 0.9.7 */
|
2012-06-10 03:24:57 +00:00
|
|
|
.domainSnapshotListAllChildren = remoteDomainSnapshotListAllChildren, /* 0.9.13 */
|
2011-09-29 18:06:49 +00:00
|
|
|
.domainSnapshotListChildrenNames = remoteDomainSnapshotListChildrenNames, /* 0.9.7 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSnapshotLookupByName = remoteDomainSnapshotLookupByName, /* 0.8.0 */
|
|
|
|
.domainHasCurrentSnapshot = remoteDomainHasCurrentSnapshot, /* 0.8.0 */
|
2011-09-24 19:19:35 +00:00
|
|
|
.domainSnapshotGetParent = remoteDomainSnapshotGetParent, /* 0.9.7 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSnapshotCurrent = remoteDomainSnapshotCurrent, /* 0.8.0 */
|
|
|
|
.domainRevertToSnapshot = remoteDomainRevertToSnapshot, /* 0.8.0 */
|
2012-05-24 22:47:04 +00:00
|
|
|
.domainSnapshotIsCurrent = remoteDomainSnapshotIsCurrent, /* 0.9.13 */
|
|
|
|
.domainSnapshotHasMetadata = remoteDomainSnapshotHasMetadata, /* 0.9.13 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSnapshotDelete = remoteDomainSnapshotDelete, /* 0.8.0 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.domainQemuMonitorCommand = remoteDomainQemuMonitorCommand, /* 0.8.3 */
|
|
|
|
.domainQemuAttach = remoteDomainQemuAttach, /* 0.9.4 */
|
|
|
|
.domainQemuAgentCommand = remoteDomainQemuAgentCommand, /* 0.10.0 */
|
2014-01-29 22:30:44 +00:00
|
|
|
.connectDomainQemuMonitorEventRegister = remoteConnectDomainQemuMonitorEventRegister, /* 1.2.3 */
|
|
|
|
.connectDomainQemuMonitorEventDeregister = remoteConnectDomainQemuMonitorEventDeregister, /* 1.2.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */
|
2012-12-13 16:24:16 +00:00
|
|
|
.domainOpenChannel = remoteDomainOpenChannel, /* 1.0.2 */
|
2011-10-21 11:49:23 +00:00
|
|
|
.domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */
|
2014-08-25 16:55:20 +00:00
|
|
|
.domainOpenGraphicsFD = remoteDomainOpenGraphicsFD, /* 1.2.8 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */
|
2011-02-01 14:23:40 +00:00
|
|
|
.domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */
|
|
|
|
.domainMigratePrepare3 = remoteDomainMigratePrepare3, /* 0.9.2 */
|
|
|
|
.domainMigratePrepareTunnel3 = remoteDomainMigratePrepareTunnel3, /* 0.9.2 */
|
|
|
|
.domainMigratePerform3 = remoteDomainMigratePerform3, /* 0.9.2 */
|
|
|
|
.domainMigrateFinish3 = remoteDomainMigrateFinish3, /* 0.9.2 */
|
|
|
|
.domainMigrateConfirm3 = remoteDomainMigrateConfirm3, /* 0.9.2 */
|
2011-06-07 09:11:15 +00:00
|
|
|
.domainSendKey = remoteDomainSendKey, /* 0.9.3 */
|
2011-11-15 16:38:19 +00:00
|
|
|
.domainSendProcessSignal = remoteDomainSendProcessSignal, /* 1.0.1 */
|
2011-07-22 05:31:16 +00:00
|
|
|
.domainBlockJobAbort = remoteDomainBlockJobAbort, /* 0.9.4 */
|
|
|
|
.domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */
|
|
|
|
.domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
|
|
|
|
.domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
|
2012-02-01 04:39:18 +00:00
|
|
|
.domainBlockRebase = remoteDomainBlockRebase, /* 0.9.10 */
|
2014-08-24 02:09:56 +00:00
|
|
|
.domainBlockCopy = remoteDomainBlockCopy, /* 1.2.9 */
|
2012-09-17 20:07:18 +00:00
|
|
|
.domainBlockCommit = remoteDomainBlockCommit, /* 0.10.2 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectSetKeepAlive = remoteConnectSetKeepAlive, /* 0.9.8 */
|
|
|
|
.connectIsAlive = remoteConnectIsAlive, /* 0.9.8 */
|
2011-11-29 07:15:14 +00:00
|
|
|
.nodeSuspendForDuration = remoteNodeSuspendForDuration, /* 0.9.8 */
|
2011-11-15 09:02:44 +00:00
|
|
|
.domainSetBlockIoTune = remoteDomainSetBlockIoTune, /* 0.9.8 */
|
|
|
|
.domainGetBlockIoTune = remoteDomainGetBlockIoTune, /* 0.9.8 */
|
2011-12-20 08:35:01 +00:00
|
|
|
.domainSetNumaParameters = remoteDomainSetNumaParameters, /* 0.9.9 */
|
|
|
|
.domainGetNumaParameters = remoteDomainGetNumaParameters, /* 0.9.9 */
|
2012-01-28 06:21:31 +00:00
|
|
|
.domainGetCPUStats = remoteDomainGetCPUStats, /* 0.9.10 */
|
2012-01-31 06:42:31 +00:00
|
|
|
.domainGetDiskErrors = remoteDomainGetDiskErrors, /* 0.9.10 */
|
2012-02-01 13:03:50 +00:00
|
|
|
.domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */
|
|
|
|
.domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */
|
2012-08-01 17:00:35 +00:00
|
|
|
.domainGetHostname = remoteDomainGetHostname, /* 0.10.0 */
|
2012-09-14 14:42:15 +00:00
|
|
|
.nodeSetMemoryParameters = remoteNodeSetMemoryParameters, /* 0.10.2 */
|
|
|
|
.nodeGetMemoryParameters = remoteNodeGetMemoryParameters, /* 0.10.2 */
|
2012-10-16 14:05:11 +00:00
|
|
|
.nodeGetCPUMap = remoteNodeGetCPUMap, /* 1.0.0 */
|
2012-11-20 18:01:21 +00:00
|
|
|
.domainFSTrim = remoteDomainFSTrim, /* 1.0.1 */
|
2012-12-21 14:20:04 +00:00
|
|
|
.domainLxcOpenNamespace = remoteDomainLxcOpenNamespace, /* 1.0.2 */
|
2013-05-29 07:47:13 +00:00
|
|
|
.domainMigrateBegin3Params = remoteDomainMigrateBegin3Params, /* 1.1.0 */
|
|
|
|
.domainMigratePrepare3Params = remoteDomainMigratePrepare3Params, /* 1.1.0 */
|
|
|
|
.domainMigratePrepareTunnel3Params = remoteDomainMigratePrepareTunnel3Params, /* 1.1.0 */
|
|
|
|
.domainMigratePerform3Params = remoteDomainMigratePerform3Params, /* 1.1.0 */
|
|
|
|
.domainMigrateFinish3Params = remoteDomainMigrateFinish3Params, /* 1.1.0 */
|
|
|
|
.domainMigrateConfirm3Params = remoteDomainMigrateConfirm3Params, /* 1.1.0 */
|
2013-09-23 09:46:00 +00:00
|
|
|
.connectGetCPUModelNames = remoteConnectGetCPUModelNames, /* 1.1.3 */
|
2014-05-02 00:05:54 +00:00
|
|
|
.domainFSFreeze = remoteDomainFSFreeze, /* 1.2.5 */
|
|
|
|
.domainFSThaw = remoteDomainFSThaw, /* 1.2.5 */
|
2014-04-02 16:25:07 +00:00
|
|
|
.domainGetTime = remoteDomainGetTime, /* 1.2.5 */
|
|
|
|
.domainSetTime = remoteDomainSetTime, /* 1.2.5 */
|
2014-06-09 15:14:47 +00:00
|
|
|
.nodeGetFreePages = remoteNodeGetFreePages, /* 1.2.6 */
|
2014-06-25 15:05:20 +00:00
|
|
|
.connectGetDomainCapabilities = remoteConnectGetDomainCapabilities, /* 1.2.7 */
|
2014-08-25 11:22:13 +00:00
|
|
|
.connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */
|
2014-09-16 16:17:22 +00:00
|
|
|
.nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */
|
2014-11-22 01:27:31 +00:00
|
|
|
.domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */
|
2015-01-25 18:38:47 +00:00
|
|
|
.domainInterfaceAddresses = remoteDomainInterfaceAddresses, /* 1.2.14 */
|
2015-05-18 08:33:18 +00:00
|
|
|
.domainSetUserPassword = remoteDomainSetUserPassword, /* 1.2.16 */
|
2015-08-10 19:59:14 +00:00
|
|
|
.domainRename = remoteDomainRename, /* 1.2.19 */
|
2016-03-01 14:17:38 +00:00
|
|
|
.connectRegisterCloseCallback = remoteConnectRegisterCloseCallback, /* 1.3.2 */
|
|
|
|
.connectUnregisterCloseCallback = remoteConnectUnregisterCloseCallback, /* 1.3.2 */
|
2014-12-01 15:59:53 +00:00
|
|
|
.domainMigrateStartPostCopy = remoteDomainMigrateStartPostCopy, /* 1.3.3 */
|
2016-06-16 17:15:45 +00:00
|
|
|
.domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */
|
2016-06-20 07:16:47 +00:00
|
|
|
.domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */
|
2016-06-21 08:44:51 +00:00
|
|
|
.domainSetVcpu = remoteDomainSetVcpu, /* 3.1.0 */
|
2017-02-23 12:09:12 +00:00
|
|
|
.domainSetBlockThreshold = remoteDomainSetBlockThreshold, /* 3.2.0 */
|
2018-04-24 20:19:03 +00:00
|
|
|
.domainSetLifecycleAction = remoteDomainSetLifecycleAction, /* 3.9.0 */
|
|
|
|
.connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */
|
2018-04-25 11:43:24 +00:00
|
|
|
.connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */
|
2018-06-08 14:40:54 +00:00
|
|
|
.nodeGetSEVInfo = remoteNodeGetSEVInfo, /* 4.5.0 */
|
2018-06-08 14:41:00 +00:00
|
|
|
.domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo /* 4.5.0 */
|
2007-06-11 11:43:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static virNetworkDriver network_driver = {
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectNumOfNetworks = remoteConnectNumOfNetworks, /* 0.3.0 */
|
|
|
|
.connectListNetworks = remoteConnectListNetworks, /* 0.3.0 */
|
|
|
|
.connectNumOfDefinedNetworks = remoteConnectNumOfDefinedNetworks, /* 0.3.0 */
|
|
|
|
.connectListDefinedNetworks = remoteConnectListDefinedNetworks, /* 0.3.0 */
|
|
|
|
.connectListAllNetworks = remoteConnectListAllNetworks, /* 0.10.2 */
|
2013-12-11 10:38:01 +00:00
|
|
|
.connectNetworkEventDeregisterAny = remoteConnectNetworkEventDeregisterAny, /* 1.2.1 */
|
|
|
|
.connectNetworkEventRegisterAny = remoteConnectNetworkEventRegisterAny, /* 1.2.1 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.networkLookupByUUID = remoteNetworkLookupByUUID, /* 0.3.0 */
|
|
|
|
.networkLookupByName = remoteNetworkLookupByName, /* 0.3.0 */
|
|
|
|
.networkCreateXML = remoteNetworkCreateXML, /* 0.3.0 */
|
|
|
|
.networkDefineXML = remoteNetworkDefineXML, /* 0.3.0 */
|
|
|
|
.networkUndefine = remoteNetworkUndefine, /* 0.3.0 */
|
2012-08-20 03:54:57 +00:00
|
|
|
.networkUpdate = remoteNetworkUpdate, /* 0.10.2 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.networkCreate = remoteNetworkCreate, /* 0.3.0 */
|
|
|
|
.networkDestroy = remoteNetworkDestroy, /* 0.3.0 */
|
|
|
|
.networkGetXMLDesc = remoteNetworkGetXMLDesc, /* 0.3.0 */
|
|
|
|
.networkGetBridgeName = remoteNetworkGetBridgeName, /* 0.3.0 */
|
|
|
|
.networkGetAutostart = remoteNetworkGetAutostart, /* 0.3.0 */
|
|
|
|
.networkSetAutostart = remoteNetworkSetAutostart, /* 0.3.0 */
|
|
|
|
.networkIsActive = remoteNetworkIsActive, /* 0.7.3 */
|
|
|
|
.networkIsPersistent = remoteNetworkIsPersistent, /* 0.7.3 */
|
2014-06-23 21:01:50 +00:00
|
|
|
.networkGetDHCPLeases = remoteNetworkGetDHCPLeases, /* 1.2.6 */
|
2007-06-11 11:43:41 +00:00
|
|
|
};
|
|
|
|
|
2009-05-20 14:26:49 +00:00
|
|
|
static virInterfaceDriver interface_driver = {
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectNumOfInterfaces = remoteConnectNumOfInterfaces, /* 0.7.2 */
|
|
|
|
.connectListInterfaces = remoteConnectListInterfaces, /* 0.7.2 */
|
|
|
|
.connectNumOfDefinedInterfaces = remoteConnectNumOfDefinedInterfaces, /* 0.7.2 */
|
|
|
|
.connectListDefinedInterfaces = remoteConnectListDefinedInterfaces, /* 0.7.2 */
|
|
|
|
.connectListAllInterfaces = remoteConnectListAllInterfaces, /* 0.10.2 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.interfaceLookupByName = remoteInterfaceLookupByName, /* 0.7.2 */
|
|
|
|
.interfaceLookupByMACString = remoteInterfaceLookupByMACString, /* 0.7.2 */
|
|
|
|
.interfaceGetXMLDesc = remoteInterfaceGetXMLDesc, /* 0.7.2 */
|
|
|
|
.interfaceDefineXML = remoteInterfaceDefineXML, /* 0.7.2 */
|
|
|
|
.interfaceUndefine = remoteInterfaceUndefine, /* 0.7.2 */
|
|
|
|
.interfaceCreate = remoteInterfaceCreate, /* 0.7.2 */
|
|
|
|
.interfaceDestroy = remoteInterfaceDestroy, /* 0.7.2 */
|
|
|
|
.interfaceIsActive = remoteInterfaceIsActive, /* 0.7.3 */
|
2011-05-05 13:35:40 +00:00
|
|
|
.interfaceChangeBegin = remoteInterfaceChangeBegin, /* 0.9.2 */
|
|
|
|
.interfaceChangeCommit = remoteInterfaceChangeCommit, /* 0.9.2 */
|
|
|
|
.interfaceChangeRollback = remoteInterfaceChangeRollback, /* 0.9.2 */
|
2009-05-20 14:26:49 +00:00
|
|
|
};
|
|
|
|
|
2008-02-20 15:23:36 +00:00
|
|
|
static virStorageDriver storage_driver = {
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectNumOfStoragePools = remoteConnectNumOfStoragePools, /* 0.4.1 */
|
|
|
|
.connectListStoragePools = remoteConnectListStoragePools, /* 0.4.1 */
|
|
|
|
.connectNumOfDefinedStoragePools = remoteConnectNumOfDefinedStoragePools, /* 0.4.1 */
|
|
|
|
.connectListDefinedStoragePools = remoteConnectListDefinedStoragePools, /* 0.4.1 */
|
|
|
|
.connectListAllStoragePools = remoteConnectListAllStoragePools, /* 0.10.2 */
|
|
|
|
.connectFindStoragePoolSources = remoteConnectFindStoragePoolSources, /* 0.4.5 */
|
2016-06-15 18:35:45 +00:00
|
|
|
.connectStoragePoolEventDeregisterAny = remoteConnectStoragePoolEventDeregisterAny, /* 2.0.0 */
|
|
|
|
.connectStoragePoolEventRegisterAny = remoteConnectStoragePoolEventRegisterAny, /* 2.0.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.storagePoolLookupByName = remoteStoragePoolLookupByName, /* 0.4.1 */
|
|
|
|
.storagePoolLookupByUUID = remoteStoragePoolLookupByUUID, /* 0.4.1 */
|
|
|
|
.storagePoolLookupByVolume = remoteStoragePoolLookupByVolume, /* 0.4.1 */
|
2018-01-25 09:35:52 +00:00
|
|
|
.storagePoolLookupByTargetPath = remoteStoragePoolLookupByTargetPath, /* 4.1.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.storagePoolCreateXML = remoteStoragePoolCreateXML, /* 0.4.1 */
|
|
|
|
.storagePoolDefineXML = remoteStoragePoolDefineXML, /* 0.4.1 */
|
|
|
|
.storagePoolBuild = remoteStoragePoolBuild, /* 0.4.1 */
|
|
|
|
.storagePoolUndefine = remoteStoragePoolUndefine, /* 0.4.1 */
|
|
|
|
.storagePoolCreate = remoteStoragePoolCreate, /* 0.4.1 */
|
|
|
|
.storagePoolDestroy = remoteStoragePoolDestroy, /* 0.4.1 */
|
|
|
|
.storagePoolDelete = remoteStoragePoolDelete, /* 0.4.1 */
|
|
|
|
.storagePoolRefresh = remoteStoragePoolRefresh, /* 0.4.1 */
|
|
|
|
.storagePoolGetInfo = remoteStoragePoolGetInfo, /* 0.4.1 */
|
|
|
|
.storagePoolGetXMLDesc = remoteStoragePoolGetXMLDesc, /* 0.4.1 */
|
|
|
|
.storagePoolGetAutostart = remoteStoragePoolGetAutostart, /* 0.4.1 */
|
|
|
|
.storagePoolSetAutostart = remoteStoragePoolSetAutostart, /* 0.4.1 */
|
|
|
|
.storagePoolNumOfVolumes = remoteStoragePoolNumOfVolumes, /* 0.4.1 */
|
|
|
|
.storagePoolListVolumes = remoteStoragePoolListVolumes, /* 0.4.1 */
|
|
|
|
.storagePoolListAllVolumes = remoteStoragePoolListAllVolumes, /* 0.10.0 */
|
|
|
|
|
|
|
|
.storageVolLookupByName = remoteStorageVolLookupByName, /* 0.4.1 */
|
|
|
|
.storageVolLookupByKey = remoteStorageVolLookupByKey, /* 0.4.1 */
|
|
|
|
.storageVolLookupByPath = remoteStorageVolLookupByPath, /* 0.4.1 */
|
|
|
|
.storageVolCreateXML = remoteStorageVolCreateXML, /* 0.4.1 */
|
|
|
|
.storageVolCreateXMLFrom = remoteStorageVolCreateXMLFrom, /* 0.6.4 */
|
|
|
|
.storageVolDownload = remoteStorageVolDownload, /* 0.9.0 */
|
|
|
|
.storageVolUpload = remoteStorageVolUpload, /* 0.9.0 */
|
|
|
|
.storageVolDelete = remoteStorageVolDelete, /* 0.4.1 */
|
|
|
|
.storageVolWipe = remoteStorageVolWipe, /* 0.8.0 */
|
|
|
|
.storageVolWipePattern = remoteStorageVolWipePattern, /* 0.9.10 */
|
|
|
|
.storageVolGetInfo = remoteStorageVolGetInfo, /* 0.4.1 */
|
2016-11-29 15:44:36 +00:00
|
|
|
.storageVolGetInfoFlags = remoteStorageVolGetInfoFlags, /* 3.0.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.storageVolGetXMLDesc = remoteStorageVolGetXMLDesc, /* 0.4.1 */
|
|
|
|
.storageVolGetPath = remoteStorageVolGetPath, /* 0.4.1 */
|
|
|
|
.storageVolResize = remoteStorageVolResize, /* 0.9.10 */
|
|
|
|
.storagePoolIsActive = remoteStoragePoolIsActive, /* 0.7.3 */
|
|
|
|
.storagePoolIsPersistent = remoteStoragePoolIsPersistent, /* 0.7.3 */
|
2008-02-20 15:23:36 +00:00
|
|
|
};
|
|
|
|
|
2009-07-28 02:46:01 +00:00
|
|
|
static virSecretDriver secret_driver = {
|
2013-04-22 17:26:01 +00:00
|
|
|
.connectNumOfSecrets = remoteConnectNumOfSecrets, /* 0.7.1 */
|
|
|
|
.connectListSecrets = remoteConnectListSecrets, /* 0.7.1 */
|
|
|
|
.connectListAllSecrets = remoteConnectListAllSecrets, /* 0.10.2 */
|
|
|
|
.secretLookupByUUID = remoteSecretLookupByUUID, /* 0.7.1 */
|
|
|
|
.secretLookupByUsage = remoteSecretLookupByUsage, /* 0.7.1 */
|
|
|
|
.secretDefineXML = remoteSecretDefineXML, /* 0.7.1 */
|
|
|
|
.secretGetXMLDesc = remoteSecretGetXMLDesc, /* 0.7.1 */
|
|
|
|
.secretSetValue = remoteSecretSetValue, /* 0.7.1 */
|
|
|
|
.secretGetValue = remoteSecretGetValue, /* 0.7.1 */
|
2016-12-22 16:11:06 +00:00
|
|
|
.secretUndefine = remoteSecretUndefine, /* 0.7.1 */
|
|
|
|
.connectSecretEventDeregisterAny = remoteConnectSecretEventDeregisterAny, /* 3.0.0 */
|
|
|
|
.connectSecretEventRegisterAny = remoteConnectSecretEventRegisterAny, /* 3.0.0 */
|
2009-07-28 02:46:01 +00:00
|
|
|
};
|
|
|
|
|
2013-04-23 10:15:48 +00:00
|
|
|
static virNodeDeviceDriver node_device_driver = {
|
2016-07-28 12:02:53 +00:00
|
|
|
.connectNodeDeviceEventDeregisterAny = remoteConnectNodeDeviceEventDeregisterAny, /* 2.2.0 */
|
|
|
|
.connectNodeDeviceEventRegisterAny = remoteConnectNodeDeviceEventRegisterAny, /* 2.2.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.nodeNumOfDevices = remoteNodeNumOfDevices, /* 0.5.0 */
|
|
|
|
.nodeListDevices = remoteNodeListDevices, /* 0.5.0 */
|
|
|
|
.connectListAllNodeDevices = remoteConnectListAllNodeDevices, /* 0.10.2 */
|
|
|
|
.nodeDeviceLookupByName = remoteNodeDeviceLookupByName, /* 0.5.0 */
|
|
|
|
.nodeDeviceLookupSCSIHostByWWN = remoteNodeDeviceLookupSCSIHostByWWN, /* 1.0.2 */
|
|
|
|
.nodeDeviceGetXMLDesc = remoteNodeDeviceGetXMLDesc, /* 0.5.0 */
|
|
|
|
.nodeDeviceGetParent = remoteNodeDeviceGetParent, /* 0.5.0 */
|
|
|
|
.nodeDeviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
|
|
|
|
.nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
|
|
|
|
.nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
|
|
|
|
.nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
|
2008-11-21 12:31:04 +00:00
|
|
|
};
|
|
|
|
|
2010-03-25 17:46:03 +00:00
|
|
|
static virNWFilterDriver nwfilter_driver = {
|
2011-05-13 13:35:01 +00:00
|
|
|
.nwfilterLookupByUUID = remoteNWFilterLookupByUUID, /* 0.8.0 */
|
|
|
|
.nwfilterLookupByName = remoteNWFilterLookupByName, /* 0.8.0 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.nwfilterGetXMLDesc = remoteNWFilterGetXMLDesc, /* 0.8.0 */
|
|
|
|
.nwfilterDefineXML = remoteNWFilterDefineXML, /* 0.8.0 */
|
|
|
|
.nwfilterUndefine = remoteNWFilterUndefine, /* 0.8.0 */
|
|
|
|
.connectNumOfNWFilters = remoteConnectNumOfNWFilters, /* 0.8.0 */
|
|
|
|
.connectListNWFilters = remoteConnectListNWFilters, /* 0.8.0 */
|
|
|
|
.connectListAllNWFilters = remoteConnectListAllNWFilters, /* 0.10.2 */
|
2010-03-25 17:46:03 +00:00
|
|
|
};
|
|
|
|
|
2015-01-20 16:16:26 +00:00
|
|
|
static virConnectDriver connect_driver = {
|
|
|
|
.hypervisorDriver = &hypervisor_driver,
|
|
|
|
.interfaceDriver = &interface_driver,
|
|
|
|
.networkDriver = &network_driver,
|
|
|
|
.nodeDeviceDriver = &node_device_driver,
|
|
|
|
.nwfilterDriver = &nwfilter_driver,
|
|
|
|
.secretDriver = &secret_driver,
|
|
|
|
.storageDriver = &storage_driver,
|
|
|
|
};
|
2008-11-21 12:31:04 +00:00
|
|
|
|
2007-10-27 01:23:28 +00:00
|
|
|
static virStateDriver state_driver = {
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
.name = "Remote",
|
2013-04-23 12:50:18 +00:00
|
|
|
.stateInitialize = remoteStateInitialize,
|
2007-10-27 01:23:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-06-25 08:41:17 +00:00
|
|
|
/** remoteRegister:
|
2007-06-11 11:43:41 +00:00
|
|
|
*
|
|
|
|
* Register driver with libvirt driver system.
|
2007-06-25 08:41:17 +00:00
|
|
|
*
|
|
|
|
* Returns -1 on error.
|
2007-06-11 11:43:41 +00:00
|
|
|
*/
|
|
|
|
int
|
2012-10-17 09:23:12 +00:00
|
|
|
remoteRegister(void)
|
2007-06-11 11:43:41 +00:00
|
|
|
{
|
2015-01-20 16:16:26 +00:00
|
|
|
if (virRegisterConnectDriver(&connect_driver,
|
|
|
|
false) < 0)
|
2014-03-17 13:35:42 +00:00
|
|
|
return -1;
|
2014-03-17 15:47:45 +00:00
|
|
|
if (virRegisterStateDriver(&state_driver) < 0)
|
2014-03-17 13:35:42 +00:00
|
|
|
return -1;
|
2007-06-11 11:43:41 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|