2
* remote_driver.c: driver to provide access to libvirtd running
5
* Copyright (C) 2007-2012 Red Hat, Inc.
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* Author: Richard Jones <rjones@redhat.com>
29
#include "virnetclient.h"
30
#include "virnetclientprogram.h"
31
#include "virnetclientstream.h"
32
#include "virterror_internal.h"
34
#include "datatypes.h"
35
#include "domain_event.h"
38
#include "remote_driver.h"
39
#include "remote_protocol.h"
40
#include "qemu_protocol.h"
46
#include "virtypedparam.h"
49
#include "virauthconfig.h"
51
#define VIR_FROM_THIS VIR_FROM_REMOTE
54
# define HYPER_TO_TYPE(_type, _to, _from) \
56
if ((_from) != (_type)(_from)) { \
57
remoteError(VIR_ERR_INTERNAL_ERROR, \
58
_("conversion from hyper to %s overflowed"), #_type); \
64
# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
65
# define HYPER_TO_ULONG(_to, _from) HYPER_TO_TYPE(unsigned long, _to, _from)
67
# define HYPER_TO_LONG(_to, _from) (_to) = (_from)
68
# define HYPER_TO_ULONG(_to, _from) (_to) = (_from)
71
static int inside_daemon = 0;
72
static virDriverPtr remoteDriver = NULL;
77
virNetClientPtr client;
78
virNetClientProgramPtr remoteProgram;
79
virNetClientProgramPtr qemuProgram;
81
int counter; /* Serial number for RPC */
83
virNetTLSContextPtr tls;
85
int is_secure; /* Secure if TLS or SASL or UNIX sockets */
86
char *type; /* Cached return from remoteType. */
87
int localUses; /* Ref count for private data */
88
char *hostname; /* Original hostname */
89
bool serverKeepAlive; /* Does server support keepalive protocol? */
91
virDomainEventStatePtr domainEventState;
95
REMOTE_CALL_QEMU = (1 << 0),
99
static void remoteDriverLock(struct private_data *driver)
101
virMutexLock(&driver->lock);
104
static void remoteDriverUnlock(struct private_data *driver)
106
virMutexUnlock(&driver->lock);
109
static int call(virConnectPtr conn, struct private_data *priv,
110
unsigned int flags, int proc_nr,
111
xdrproc_t args_filter, char *args,
112
xdrproc_t ret_filter, char *ret);
113
static int callWithFD(virConnectPtr conn, struct private_data *priv,
114
unsigned int flags, int fd, int proc_nr,
115
xdrproc_t args_filter, char *args,
116
xdrproc_t ret_filter, char *ret);
117
static int remoteAuthenticate (virConnectPtr conn, struct private_data *priv,
118
virConnectAuthPtr auth, const char *authtype);
120
static int remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
121
virConnectAuthPtr auth, const char *mech);
124
static int remoteAuthPolkit (virConnectPtr conn, struct private_data *priv,
125
virConnectAuthPtr auth);
126
#endif /* HAVE_POLKIT */
128
#define remoteError(code, ...) \
129
virReportErrorHelper(VIR_FROM_REMOTE, code, __FILE__, \
130
__FUNCTION__, __LINE__, __VA_ARGS__)
132
static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain);
133
static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network network);
134
static virNWFilterPtr get_nonnull_nwfilter (virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
135
static virInterfacePtr get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface iface);
136
static virStoragePoolPtr get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool);
137
static virStorageVolPtr get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol);
138
static virNodeDevicePtr get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev);
139
static virSecretPtr get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret);
140
static virDomainSnapshotPtr get_nonnull_domain_snapshot (virDomainPtr domain, remote_nonnull_domain_snapshot snapshot);
141
static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
142
static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src);
143
static void make_nonnull_interface (remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
144
static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src);
145
static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
146
static void make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
147
static void make_nonnull_nwfilter (remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
148
static void make_nonnull_domain_snapshot (remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
149
static void remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event);
150
/*----------------------------------------------------------------------*/
152
/* Helper functions for remoteOpen. */
153
static char *get_transport_from_scheme (char *scheme);
157
remoteStartup(int privileged ATTRIBUTE_UNUSED)
159
/* Mark that we're inside the daemon so we can avoid
160
* re-entering ourselves
169
* remoteFindDaemonPath:
171
* Tries to find the path to the libvirtd binary.
173
* Returns path on success or NULL in case of error.
176
remoteFindDaemonPath(void)
178
static const char *serverPaths[] = {
180
SBINDIR "/libvirtd_dbg",
184
const char *customDaemon = getenv("LIBVIRTD_PATH");
189
for (i = 0; serverPaths[i]; i++) {
190
if (virFileIsExecutable(serverPaths[i])) {
191
return serverPaths[i];
200
remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
201
virNetClientPtr client ATTRIBUTE_UNUSED,
202
void *evdata, void *opaque);
204
remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
205
virNetClientPtr client ATTRIBUTE_UNUSED,
206
void *evdata, void *opaque);
208
remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog,
209
virNetClientPtr client,
210
void *evdata, void *opaque);
212
remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog,
213
virNetClientPtr client,
214
void *evdata, void *opaque);
216
remoteDomainBuildEventIOError(virNetClientProgramPtr prog,
217
virNetClientPtr client,
218
void *evdata, void *opaque);
220
remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog,
221
virNetClientPtr client,
222
void *evdata, void *opaque);
224
remoteDomainBuildEventGraphics(virNetClientProgramPtr prog,
225
virNetClientPtr client,
226
void *evdata, void *opaque);
228
remoteDomainBuildEventControlError(virNetClientProgramPtr prog,
229
virNetClientPtr client,
230
void *evdata, void *opaque);
233
remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog,
234
virNetClientPtr client,
235
void *evdata, void *opaque);
238
remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog,
239
virNetClientPtr client,
240
void *evdata, void *opaque);
243
remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog,
244
virNetClientPtr client,
245
void *evdata, void *opaque);
248
remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog,
249
virNetClientPtr client,
250
void *evdata, void *opaque);
253
remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog,
254
virNetClientPtr client,
255
void *evdata, void *opaque);
257
static virNetClientProgramEvent remoteDomainEvents[] = {
258
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
259
remoteDomainBuildEventRTCChange,
260
sizeof(remote_domain_event_rtc_change_msg),
261
(xdrproc_t)xdr_remote_domain_event_rtc_change_msg },
262
{ REMOTE_PROC_DOMAIN_EVENT_REBOOT,
263
remoteDomainBuildEventReboot,
264
sizeof(remote_domain_event_reboot_msg),
265
(xdrproc_t)xdr_remote_domain_event_reboot_msg },
266
{ REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
267
remoteDomainBuildEventLifecycle,
268
sizeof(remote_domain_event_lifecycle_msg),
269
(xdrproc_t)xdr_remote_domain_event_lifecycle_msg },
270
{ REMOTE_PROC_DOMAIN_EVENT_WATCHDOG,
271
remoteDomainBuildEventWatchdog,
272
sizeof(remote_domain_event_watchdog_msg),
273
(xdrproc_t)xdr_remote_domain_event_watchdog_msg},
274
{ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR,
275
remoteDomainBuildEventIOError,
276
sizeof(remote_domain_event_io_error_msg),
277
(xdrproc_t)xdr_remote_domain_event_io_error_msg },
278
{ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON,
279
remoteDomainBuildEventIOErrorReason,
280
sizeof(remote_domain_event_io_error_reason_msg),
281
(xdrproc_t)xdr_remote_domain_event_io_error_reason_msg },
282
{ REMOTE_PROC_DOMAIN_EVENT_GRAPHICS,
283
remoteDomainBuildEventGraphics,
284
sizeof(remote_domain_event_graphics_msg),
285
(xdrproc_t)xdr_remote_domain_event_graphics_msg },
286
{ REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR,
287
remoteDomainBuildEventControlError,
288
sizeof(remote_domain_event_control_error_msg),
289
(xdrproc_t)xdr_remote_domain_event_control_error_msg },
290
{ REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB,
291
remoteDomainBuildEventBlockJob,
292
sizeof(remote_domain_event_block_job_msg),
293
(xdrproc_t)xdr_remote_domain_event_block_job_msg },
294
{ REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE,
295
remoteDomainBuildEventDiskChange,
296
sizeof(remote_domain_event_disk_change_msg),
297
(xdrproc_t)xdr_remote_domain_event_disk_change_msg },
298
{ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE,
299
remoteDomainBuildEventTrayChange,
300
sizeof(remote_domain_event_tray_change_msg),
301
(xdrproc_t)xdr_remote_domain_event_tray_change_msg },
302
{ REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP,
303
remoteDomainBuildEventPMWakeup,
304
sizeof(remote_domain_event_pmwakeup_msg),
305
(xdrproc_t)xdr_remote_domain_event_pmwakeup_msg },
306
{ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND,
307
remoteDomainBuildEventPMSuspend,
308
sizeof(remote_domain_event_pmsuspend_msg),
309
(xdrproc_t)xdr_remote_domain_event_pmsuspend_msg },
312
enum virDrvOpenRemoteFlags {
313
VIR_DRV_OPEN_REMOTE_RO = (1 << 0),
314
VIR_DRV_OPEN_REMOTE_USER = (1 << 1), /* Use the per-user socket path */
315
VIR_DRV_OPEN_REMOTE_AUTOSTART = (1 << 2), /* Autostart a per-user daemon */
320
* URIs that this driver needs to handle:
323
* - Everything that no one else has yet claimed, but nothing if
324
* we're inside the libvirtd daemon
327
* - Plain paths (///var/lib/xen/xend-socket) -> UNIX domain socket
328
* - xxx://servername/ -> TLS connection
329
* - xxx+tls://servername/ -> TLS connection
330
* - xxx+tls:/// -> TLS connection to localhost
331
* - xxx+tcp://servername/ -> TCP connection
332
* - xxx+tcp:/// -> TCP connection to localhost
333
* - xxx+unix:/// -> UNIX domain socket
334
* - xxx:/// -> UNIX domain socket
337
doRemoteOpen (virConnectPtr conn,
338
struct private_data *priv,
339
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
342
char *transport_str = NULL;
351
const char *daemonPath;
354
/* We handle *ALL* URIs here. The caller has rejected any
355
* URIs we don't care about */
358
if (!conn->uri->scheme) {
359
/* This is the ///var/lib/xen/xend-socket local path style */
360
if (!conn->uri->path)
361
return VIR_DRV_OPEN_DECLINED;
362
if (conn->uri->path[0] != '/')
363
return VIR_DRV_OPEN_DECLINED;
365
transport = trans_unix;
367
transport_str = get_transport_from_scheme (conn->uri->scheme);
369
if (!transport_str) {
370
if (conn->uri->server)
371
transport = trans_tls;
373
transport = trans_unix;
375
if (STRCASEEQ (transport_str, "tls"))
376
transport = trans_tls;
377
else if (STRCASEEQ (transport_str, "unix")) {
378
if (conn->uri->server) {
379
remoteError(VIR_ERR_INVALID_ARG,
380
_("using unix socket and remote "
381
"server '%s' is not supported."),
383
return VIR_DRV_OPEN_ERROR;
385
transport = trans_unix;
387
} else if (STRCASEEQ (transport_str, "ssh"))
388
transport = trans_ssh;
389
else if (STRCASEEQ (transport_str, "ext"))
390
transport = trans_ext;
391
else if (STRCASEEQ (transport_str, "tcp"))
392
transport = trans_tcp;
394
remoteError(VIR_ERR_INVALID_ARG, "%s",
395
_("remote_open: transport in URL not recognised "
396
"(should be tls|unix|ssh|ext|tcp)"));
397
return VIR_DRV_OPEN_ERROR;
402
/* No URI, then must be probing so use UNIX socket */
403
transport = trans_unix;
406
/* Local variables which we will initialize. These can
407
* get freed in the failed: path.
409
char *name = NULL, *command = NULL, *sockname = NULL, *netcat = NULL;
410
char *port = NULL, *authtype = NULL, *username = NULL;
411
bool sanity = true, verify = true, tty ATTRIBUTE_UNUSED = true;
412
char *pkipath = NULL, *keyfile = NULL;
414
/* Return code from this function, and the private data. */
415
int retcode = VIR_DRV_OPEN_ERROR;
417
/* Remote server defaults to "localhost" if not specified. */
418
if (conn->uri && conn->uri->port != 0) {
419
if (virAsprintf(&port, "%d", conn->uri->port) == -1) goto out_of_memory;
420
} else if (transport == trans_tls) {
421
port = strdup (LIBVIRTD_TLS_PORT);
422
if (!port) goto out_of_memory;
423
} else if (transport == trans_tcp) {
424
port = strdup (LIBVIRTD_TCP_PORT);
425
if (!port) goto out_of_memory;
427
port = NULL; /* Port not used for unix, ext., default for ssh */
430
priv->hostname = strdup (conn->uri && conn->uri->server ?
431
conn->uri->server : "localhost");
434
if (conn->uri && conn->uri->user) {
435
username = strdup (conn->uri->user);
440
/* Get the variables from the query string.
441
* Then we need to reconstruct the query string (because
442
* feasibly it might contain variables needed by the real driver,
443
* although that won't be the case for now).
448
for (i = 0; i < conn->uri->paramsCount ; i++) {
449
virURIParamPtr var = &conn->uri->params[i];
450
if (STRCASEEQ (var->name, "name")) {
452
name = strdup (var->value);
453
if (!name) goto out_of_memory;
455
} else if (STRCASEEQ (var->name, "command")) {
457
command = strdup (var->value);
458
if (!command) goto out_of_memory;
460
} else if (STRCASEEQ (var->name, "socket")) {
462
sockname = strdup (var->value);
463
if (!sockname) goto out_of_memory;
465
} else if (STRCASEEQ (var->name, "auth")) {
467
authtype = strdup (var->value);
468
if (!authtype) goto out_of_memory;
470
} else if (STRCASEEQ (var->name, "netcat")) {
472
netcat = strdup (var->value);
473
if (!netcat) goto out_of_memory;
475
} else if (STRCASEEQ (var->name, "keyfile")) {
477
keyfile = strdup (var->value);
478
if (!keyfile) goto out_of_memory;
479
} else if (STRCASEEQ (var->name, "no_sanity")) {
480
sanity = atoi(var->value) == 0;
482
} else if (STRCASEEQ (var->name, "no_verify")) {
483
verify = atoi (var->value) == 0;
485
} else if (STRCASEEQ (var->name, "no_tty")) {
486
tty = atoi (var->value) == 0;
488
} else if (STRCASEEQ(var->name, "pkipath")) {
490
pkipath = strdup(var->value);
491
if (!pkipath) goto out_of_memory;
493
} else if (STRCASEEQ(var->name, "authfile")) {
494
/* Strip this param, used by virauth.c */
497
VIR_DEBUG("passing through variable '%s' ('%s') to remote end",
498
var->name, var->value);
502
/* Construct the original name. */
504
if (conn->uri->scheme &&
505
(STREQ(conn->uri->scheme, "remote") ||
506
STRPREFIX(conn->uri->scheme, "remote+"))) {
507
/* Allow remote serve to probe */
508
if (!(name = strdup("")))
512
.scheme = conn->uri->scheme,
513
.query = virURIFormatParams(conn->uri),
514
.path = conn->uri->path,
515
.fragment = conn->uri->fragment,
518
/* Evil, blank out transport scheme temporarily */
520
assert (transport_str[-1] == '+');
521
transport_str[-1] = '\0';
524
name = virURIFormat(&tmpuri);
526
VIR_FREE(tmpuri.query);
528
/* Restore transport scheme */
530
transport_str[-1] = '+';
537
/* Probe URI server side */
538
if (!(name = strdup("")))
542
VIR_DEBUG("proceeding with name = %s", name);
544
/* For ext transport, command is required. */
545
if (transport == trans_ext && !command) {
546
remoteError(VIR_ERR_INVALID_ARG, "%s",
547
_("remote_open: for 'ext' transport, command is required"));
552
VIR_DEBUG("Connecting with transport %d", transport);
553
/* Connect to the remote service. */
556
priv->tls = virNetTLSContextNewClientPath(pkipath,
557
geteuid() != 0 ? true : false,
565
priv->client = virNetClientNewTCP(priv->hostname, port);
570
VIR_DEBUG("Starting TLS session");
571
if (virNetClientSetTLSSession(priv->client, priv->tls) < 0)
580
if (flags & VIR_DRV_OPEN_REMOTE_USER) {
581
char *userdir = virGetUserRuntimeDirectory();
586
if (virAsprintf(&sockname, "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) {
592
if (flags & VIR_DRV_OPEN_REMOTE_RO)
593
sockname = strdup(LIBVIRTD_PRIV_UNIX_SOCKET_RO);
595
sockname = strdup(LIBVIRTD_PRIV_UNIX_SOCKET);
596
if (sockname == NULL)
599
VIR_DEBUG("Proceeding with sockname %s", sockname);
602
if (!(daemonPath = remoteFindDaemonPath())) {
603
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
604
_("Unable to locate libvirtd daemon in $PATH"));
607
if (!(priv->client = virNetClientNewUNIX(sockname,
608
flags & VIR_DRV_OPEN_REMOTE_AUTOSTART,
616
command = command ? command : strdup ("ssh");
621
if (flags & VIR_DRV_OPEN_REMOTE_RO)
622
sockname = strdup(LIBVIRTD_PRIV_UNIX_SOCKET_RO);
624
sockname = strdup(LIBVIRTD_PRIV_UNIX_SOCKET);
625
if (sockname == NULL)
629
if (!(priv->client = virNetClientNewSSH(priv->hostname,
635
netcat ? netcat : "nc",
644
char const *cmd_argv[] = { command, NULL };
645
if (!(priv->client = virNetClientNewExternal(cmd_argv)))
648
/* Do not set 'is_secure' flag since we can't guarantee
649
* an external program is secure, and this flag must be
658
remoteError(VIR_ERR_INVALID_ARG, "%s",
659
_("transport methods unix, ssh and ext are not supported "
664
} /* switch (transport) */
666
if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM,
667
REMOTE_PROTOCOL_VERSION,
669
ARRAY_CARDINALITY(remoteDomainEvents),
672
if (!(priv->qemuProgram = virNetClientProgramNew(QEMU_PROGRAM,
673
QEMU_PROTOCOL_VERSION,
679
if (virNetClientAddProgram(priv->client, priv->remoteProgram) < 0 ||
680
virNetClientAddProgram(priv->client, priv->qemuProgram) < 0)
683
/* Try and authenticate with server */
684
VIR_DEBUG("Trying authentication");
685
if (remoteAuthenticate(conn, priv, auth, authtype) == -1)
688
if (virNetClientKeepAliveIsSupported(priv->client)) {
689
remote_supports_feature_args args =
690
{ VIR_DRV_FEATURE_PROGRAM_KEEPALIVE };
691
remote_supports_feature_ret ret = { 0 };
694
rc = call(conn, priv, 0, REMOTE_PROC_SUPPORTS_FEATURE,
695
(xdrproc_t)xdr_remote_supports_feature_args, (char *) &args,
696
(xdrproc_t)xdr_remote_supports_feature_ret, (char *) &ret);
698
if (rc != -1 && ret.supported) {
699
priv->serverKeepAlive = true;
701
VIR_INFO("Disabling keepalive protocol since it is not supported"
706
/* Finally we can call the remote side's open function. */
708
remote_open_args args = { &name, flags };
710
VIR_DEBUG("Trying to open URI %s", name);
711
if (call (conn, priv, 0, REMOTE_PROC_OPEN,
712
(xdrproc_t) xdr_remote_open_args, (char *) &args,
713
(xdrproc_t) xdr_void, (char *) NULL) == -1)
717
/* Now try and find out what URI the daemon used */
718
if (conn->uri == NULL) {
719
remote_get_uri_ret uriret;
721
VIR_DEBUG("Trying to query remote URI");
722
memset (&uriret, 0, sizeof(uriret));
723
if (call (conn, priv, 0,
725
(xdrproc_t) xdr_void, (char *) NULL,
726
(xdrproc_t) xdr_remote_get_uri_ret, (char *) &uriret) < 0)
729
VIR_DEBUG("Auto-probed URI is %s", uriret.uri);
730
conn->uri = virURIParse(uriret.uri);
731
VIR_FREE(uriret.uri);
736
if (!(priv->domainEventState = virDomainEventStateNew()))
740
retcode = VIR_DRV_OPEN_SUCCESS;
743
/* Free up the URL and strings. */
760
virNetClientProgramFree(priv->remoteProgram);
761
virNetClientProgramFree(priv->qemuProgram);
762
virNetClientClose(priv->client);
763
virNetClientFree(priv->client);
766
VIR_FREE(priv->hostname);
770
static struct private_data *
771
remoteAllocPrivateData(void)
773
struct private_data *priv;
774
if (VIR_ALLOC(priv) < 0) {
779
if (virMutexInit(&priv->lock) < 0) {
780
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
781
_("cannot initialize mutex"));
785
remoteDriverLock(priv);
792
remoteOpenSecondaryDriver(virConnectPtr conn,
793
virConnectAuthPtr auth,
795
struct private_data **priv)
800
if (!((*priv) = remoteAllocPrivateData()))
801
return VIR_DRV_OPEN_ERROR;
803
if (flags & VIR_CONNECT_RO)
804
rflags |= VIR_DRV_OPEN_REMOTE_RO;
806
ret = doRemoteOpen(conn, *priv, auth, rflags);
807
if (ret != VIR_DRV_OPEN_SUCCESS) {
808
remoteDriverUnlock(*priv);
811
(*priv)->localUses = 1;
812
remoteDriverUnlock(*priv);
818
static virDrvOpenStatus
819
remoteOpen (virConnectPtr conn,
820
virConnectAuthPtr auth,
823
struct private_data *priv;
825
const char *autostart = getenv("LIBVIRT_AUTOSTART");
827
if (inside_daemon && (!conn->uri || (conn->uri && !conn->uri->server)))
828
return VIR_DRV_OPEN_DECLINED;
830
if (!(priv = remoteAllocPrivateData()))
831
return VIR_DRV_OPEN_ERROR;
833
if (flags & VIR_CONNECT_RO)
834
rflags |= VIR_DRV_OPEN_REMOTE_RO;
837
* If no servername is given, and no +XXX
838
* transport is listed, or transport is unix,
839
* and path is /session, and uid is unprivileged
840
* then auto-spawn a daemon.
843
!conn->uri->server &&
846
((strchr(conn->uri->scheme, '+') == 0)||
847
(strstr(conn->uri->scheme, "+unix") != NULL)) &&
848
(STREQ(conn->uri->path, "/session") ||
849
STRPREFIX(conn->uri->scheme, "test+")) &&
851
VIR_DEBUG("Auto-spawn user daemon instance");
852
rflags |= VIR_DRV_OPEN_REMOTE_USER;
854
STRNEQ(autostart, "0"))
855
rflags |= VIR_DRV_OPEN_REMOTE_AUTOSTART;
859
* If URI is NULL, then do a UNIX connection possibly auto-spawning
860
* unprivileged server and probe remote server for URI. On Solaris,
861
* this isn't supported, but we may be privileged enough to connect
862
* to the UNIX socket anyway.
865
VIR_DEBUG("Auto-probe remote URI");
868
VIR_DEBUG("Auto-spawn user daemon instance");
869
rflags |= VIR_DRV_OPEN_REMOTE_USER;
871
STRNEQ(autostart, "0"))
872
rflags |= VIR_DRV_OPEN_REMOTE_AUTOSTART;
877
ret = doRemoteOpen(conn, priv, auth, rflags);
878
if (ret != VIR_DRV_OPEN_SUCCESS) {
879
conn->privateData = NULL;
880
remoteDriverUnlock(priv);
883
conn->privateData = priv;
884
remoteDriverUnlock(priv);
890
/* In a string "driver+transport" return a pointer to "transport". */
892
get_transport_from_scheme (char *scheme)
894
char *p = strchr (scheme, '+');
898
/*----------------------------------------------------------------------*/
902
doRemoteClose (virConnectPtr conn, struct private_data *priv)
906
if (call (conn, priv, 0, REMOTE_PROC_CLOSE,
907
(xdrproc_t) xdr_void, (char *) NULL,
908
(xdrproc_t) xdr_void, (char *) NULL) == -1)
911
virNetTLSContextFree(priv->tls);
913
virNetClientClose(priv->client);
914
virNetClientFree(priv->client);
916
virNetClientProgramFree(priv->remoteProgram);
917
virNetClientProgramFree(priv->qemuProgram);
918
priv->remoteProgram = priv->qemuProgram = NULL;
920
/* Free hostname copy */
921
VIR_FREE(priv->hostname);
923
/* See comment for remoteType. */
924
VIR_FREE(priv->type);
926
virDomainEventStateFree(priv->domainEventState);
927
priv->domainEventState = NULL;
933
remoteClose (virConnectPtr conn)
936
struct private_data *priv = conn->privateData;
938
remoteDriverLock(priv);
940
if (!priv->localUses) {
941
ret = doRemoteClose(conn, priv);
942
conn->privateData = NULL;
943
remoteDriverUnlock(priv);
944
virMutexDestroy(&priv->lock);
948
remoteDriverUnlock(priv);
954
/* Unfortunately this function is defined to return a static string.
955
* Since the remote end always answers with the same type (for a
956
* single connection anyway) we cache the type in the connection's
957
* private data, and free it when we close the connection.
960
* http://www.redhat.com/archives/libvir-list/2007-February/msg00096.html
963
remoteType (virConnectPtr conn)
966
remote_get_type_ret ret;
967
struct private_data *priv = conn->privateData;
969
remoteDriverLock(priv);
977
memset (&ret, 0, sizeof(ret));
978
if (call (conn, priv, 0, REMOTE_PROC_GET_TYPE,
979
(xdrproc_t) xdr_void, (char *) NULL,
980
(xdrproc_t) xdr_remote_get_type_ret, (char *) &ret) == -1)
984
rv = priv->type = ret.type;
987
remoteDriverUnlock(priv);
991
static int remoteIsSecure(virConnectPtr conn)
994
struct private_data *priv = conn->privateData;
995
remote_is_secure_ret ret;
996
remoteDriverLock(priv);
998
memset (&ret, 0, sizeof(ret));
999
if (call (conn, priv, 0, REMOTE_PROC_IS_SECURE,
1000
(xdrproc_t) xdr_void, (char *) NULL,
1001
(xdrproc_t) xdr_remote_is_secure_ret, (char *) &ret) == -1)
1004
/* We claim to be secure, if the remote driver
1005
* transport itself is secure, and the remote
1006
* HV connection is secure
1008
* ie, we don't want to claim to be secure if the
1009
* remote driver is used to connect to a XenD
1010
* driver using unencrypted HTTP:/// access
1012
rv = priv->is_secure && ret.secure ? 1 : 0;
1015
remoteDriverUnlock(priv);
1019
static int remoteIsEncrypted(virConnectPtr conn)
1023
struct private_data *priv = conn->privateData;
1024
remote_is_secure_ret ret;
1025
remoteDriverLock(priv);
1027
memset (&ret, 0, sizeof(ret));
1028
if (call (conn, priv, 0, REMOTE_PROC_IS_SECURE,
1029
(xdrproc_t) xdr_void, (char *) NULL,
1030
(xdrproc_t) xdr_remote_is_secure_ret, (char *) &ret) == -1)
1033
if (virNetClientIsEncrypted(priv->client))
1036
/* We claim to be encrypted, if the remote driver
1037
* transport itself is encrypted, and the remote
1038
* HV connection is secure.
1040
* Yes, we really don't check the remote 'encrypted'
1041
* option, since it will almost always be false,
1042
* even if secure (eg UNIX sockets).
1044
rv = encrypted && ret.secure ? 1 : 0;
1047
remoteDriverUnlock(priv);
1052
remoteNodeGetCPUStats (virConnectPtr conn,
1054
virNodeCPUStatsPtr params, int *nparams,
1058
remote_node_get_cpu_stats_args args;
1059
remote_node_get_cpu_stats_ret ret;
1061
struct private_data *priv = conn->privateData;
1063
remoteDriverLock(priv);
1065
args.nparams = *nparams;
1066
args.cpuNum = cpuNum;
1069
memset (&ret, 0, sizeof(ret));
1070
if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_CPU_STATS,
1071
(xdrproc_t) xdr_remote_node_get_cpu_stats_args,
1073
(xdrproc_t) xdr_remote_node_get_cpu_stats_ret,
1074
(char *) &ret) == -1)
1077
/* Check the length of the returned list carefully. */
1078
if (ret.params.params_len > REMOTE_NODE_CPU_STATS_MAX ||
1079
ret.params.params_len > *nparams) {
1080
remoteError(VIR_ERR_RPC, "%s",
1081
_("remoteNodeGetCPUStats: "
1082
"returned number of stats exceeds limit"));
1085
/* Handle the case when the caller does not know the number of stats
1086
* and is asking for the number of stats supported
1088
if (*nparams == 0) {
1089
*nparams = ret.nparams;
1094
*nparams = ret.params.params_len;
1096
/* Deserialise the result. */
1097
for (i = 0; i < *nparams; ++i) {
1098
if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
1099
remoteError(VIR_ERR_INTERNAL_ERROR,
1100
_("Stats %s too big for destination"),
1101
ret.params.params_val[i].field);
1104
params[i].value = ret.params.params_val[i].value;
1110
xdr_free ((xdrproc_t) xdr_remote_node_get_cpu_stats_ret,
1113
remoteDriverUnlock(priv);
1118
remoteNodeGetMemoryStats (virConnectPtr conn,
1120
virNodeMemoryStatsPtr params, int *nparams,
1124
remote_node_get_memory_stats_args args;
1125
remote_node_get_memory_stats_ret ret;
1127
struct private_data *priv = conn->privateData;
1129
remoteDriverLock(priv);
1131
args.nparams = *nparams;
1132
args.cellNum = cellNum;
1135
memset (&ret, 0, sizeof(ret));
1136
if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_MEMORY_STATS,
1137
(xdrproc_t) xdr_remote_node_get_memory_stats_args, (char *) &args,
1138
(xdrproc_t) xdr_remote_node_get_memory_stats_ret, (char *) &ret) == -1)
1141
/* Check the length of the returned list carefully. */
1142
if (ret.params.params_len > REMOTE_NODE_MEMORY_STATS_MAX ||
1143
ret.params.params_len > *nparams) {
1144
remoteError(VIR_ERR_RPC, "%s",
1145
_("remoteNodeGetMemoryStats: "
1146
"returned number of stats exceeds limit"));
1149
/* Handle the case when the caller does not know the number of stats
1150
* and is asking for the number of stats supported
1152
if (*nparams == 0) {
1153
*nparams = ret.nparams;
1158
*nparams = ret.params.params_len;
1160
/* Deserialise the result. */
1161
for (i = 0; i < *nparams; ++i) {
1162
if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) == NULL) {
1163
remoteError(VIR_ERR_INTERNAL_ERROR,
1164
_("Stats %s too big for destination"),
1165
ret.params.params_val[i].field);
1168
params[i].value = ret.params.params_val[i].value;
1174
xdr_free ((xdrproc_t) xdr_remote_node_get_memory_stats_ret,
1177
remoteDriverUnlock(priv);
1182
remoteNodeGetCellsFreeMemory(virConnectPtr conn,
1183
unsigned long long *freeMems,
1188
remote_node_get_cells_free_memory_args args;
1189
remote_node_get_cells_free_memory_ret ret;
1191
struct private_data *priv = conn->privateData;
1193
remoteDriverLock(priv);
1195
if (maxCells > REMOTE_NODE_MAX_CELLS) {
1196
remoteError(VIR_ERR_RPC,
1197
_("too many NUMA cells: %d > %d"),
1198
maxCells, REMOTE_NODE_MAX_CELLS);
1202
args.startCell = startCell;
1203
args.maxcells = maxCells;
1205
memset (&ret, 0, sizeof(ret));
1206
if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_CELLS_FREE_MEMORY,
1207
(xdrproc_t) xdr_remote_node_get_cells_free_memory_args, (char *)&args,
1208
(xdrproc_t) xdr_remote_node_get_cells_free_memory_ret, (char *)&ret) == -1)
1211
for (i = 0 ; i < ret.cells.cells_len ; i++)
1212
freeMems[i] = ret.cells.cells_val[i];
1214
xdr_free((xdrproc_t) xdr_remote_node_get_cells_free_memory_ret, (char *) &ret);
1216
rv = ret.cells.cells_len;
1219
remoteDriverUnlock(priv);
1224
remoteListDomains (virConnectPtr conn, int *ids, int maxids)
1228
remote_list_domains_args args;
1229
remote_list_domains_ret ret;
1230
struct private_data *priv = conn->privateData;
1232
remoteDriverLock(priv);
1234
if (maxids > REMOTE_DOMAIN_ID_LIST_MAX) {
1235
remoteError(VIR_ERR_RPC,
1236
_("too many remote domain IDs: %d > %d"),
1237
maxids, REMOTE_DOMAIN_ID_LIST_MAX);
1240
args.maxids = maxids;
1242
memset (&ret, 0, sizeof(ret));
1243
if (call (conn, priv, 0, REMOTE_PROC_LIST_DOMAINS,
1244
(xdrproc_t) xdr_remote_list_domains_args, (char *) &args,
1245
(xdrproc_t) xdr_remote_list_domains_ret, (char *) &ret) == -1)
1248
if (ret.ids.ids_len > maxids) {
1249
remoteError(VIR_ERR_RPC,
1250
_("too many remote domain IDs: %d > %d"),
1251
ret.ids.ids_len, maxids);
1255
for (i = 0; i < ret.ids.ids_len; ++i)
1256
ids[i] = ret.ids.ids_val[i];
1258
rv = ret.ids.ids_len;
1261
xdr_free ((xdrproc_t) xdr_remote_list_domains_ret, (char *) &ret);
1264
remoteDriverUnlock(priv);
1269
remoteConnectListAllDomains(virConnectPtr conn,
1270
virDomainPtr **domains,
1275
virDomainPtr *doms = NULL;
1276
remote_connect_list_all_domains_args args;
1277
remote_connect_list_all_domains_ret ret;
1279
struct private_data *priv = conn->privateData;
1281
remoteDriverLock(priv);
1283
args.need_results = !!domains;
1286
memset(&ret, 0, sizeof(ret));
1290
REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS,
1291
(xdrproc_t) xdr_remote_connect_list_all_domains_args,
1293
(xdrproc_t) xdr_remote_connect_list_all_domains_ret,
1294
(char *) &ret) == -1)
1298
if (VIR_ALLOC_N(doms, ret.domains.domains_len + 1) < 0) {
1299
virReportOOMError();
1303
for (i = 0; i < ret.domains.domains_len; i++) {
1304
doms[i] = get_nonnull_domain(conn, ret.domains.domains_val[i]);
1306
virReportOOMError();
1318
for (i = 0; i < ret.domains.domains_len; i++)
1320
virDomainFree(doms[i]);
1324
xdr_free((xdrproc_t) xdr_remote_connect_list_all_domains_ret, (char *) &ret);
1327
remoteDriverUnlock(priv);
1331
/* Helper to free typed parameters. */
1333
remoteFreeTypedParameters(remote_typed_param *args_params_val,
1334
u_int args_params_len)
1338
if (args_params_val == NULL)
1341
for (i = 0; i < args_params_len; i++) {
1342
VIR_FREE(args_params_val[i].field);
1343
if (args_params_val[i].value.type == VIR_TYPED_PARAM_STRING)
1344
VIR_FREE(args_params_val[i].value.remote_typed_param_value_u.s);
1347
VIR_FREE(args_params_val);
1350
/* Helper to serialize typed parameters. */
1352
remoteSerializeTypedParameters(virTypedParameterPtr params,
1354
remote_typed_param **args_params_val,
1355
u_int *args_params_len)
1359
remote_typed_param *val;
1361
*args_params_len = nparams;
1362
if (VIR_ALLOC_N(val, nparams) < 0) {
1363
virReportOOMError();
1367
for (i = 0; i < nparams; ++i) {
1368
/* call() will free this: */
1369
val[i].field = strdup (params[i].field);
1370
if (val[i].field == NULL) {
1371
virReportOOMError();
1374
val[i].value.type = params[i].type;
1375
switch (params[i].type) {
1376
case VIR_TYPED_PARAM_INT:
1377
val[i].value.remote_typed_param_value_u.i = params[i].value.i;
1379
case VIR_TYPED_PARAM_UINT:
1380
val[i].value.remote_typed_param_value_u.ui = params[i].value.ui;
1382
case VIR_TYPED_PARAM_LLONG:
1383
val[i].value.remote_typed_param_value_u.l = params[i].value.l;
1385
case VIR_TYPED_PARAM_ULLONG:
1386
val[i].value.remote_typed_param_value_u.ul = params[i].value.ul;
1388
case VIR_TYPED_PARAM_DOUBLE:
1389
val[i].value.remote_typed_param_value_u.d = params[i].value.d;
1391
case VIR_TYPED_PARAM_BOOLEAN:
1392
val[i].value.remote_typed_param_value_u.b = params[i].value.b;
1394
case VIR_TYPED_PARAM_STRING:
1395
val[i].value.remote_typed_param_value_u.s = strdup(params[i].value.s);
1396
if (val[i].value.remote_typed_param_value_u.s == NULL) {
1397
virReportOOMError();
1402
remoteError(VIR_ERR_RPC, _("unknown parameter type: %d"),
1408
*args_params_val = val;
1413
remoteFreeTypedParameters(val, nparams);
1417
/* Helper to deserialize typed parameters. */
1419
remoteDeserializeTypedParameters(remote_typed_param *ret_params_val,
1420
u_int ret_params_len,
1422
virTypedParameterPtr params,
1428
/* Check the length of the returned list carefully. */
1429
if (ret_params_len > limit || ret_params_len > *nparams) {
1430
remoteError(VIR_ERR_RPC, "%s",
1431
_("returned number of parameters exceeds limit"));
1435
*nparams = ret_params_len;
1437
/* Deserialise the result. */
1438
for (i = 0; i < ret_params_len; ++i) {
1439
if (virStrcpyStatic(params[i].field,
1440
ret_params_val[i].field) == NULL) {
1441
remoteError(VIR_ERR_INTERNAL_ERROR,
1442
_("Parameter %s too big for destination"),
1443
ret_params_val[i].field);
1446
params[i].type = ret_params_val[i].value.type;
1447
switch (params[i].type) {
1448
case VIR_TYPED_PARAM_INT:
1450
ret_params_val[i].value.remote_typed_param_value_u.i;
1452
case VIR_TYPED_PARAM_UINT:
1453
params[i].value.ui =
1454
ret_params_val[i].value.remote_typed_param_value_u.ui;
1456
case VIR_TYPED_PARAM_LLONG:
1458
ret_params_val[i].value.remote_typed_param_value_u.l;
1460
case VIR_TYPED_PARAM_ULLONG:
1461
params[i].value.ul =
1462
ret_params_val[i].value.remote_typed_param_value_u.ul;
1464
case VIR_TYPED_PARAM_DOUBLE:
1466
ret_params_val[i].value.remote_typed_param_value_u.d;
1468
case VIR_TYPED_PARAM_BOOLEAN:
1470
ret_params_val[i].value.remote_typed_param_value_u.b;
1472
case VIR_TYPED_PARAM_STRING:
1474
strdup(ret_params_val[i].value.remote_typed_param_value_u.s);
1475
if (params[i].value.s == NULL) {
1476
virReportOOMError();
1481
remoteError(VIR_ERR_RPC, _("unknown parameter type: %d"),
1491
virTypedParameterArrayClear(params, i);
1496
remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val,
1497
u_int ret_errors_len,
1499
virDomainDiskErrorPtr errors,
1505
if (ret_errors_len > limit || ret_errors_len > maxerrors) {
1506
remoteError(VIR_ERR_RPC, "%s",
1507
_("returned number of disk errors exceeds limit"));
1511
for (i = 0; i < ret_errors_len; i++) {
1512
if (!(errors[i].disk = strdup(ret_errors_val[i].disk))) {
1513
virReportOOMError();
1516
errors[i].error = ret_errors_val[i].error;
1522
for (j = 0; j < i; j++)
1523
VIR_FREE(errors[i].disk);
1529
remoteDomainBlockStatsFlags(virDomainPtr domain,
1531
virTypedParameterPtr params,
1536
remote_domain_block_stats_flags_args args;
1537
remote_domain_block_stats_flags_ret ret;
1538
struct private_data *priv = domain->conn->privateData;
1540
remoteDriverLock(priv);
1542
make_nonnull_domain (&args.dom, domain);
1543
args.nparams = *nparams;
1544
args.path = (char *) path;
1547
memset (&ret, 0, sizeof(ret));
1548
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS,
1549
(xdrproc_t) xdr_remote_domain_block_stats_flags_args, (char *) &args,
1550
(xdrproc_t) xdr_remote_domain_block_stats_flags_ret, (char *) &ret) == -1)
1553
/* Check the length of the returned list carefully. */
1554
if (ret.params.params_len > REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX ||
1555
ret.params.params_len > *nparams) {
1556
remoteError(VIR_ERR_RPC, "%s",
1557
_("remoteDomainBlockStatsFlags: "
1558
"returned number of stats exceeds limit"));
1562
/* Handle the case when the caller does not know the number of stats
1563
* and is asking for the number of stats supported
1565
if (*nparams == 0) {
1566
*nparams = ret.nparams;
1571
*nparams = ret.params.params_len;
1573
/* Deserialise the result. */
1574
if (remoteDeserializeTypedParameters(ret.params.params_val,
1575
ret.params.params_len,
1576
REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
1584
xdr_free ((xdrproc_t) xdr_remote_domain_block_stats_flags_ret,
1587
remoteDriverUnlock(priv);
1592
remoteDomainGetMemoryParameters (virDomainPtr domain,
1593
virTypedParameterPtr params, int *nparams,
1597
remote_domain_get_memory_parameters_args args;
1598
remote_domain_get_memory_parameters_ret ret;
1599
struct private_data *priv = domain->conn->privateData;
1601
remoteDriverLock(priv);
1603
make_nonnull_domain (&args.dom, domain);
1604
args.nparams = *nparams;
1607
memset (&ret, 0, sizeof(ret));
1608
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS,
1609
(xdrproc_t) xdr_remote_domain_get_memory_parameters_args, (char *) &args,
1610
(xdrproc_t) xdr_remote_domain_get_memory_parameters_ret, (char *) &ret) == -1)
1613
/* Handle the case when the caller does not know the number of parameters
1614
* and is asking for the number of parameters supported
1616
if (*nparams == 0) {
1617
*nparams = ret.nparams;
1622
if (remoteDeserializeTypedParameters(ret.params.params_val,
1623
ret.params.params_len,
1624
REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
1632
xdr_free ((xdrproc_t) xdr_remote_domain_get_memory_parameters_ret,
1635
remoteDriverUnlock(priv);
1640
remoteDomainGetNumaParameters (virDomainPtr domain,
1641
virTypedParameterPtr params, int *nparams,
1645
remote_domain_get_numa_parameters_args args;
1646
remote_domain_get_numa_parameters_ret ret;
1647
struct private_data *priv = domain->conn->privateData;
1649
remoteDriverLock(priv);
1651
make_nonnull_domain (&args.dom, domain);
1652
args.nparams = *nparams;
1655
memset (&ret, 0, sizeof(ret));
1656
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_NUMA_PARAMETERS,
1657
(xdrproc_t) xdr_remote_domain_get_numa_parameters_args, (char *) &args,
1658
(xdrproc_t) xdr_remote_domain_get_numa_parameters_ret, (char *) &ret) == -1)
1661
/* Handle the case when the caller does not know the number of parameters
1662
* and is asking for the number of parameters supported
1664
if (*nparams == 0) {
1665
*nparams = ret.nparams;
1670
if (remoteDeserializeTypedParameters(ret.params.params_val,
1671
ret.params.params_len,
1672
REMOTE_DOMAIN_NUMA_PARAMETERS_MAX,
1680
xdr_free ((xdrproc_t) xdr_remote_domain_get_numa_parameters_ret,
1683
remoteDriverUnlock(priv);
1688
remoteDomainGetBlkioParameters (virDomainPtr domain,
1689
virTypedParameterPtr params, int *nparams,
1693
remote_domain_get_blkio_parameters_args args;
1694
remote_domain_get_blkio_parameters_ret ret;
1695
struct private_data *priv = domain->conn->privateData;
1697
remoteDriverLock(priv);
1699
make_nonnull_domain (&args.dom, domain);
1700
args.nparams = *nparams;
1703
memset (&ret, 0, sizeof(ret));
1704
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS,
1705
(xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, (char *) &args,
1706
(xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1)
1709
/* Handle the case when the caller does not know the number of parameters
1710
* and is asking for the number of parameters supported
1712
if (*nparams == 0) {
1713
*nparams = ret.nparams;
1718
if (remoteDeserializeTypedParameters(ret.params.params_val,
1719
ret.params.params_len,
1720
REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX,
1728
xdr_free ((xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret,
1731
remoteDriverUnlock(priv);
1736
remoteDomainGetVcpuPinInfo (virDomainPtr domain,
1738
unsigned char *cpumaps,
1744
remote_domain_get_vcpu_pin_info_args args;
1745
remote_domain_get_vcpu_pin_info_ret ret;
1746
struct private_data *priv = domain->conn->privateData;
1748
remoteDriverLock(priv);
1750
if (ncpumaps > REMOTE_VCPUINFO_MAX) {
1751
remoteError(VIR_ERR_RPC,
1752
_("vCPU count exceeds maximum: %d > %d"),
1753
ncpumaps, REMOTE_VCPUINFO_MAX);
1757
if (INT_MULTIPLY_OVERFLOW(ncpumaps, maplen) ||
1758
ncpumaps * maplen > REMOTE_CPUMAPS_MAX) {
1759
remoteError(VIR_ERR_RPC,
1760
_("vCPU map buffer length exceeds maximum: %d > %d"),
1761
ncpumaps * maplen, REMOTE_CPUMAPS_MAX);
1765
make_nonnull_domain (&args.dom, domain);
1766
args.ncpumaps = ncpumaps;
1767
args.maplen = maplen;
1770
memset (&ret, 0, sizeof(ret));
1772
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO,
1773
(xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_args,
1775
(xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_ret,
1776
(char *) &ret) == -1)
1779
if (ret.num > ncpumaps) {
1780
remoteError(VIR_ERR_RPC,
1781
_("host reports too many vCPUs: %d > %d"),
1786
if (ret.cpumaps.cpumaps_len > ncpumaps * maplen) {
1787
remoteError(VIR_ERR_RPC,
1788
_("host reports map buffer length exceeds maximum: %d > %d"),
1789
ret.cpumaps.cpumaps_len, ncpumaps * maplen);
1793
memset (cpumaps, 0, ncpumaps * maplen);
1795
for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
1796
cpumaps[i] = ret.cpumaps.cpumaps_val[i];
1801
xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_ret, (char *) &ret);
1804
remoteDriverUnlock(priv);
1809
remoteDomainGetVcpus (virDomainPtr domain,
1810
virVcpuInfoPtr info,
1812
unsigned char *cpumaps,
1817
remote_domain_get_vcpus_args args;
1818
remote_domain_get_vcpus_ret ret;
1819
struct private_data *priv = domain->conn->privateData;
1821
remoteDriverLock(priv);
1823
if (maxinfo > REMOTE_VCPUINFO_MAX) {
1824
remoteError(VIR_ERR_RPC,
1825
_("vCPU count exceeds maximum: %d > %d"),
1826
maxinfo, REMOTE_VCPUINFO_MAX);
1829
if (INT_MULTIPLY_OVERFLOW(maxinfo, maplen) ||
1830
maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
1831
remoteError(VIR_ERR_RPC,
1832
_("vCPU map buffer length exceeds maximum: %d > %d"),
1833
maxinfo * maplen, REMOTE_CPUMAPS_MAX);
1837
make_nonnull_domain (&args.dom, domain);
1838
args.maxinfo = maxinfo;
1839
args.maplen = maplen;
1841
memset (&ret, 0, sizeof(ret));
1842
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS,
1843
(xdrproc_t) xdr_remote_domain_get_vcpus_args, (char *) &args,
1844
(xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret) == -1)
1847
if (ret.info.info_len > maxinfo) {
1848
remoteError(VIR_ERR_RPC,
1849
_("host reports too many vCPUs: %d > %d"),
1850
ret.info.info_len, maxinfo);
1853
if (ret.cpumaps.cpumaps_len > maxinfo * maplen) {
1854
remoteError(VIR_ERR_RPC,
1855
_("host reports map buffer length exceeds maximum: %d > %d"),
1856
ret.cpumaps.cpumaps_len, maxinfo * maplen);
1860
memset (info, 0, sizeof(virVcpuInfo) * maxinfo);
1861
memset (cpumaps, 0, maxinfo * maplen);
1863
for (i = 0; i < ret.info.info_len; ++i) {
1864
info[i].number = ret.info.info_val[i].number;
1865
info[i].state = ret.info.info_val[i].state;
1866
info[i].cpuTime = ret.info.info_val[i].cpu_time;
1867
info[i].cpu = ret.info.info_val[i].cpu;
1870
for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
1871
cpumaps[i] = ret.cpumaps.cpumaps_val[i];
1873
rv = ret.info.info_len;
1876
xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret);
1879
remoteDriverUnlock(priv);
1884
remoteDomainGetSecurityLabel (virDomainPtr domain, virSecurityLabelPtr seclabel)
1886
remote_domain_get_security_label_args args;
1887
remote_domain_get_security_label_ret ret;
1888
struct private_data *priv = domain->conn->privateData;
1891
remoteDriverLock(priv);
1893
make_nonnull_domain (&args.dom, domain);
1894
memset (&ret, 0, sizeof(ret));
1895
memset (seclabel, 0, sizeof(*seclabel));
1897
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL,
1898
(xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args,
1899
(xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) == -1) {
1903
if (ret.label.label_val != NULL) {
1904
if (strlen (ret.label.label_val) >= sizeof(seclabel->label)) {
1905
remoteError(VIR_ERR_RPC, _("security label exceeds maximum: %zu"),
1906
sizeof(seclabel->label) - 1);
1909
strcpy (seclabel->label, ret.label.label_val);
1910
seclabel->enforcing = ret.enforcing;
1916
xdr_free((xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret);
1919
remoteDriverUnlock(priv);
1924
remoteDomainGetState(virDomainPtr domain,
1930
remote_domain_get_state_args args;
1931
remote_domain_get_state_ret ret;
1932
struct private_data *priv = domain->conn->privateData;
1934
remoteDriverLock(priv);
1936
make_nonnull_domain(&args.dom, domain);
1939
memset(&ret, 0, sizeof(ret));
1940
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_STATE,
1941
(xdrproc_t) xdr_remote_domain_get_state_args, (char *) &args,
1942
(xdrproc_t) xdr_remote_domain_get_state_ret, (char *) &ret) == -1)
1947
*reason = ret.reason;
1952
remoteDriverUnlock(priv);
1957
remoteNodeGetSecurityModel (virConnectPtr conn, virSecurityModelPtr secmodel)
1959
remote_node_get_security_model_ret ret;
1960
struct private_data *priv = conn->privateData;
1963
remoteDriverLock(priv);
1965
memset (&ret, 0, sizeof(ret));
1966
memset (secmodel, 0, sizeof(*secmodel));
1968
if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL,
1969
(xdrproc_t) xdr_void, NULL,
1970
(xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) == -1) {
1974
if (ret.model.model_val != NULL) {
1975
if (strlen (ret.model.model_val) >= sizeof(secmodel->model)) {
1976
remoteError(VIR_ERR_RPC, _("security model exceeds maximum: %zu"),
1977
sizeof(secmodel->model) - 1);
1980
strcpy (secmodel->model, ret.model.model_val);
1983
if (ret.doi.doi_val != NULL) {
1984
if (strlen (ret.doi.doi_val) >= sizeof(secmodel->doi)) {
1985
remoteError(VIR_ERR_RPC, _("security doi exceeds maximum: %zu"),
1986
sizeof(secmodel->doi) - 1);
1989
strcpy (secmodel->doi, ret.doi.doi_val);
1995
xdr_free((xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret);
1998
remoteDriverUnlock(priv);
2003
remoteDomainMigratePrepare (virConnectPtr dconn,
2004
char **cookie, int *cookielen,
2005
const char *uri_in, char **uri_out,
2006
unsigned long flags, const char *dname,
2007
unsigned long resource)
2010
remote_domain_migrate_prepare_args args;
2011
remote_domain_migrate_prepare_ret ret;
2012
struct private_data *priv = dconn->privateData;
2014
remoteDriverLock(priv);
2016
args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
2018
args.dname = dname == NULL ? NULL : (char **) &dname;
2019
args.resource = resource;
2021
memset (&ret, 0, sizeof(ret));
2022
if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE,
2023
(xdrproc_t) xdr_remote_domain_migrate_prepare_args, (char *) &args,
2024
(xdrproc_t) xdr_remote_domain_migrate_prepare_ret, (char *) &ret) == -1)
2027
if (ret.cookie.cookie_len > 0) {
2028
*cookie = ret.cookie.cookie_val; /* Caller frees. */
2029
*cookielen = ret.cookie.cookie_len;
2032
*uri_out = *ret.uri_out; /* Caller frees. */
2034
VIR_FREE(ret.uri_out);
2038
remoteDriverUnlock(priv);
2043
remoteDomainMigratePrepare2 (virConnectPtr dconn,
2044
char **cookie, int *cookielen,
2045
const char *uri_in, char **uri_out,
2046
unsigned long flags, const char *dname,
2047
unsigned long resource,
2048
const char *dom_xml)
2051
remote_domain_migrate_prepare2_args args;
2052
remote_domain_migrate_prepare2_ret ret;
2053
struct private_data *priv = dconn->privateData;
2055
remoteDriverLock(priv);
2057
args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
2059
args.dname = dname == NULL ? NULL : (char **) &dname;
2060
args.resource = resource;
2061
args.dom_xml = (char *) dom_xml;
2063
memset (&ret, 0, sizeof(ret));
2064
if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE2,
2065
(xdrproc_t) xdr_remote_domain_migrate_prepare2_args, (char *) &args,
2066
(xdrproc_t) xdr_remote_domain_migrate_prepare2_ret, (char *) &ret) == -1)
2069
if (ret.cookie.cookie_len > 0) {
2070
if (!cookie || !cookielen) {
2071
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
2072
_("caller ignores cookie or cookielen"));
2075
*cookie = ret.cookie.cookie_val; /* Caller frees. */
2076
*cookielen = ret.cookie.cookie_len;
2080
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
2081
_("caller ignores uri_out"));
2084
*uri_out = *ret.uri_out; /* Caller frees. */
2090
VIR_FREE(ret.uri_out);
2091
remoteDriverUnlock(priv);
2094
if (ret.cookie.cookie_len)
2095
VIR_FREE(ret.cookie.cookie_val);
2097
VIR_FREE(*ret.uri_out);
2102
remoteDomainCreate (virDomainPtr domain)
2105
remote_domain_create_args args;
2106
remote_domain_lookup_by_uuid_args args2;
2107
remote_domain_lookup_by_uuid_ret ret2;
2108
struct private_data *priv = domain->conn->privateData;
2110
remoteDriverLock(priv);
2112
make_nonnull_domain (&args.dom, domain);
2114
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_CREATE,
2115
(xdrproc_t) xdr_remote_domain_create_args, (char *) &args,
2116
(xdrproc_t) xdr_void, (char *) NULL) == -1)
2119
/* Need to do a lookup figure out ID of newly started guest, because
2120
* bug in design of REMOTE_PROC_DOMAIN_CREATE means we aren't getting
2123
memcpy (args2.uuid, domain->uuid, VIR_UUID_BUFLEN);
2124
memset (&ret2, 0, sizeof(ret2));
2125
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID,
2126
(xdrproc_t) xdr_remote_domain_lookup_by_uuid_args, (char *) &args2,
2127
(xdrproc_t) xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2) == -1)
2130
domain->id = ret2.dom.id;
2131
xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2);
2136
remoteDriverUnlock(priv);
2141
remoteDomainGetSchedulerType (virDomainPtr domain, int *nparams)
2144
remote_domain_get_scheduler_type_args args;
2145
remote_domain_get_scheduler_type_ret ret;
2146
struct private_data *priv = domain->conn->privateData;
2148
remoteDriverLock(priv);
2150
make_nonnull_domain (&args.dom, domain);
2152
memset (&ret, 0, sizeof(ret));
2153
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE,
2154
(xdrproc_t) xdr_remote_domain_get_scheduler_type_args, (char *) &args,
2155
(xdrproc_t) xdr_remote_domain_get_scheduler_type_ret, (char *) &ret) == -1)
2158
if (nparams) *nparams = ret.nparams;
2160
/* Caller frees this. */
2164
remoteDriverUnlock(priv);
2169
remoteDomainMemoryStats (virDomainPtr domain,
2170
struct _virDomainMemoryStat *stats,
2171
unsigned int nr_stats,
2175
remote_domain_memory_stats_args args;
2176
remote_domain_memory_stats_ret ret;
2177
struct private_data *priv = domain->conn->privateData;
2180
remoteDriverLock(priv);
2182
make_nonnull_domain (&args.dom, domain);
2183
if (nr_stats > REMOTE_DOMAIN_MEMORY_STATS_MAX) {
2184
remoteError(VIR_ERR_RPC,
2185
_("too many memory stats requested: %d > %d"), nr_stats,
2186
REMOTE_DOMAIN_MEMORY_STATS_MAX);
2189
args.maxStats = nr_stats;
2191
memset (&ret, 0, sizeof(ret));
2193
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_STATS,
2194
(xdrproc_t) xdr_remote_domain_memory_stats_args,
2196
(xdrproc_t) xdr_remote_domain_memory_stats_ret,
2197
(char *) &ret) == -1)
2200
for (i = 0; i < ret.stats.stats_len; i++) {
2201
stats[i].tag = ret.stats.stats_val[i].tag;
2202
stats[i].val = ret.stats.stats_val[i].val;
2204
rv = ret.stats.stats_len;
2205
xdr_free((xdrproc_t) xdr_remote_domain_memory_stats_ret, (char *) &ret);
2208
remoteDriverUnlock(priv);
2213
remoteDomainBlockPeek (virDomainPtr domain,
2215
unsigned long long offset,
2221
remote_domain_block_peek_args args;
2222
remote_domain_block_peek_ret ret;
2223
struct private_data *priv = domain->conn->privateData;
2225
remoteDriverLock(priv);
2227
if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
2228
remoteError(VIR_ERR_RPC,
2229
_("block peek request too large for remote protocol, %zi > %d"),
2230
size, REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX);
2234
make_nonnull_domain (&args.dom, domain);
2235
args.path = (char *) path;
2236
args.offset = offset;
2240
memset (&ret, 0, sizeof(ret));
2241
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_PEEK,
2242
(xdrproc_t) xdr_remote_domain_block_peek_args,
2244
(xdrproc_t) xdr_remote_domain_block_peek_ret,
2245
(char *) &ret) == -1)
2248
if (ret.buffer.buffer_len != size) {
2249
remoteError(VIR_ERR_RPC, "%s",
2250
_("returned buffer is not same size as requested"));
2254
memcpy (buffer, ret.buffer.buffer_val, size);
2258
VIR_FREE(ret.buffer.buffer_val);
2261
remoteDriverUnlock(priv);
2266
remoteDomainMemoryPeek (virDomainPtr domain,
2267
unsigned long long offset,
2273
remote_domain_memory_peek_args args;
2274
remote_domain_memory_peek_ret ret;
2275
struct private_data *priv = domain->conn->privateData;
2277
remoteDriverLock(priv);
2279
if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) {
2280
remoteError(VIR_ERR_RPC,
2281
_("memory peek request too large for remote protocol, %zi > %d"),
2282
size, REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX);
2286
make_nonnull_domain (&args.dom, domain);
2287
args.offset = offset;
2291
memset (&ret, 0, sizeof(ret));
2292
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_PEEK,
2293
(xdrproc_t) xdr_remote_domain_memory_peek_args,
2295
(xdrproc_t) xdr_remote_domain_memory_peek_ret,
2296
(char *) &ret) == -1)
2299
if (ret.buffer.buffer_len != size) {
2300
remoteError(VIR_ERR_RPC, "%s",
2301
_("returned buffer is not same size as requested"));
2305
memcpy (buffer, ret.buffer.buffer_val, size);
2309
VIR_FREE(ret.buffer.buffer_val);
2312
remoteDriverUnlock(priv);
2316
static int remoteDomainGetBlockJobInfo(virDomainPtr domain,
2318
virDomainBlockJobInfoPtr info,
2322
remote_domain_get_block_job_info_args args;
2323
remote_domain_get_block_job_info_ret ret;
2324
struct private_data *priv = domain->conn->privateData;
2326
remoteDriverLock(priv);
2328
make_nonnull_domain(&args.dom, domain);
2329
args.path = (char *)path;
2332
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO,
2333
(xdrproc_t)xdr_remote_domain_get_block_job_info_args,
2335
(xdrproc_t)xdr_remote_domain_get_block_job_info_ret,
2336
(char *)&ret) == -1)
2340
info->type = ret.type;
2341
info->bandwidth = ret.bandwidth;
2342
info->cur = ret.cur;
2343
info->end = ret.end;
2350
remoteDriverUnlock(priv);
2354
static int remoteDomainGetBlockIoTune(virDomainPtr domain,
2356
virTypedParameterPtr params,
2361
remote_domain_get_block_io_tune_args args;
2362
remote_domain_get_block_io_tune_ret ret;
2363
struct private_data *priv = domain->conn->privateData;
2365
remoteDriverLock(priv);
2367
make_nonnull_domain(&args.dom, domain);
2368
args.disk = disk ? (char **)&disk : NULL;
2369
args.nparams = *nparams;
2372
memset(&ret, 0, sizeof(ret));
2375
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_IO_TUNE,
2376
(xdrproc_t) xdr_remote_domain_get_block_io_tune_args,
2378
(xdrproc_t) xdr_remote_domain_get_block_io_tune_ret,
2379
(char *) &ret) == -1) {
2383
/* Handle the case when the caller does not know the number of parameters
2384
* and is asking for the number of parameters supported
2386
if (*nparams == 0) {
2387
*nparams = ret.nparams;
2392
if (remoteDeserializeTypedParameters(ret.params.params_val,
2393
ret.params.params_len,
2394
REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
2402
xdr_free ((xdrproc_t) xdr_remote_domain_get_block_io_tune_ret,
2405
remoteDriverUnlock(priv);
2409
static int remoteDomainGetCPUStats(virDomainPtr domain,
2410
virTypedParameterPtr params,
2411
unsigned int nparams,
2416
struct private_data *priv = domain->conn->privateData;
2417
remote_domain_get_cpu_stats_args args;
2418
remote_domain_get_cpu_stats_ret ret;
2422
remoteDriverLock(priv);
2424
if (nparams > REMOTE_NODE_CPU_STATS_MAX) {
2425
remoteError(VIR_ERR_RPC,
2426
_("nparams count exceeds maximum: %u > %u"),
2427
nparams, REMOTE_NODE_CPU_STATS_MAX);
2430
if (ncpus > REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX) {
2431
remoteError(VIR_ERR_RPC,
2432
_("ncpus count exceeds maximum: %u > %u"),
2433
ncpus, REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX);
2437
make_nonnull_domain(&args.dom, domain);
2438
args.nparams = nparams;
2439
args.start_cpu = start_cpu;
2443
memset(&ret, 0, sizeof(ret));
2445
if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_CPU_STATS,
2446
(xdrproc_t) xdr_remote_domain_get_cpu_stats_args,
2448
(xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
2449
(char *) &ret) == -1)
2452
/* Check the length of the returned list carefully. */
2453
if (ret.params.params_len > nparams * ncpus ||
2454
(ret.params.params_len &&
2455
((ret.params.params_len % ret.nparams) || ret.nparams > nparams))) {
2456
remoteError(VIR_ERR_RPC, "%s",
2457
_("remoteDomainGetCPUStats: "
2458
"returned number of stats exceeds limit"));
2459
memset(params, 0, sizeof(*params) * nparams * ncpus);
2463
/* Handle the case when the caller does not know the number of stats
2464
* and is asking for the number of stats supported
2471
/* The remote side did not send back any zero entries, so we have
2472
* to expand things back into a possibly sparse array, where the
2473
* tail of the array may be omitted.
2475
memset(params, 0, sizeof(*params) * nparams * ncpus);
2476
ncpus = ret.params.params_len / ret.nparams;
2477
for (cpu = 0; cpu < ncpus; cpu++) {
2479
remote_typed_param *stride = &ret.params.params_val[cpu * ret.nparams];
2481
if (remoteDeserializeTypedParameters(stride, ret.nparams,
2482
REMOTE_NODE_CPU_STATS_MAX,
2483
¶ms[cpu * nparams],
2491
virTypedParameterArrayClear(params, nparams * ncpus);
2493
xdr_free ((xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
2496
remoteDriverUnlock(priv);
2501
/*----------------------------------------------------------------------*/
2503
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
2504
remoteGenericOpen(virConnectPtr conn, virConnectAuthPtr auth,
2505
unsigned int flags, void **genericPrivateData)
2508
return VIR_DRV_OPEN_DECLINED;
2511
STREQ (conn->driver->name, "remote")) {
2512
struct private_data *priv;
2514
/* If we're here, the remote driver is already
2515
* in use due to a) a QEMU uri, or b) a remote
2516
* URI. So we can re-use existing connection */
2517
priv = conn->privateData;
2518
remoteDriverLock(priv);
2520
*genericPrivateData = priv;
2521
remoteDriverUnlock(priv);
2522
return VIR_DRV_OPEN_SUCCESS;
2523
} else if (conn->networkDriver &&
2524
STREQ (conn->networkDriver->name, "remote")) {
2525
struct private_data *priv = conn->networkPrivateData;
2526
remoteDriverLock(priv);
2527
*genericPrivateData = priv;
2529
remoteDriverUnlock(priv);
2530
return VIR_DRV_OPEN_SUCCESS;
2532
/* Using a non-remote driver, so we need to open a
2533
* new connection for network APIs, forcing it to
2534
* use the UNIX transport. This handles Xen driver
2535
* which doesn't have its own impl of the network APIs. */
2536
struct private_data *priv;
2537
int ret = remoteOpenSecondaryDriver(conn, auth, flags, &priv);
2538
*genericPrivateData = priv;
2544
remoteGenericClose(virConnectPtr conn, void **genericPrivateData)
2547
struct private_data *priv = *genericPrivateData;
2549
remoteDriverLock(priv);
2551
if (!priv->localUses) {
2552
rv = doRemoteClose(conn, priv);
2553
*genericPrivateData = NULL;
2554
remoteDriverUnlock(priv);
2555
virMutexDestroy(&priv->lock);
2559
remoteDriverUnlock(priv);
2563
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
2564
remoteNetworkOpen(virConnectPtr conn, virConnectAuthPtr auth,
2567
return remoteGenericOpen(conn, auth, flags, &conn->networkPrivateData);
2571
remoteNetworkClose(virConnectPtr conn)
2573
return remoteGenericClose(conn, &conn->networkPrivateData);
2576
/*----------------------------------------------------------------------*/
2578
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
2579
remoteInterfaceOpen(virConnectPtr conn, virConnectAuthPtr auth,
2582
return remoteGenericOpen(conn, auth, flags, &conn->interfacePrivateData);
2586
remoteInterfaceClose(virConnectPtr conn)
2588
return remoteGenericClose(conn, &conn->interfacePrivateData);
2591
/*----------------------------------------------------------------------*/
2593
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
2594
remoteStorageOpen(virConnectPtr conn, virConnectAuthPtr auth,
2597
return remoteGenericOpen(conn, auth, flags, &conn->storagePrivateData);
2601
remoteStorageClose(virConnectPtr conn)
2603
return remoteGenericClose(conn, &conn->storagePrivateData);
2607
remoteFindStoragePoolSources (virConnectPtr conn,
2609
const char *srcSpec,
2613
remote_find_storage_pool_sources_args args;
2614
remote_find_storage_pool_sources_ret ret;
2615
struct private_data *priv = conn->storagePrivateData;
2616
const char *emptyString = "";
2618
remoteDriverLock(priv);
2620
args.type = (char*)type;
2622
* I'd think the following would work here:
2623
* args.srcSpec = (char**)&srcSpec;
2624
* since srcSpec is a remote_string (not a remote_nonnull_string).
2626
* But when srcSpec is NULL, this yields:
2627
* libvir: Remote error : marshaling args
2629
* So for now I'm working around this by turning NULL srcSpecs
2630
* into empty strings.
2632
args.srcSpec = srcSpec ? (char **)&srcSpec : (char **)&emptyString;
2635
memset (&ret, 0, sizeof(ret));
2636
if (call (conn, priv, 0, REMOTE_PROC_FIND_STORAGE_POOL_SOURCES,
2637
(xdrproc_t) xdr_remote_find_storage_pool_sources_args, (char *) &args,
2638
(xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret) == -1)
2642
ret.xml = NULL; /* To stop xdr_free free'ing it */
2644
xdr_free ((xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret);
2647
remoteDriverUnlock(priv);
2651
/*----------------------------------------------------------------------*/
2653
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
2654
remoteDevMonOpen(virConnectPtr conn, virConnectAuthPtr auth,
2657
return remoteGenericOpen(conn, auth, flags, &conn->devMonPrivateData);
2661
remoteDevMonClose(virConnectPtr conn)
2663
return remoteGenericClose(conn, &conn->devMonPrivateData);
2667
remoteNodeDeviceDettach (virNodeDevicePtr dev)
2670
remote_node_device_dettach_args args;
2671
/* This method is unusual in that it uses the HV driver, not the devMon driver
2672
* hence its use of privateData, instead of devMonPrivateData */
2673
struct private_data *priv = dev->conn->privateData;
2675
remoteDriverLock(priv);
2677
args.name = dev->name;
2679
if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DETTACH,
2680
(xdrproc_t) xdr_remote_node_device_dettach_args, (char *) &args,
2681
(xdrproc_t) xdr_void, (char *) NULL) == -1)
2687
remoteDriverUnlock(priv);
2692
remoteNodeDeviceReAttach (virNodeDevicePtr dev)
2695
remote_node_device_re_attach_args args;
2696
/* This method is unusual in that it uses the HV driver, not the devMon driver
2697
* hence its use of privateData, instead of devMonPrivateData */
2698
struct private_data *priv = dev->conn->privateData;
2700
remoteDriverLock(priv);
2702
args.name = dev->name;
2704
if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RE_ATTACH,
2705
(xdrproc_t) xdr_remote_node_device_re_attach_args, (char *) &args,
2706
(xdrproc_t) xdr_void, (char *) NULL) == -1)
2712
remoteDriverUnlock(priv);
2717
remoteNodeDeviceReset (virNodeDevicePtr dev)
2720
remote_node_device_reset_args args;
2721
/* This method is unusual in that it uses the HV driver, not the devMon driver
2722
* hence its use of privateData, instead of devMonPrivateData */
2723
struct private_data *priv = dev->conn->privateData;
2725
remoteDriverLock(priv);
2727
args.name = dev->name;
2729
if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RESET,
2730
(xdrproc_t) xdr_remote_node_device_reset_args, (char *) &args,
2731
(xdrproc_t) xdr_void, (char *) NULL) == -1)
2737
remoteDriverUnlock(priv);
2741
/* ------------------------------------------------------------- */
2743
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
2744
remoteNWFilterOpen(virConnectPtr conn, virConnectAuthPtr auth,
2747
return remoteGenericOpen(conn, auth, flags, &conn->nwfilterPrivateData);
2751
remoteNWFilterClose(virConnectPtr conn)
2753
return remoteGenericClose(conn, &conn->nwfilterPrivateData);
2756
/*----------------------------------------------------------------------*/
2759
remoteAuthenticate (virConnectPtr conn, struct private_data *priv,
2760
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
2761
const char *authtype)
2763
struct remote_auth_list_ret ret;
2764
int err, type = REMOTE_AUTH_NONE;
2766
memset(&ret, 0, sizeof(ret));
2767
err = call (conn, priv, 0,
2768
REMOTE_PROC_AUTH_LIST,
2769
(xdrproc_t) xdr_void, (char *) NULL,
2770
(xdrproc_t) xdr_remote_auth_list_ret, (char *) &ret);
2772
virErrorPtr verr = virGetLastError();
2773
if (verr && verr->code == VIR_ERR_NO_SUPPORT) {
2774
/* Missing RPC - old server - ignore */
2775
virResetLastError();
2781
if (ret.types.types_len == 0)
2786
if (STRCASEEQ(authtype, "sasl") ||
2787
STRCASEEQLEN(authtype, "sasl.", 5)) {
2788
want = REMOTE_AUTH_SASL;
2789
} else if (STRCASEEQ(authtype, "polkit")) {
2790
want = REMOTE_AUTH_POLKIT;
2792
remoteError(VIR_ERR_AUTH_FAILED,
2793
_("unknown authentication type %s"), authtype);
2796
for (i = 0 ; i < ret.types.types_len ; i++) {
2797
if (ret.types.types_val[i] == want)
2800
if (type == REMOTE_AUTH_NONE) {
2801
remoteError(VIR_ERR_AUTH_FAILED,
2802
_("requested authentication type %s rejected"),
2807
type = ret.types.types_val[0];
2812
case REMOTE_AUTH_SASL: {
2813
const char *mech = NULL;
2815
STRCASEEQLEN(authtype, "sasl.", 5))
2816
mech = authtype + 5;
2818
if (remoteAuthSASL(conn, priv, auth, mech) < 0) {
2819
VIR_FREE(ret.types.types_val);
2827
case REMOTE_AUTH_POLKIT:
2828
if (remoteAuthPolkit(conn, priv, auth) < 0) {
2829
VIR_FREE(ret.types.types_val);
2835
case REMOTE_AUTH_NONE:
2836
/* Nothing todo, hurrah ! */
2840
remoteError(VIR_ERR_AUTH_FAILED,
2841
_("unsupported authentication type %d"),
2842
ret.types.types_val[0]);
2843
VIR_FREE(ret.types.types_val);
2847
VIR_FREE(ret.types.types_val);
2855
static int remoteAuthCredVir2SASL(int vircred)
2858
case VIR_CRED_USERNAME:
2859
return SASL_CB_USER;
2861
case VIR_CRED_AUTHNAME:
2862
return SASL_CB_AUTHNAME;
2864
case VIR_CRED_LANGUAGE:
2865
return SASL_CB_LANGUAGE;
2867
case VIR_CRED_CNONCE:
2868
return SASL_CB_CNONCE;
2870
case VIR_CRED_PASSPHRASE:
2871
return SASL_CB_PASS;
2873
case VIR_CRED_ECHOPROMPT:
2874
return SASL_CB_ECHOPROMPT;
2876
case VIR_CRED_NOECHOPROMPT:
2877
return SASL_CB_NOECHOPROMPT;
2879
case VIR_CRED_REALM:
2880
return SASL_CB_GETREALM;
2886
static int remoteAuthCredSASL2Vir(int vircred)
2890
return VIR_CRED_USERNAME;
2892
case SASL_CB_AUTHNAME:
2893
return VIR_CRED_AUTHNAME;
2895
case SASL_CB_LANGUAGE:
2896
return VIR_CRED_LANGUAGE;
2898
case SASL_CB_CNONCE:
2899
return VIR_CRED_CNONCE;
2902
return VIR_CRED_PASSPHRASE;
2904
case SASL_CB_ECHOPROMPT:
2905
return VIR_CRED_ECHOPROMPT;
2907
case SASL_CB_NOECHOPROMPT:
2908
return VIR_CRED_NOECHOPROMPT;
2910
case SASL_CB_GETREALM:
2911
return VIR_CRED_REALM;
2918
* @param credtype array of credential types client supports
2919
* @param ncredtype size of credtype array
2920
* @return the SASL callback structure, or NULL on error
2922
* Build up the SASL callback structure. We register one callback for
2923
* each credential type that the libvirt client indicated they support.
2924
* We explicitly leav the callback function pointer at NULL though,
2925
* because we don't actually want to get SASL callbacks triggered.
2926
* Instead, we want the start/step functions to return SASL_INTERACT.
2927
* This lets us give the libvirt client a list of all required
2928
* credentials in one go, rather than triggering the callback one
2929
* credential at a time,
2931
static sasl_callback_t *remoteAuthMakeCallbacks(int *credtype, int ncredtype)
2933
sasl_callback_t *cbs;
2935
if (VIR_ALLOC_N(cbs, ncredtype+1) < 0) {
2939
for (i = 0, n = 0 ; i < ncredtype ; i++) {
2940
int id = remoteAuthCredVir2SASL(credtype[i]);
2943
/* Don't fill proc or context fields of sasl_callback_t
2944
* because we want to use interactions instead */
2952
* @param interact SASL interactions required
2953
* @param cred populated with libvirt credential metadata
2954
* @return the size of the cred array returned
2956
* Builds up an array of libvirt credential structs, populating
2957
* with data from the SASL interaction struct. These two structs
2958
* are basically a 1-to-1 copy of each other.
2960
static int remoteAuthMakeCredentials(sasl_interact_t *interact,
2961
virConnectCredentialPtr *cred,
2968
for (ninteract = 0, *ncred = 0 ; interact[ninteract].id != 0 ; ninteract++) {
2969
if (interact[ninteract].result)
2974
if (VIR_ALLOC_N(*cred, *ncred) < 0)
2977
for (ninteract = 0, *ncred = 0 ; interact[ninteract].id != 0 ; ninteract++) {
2978
if (interact[ninteract].result)
2981
(*cred)[*ncred].type = remoteAuthCredSASL2Vir(interact[ninteract].id);
2982
if (!(*cred)[*ncred].type) {
2987
if (interact[*ncred].challenge)
2988
(*cred)[*ncred].challenge = interact[ninteract].challenge;
2989
(*cred)[*ncred].prompt = interact[ninteract].prompt;
2990
if (interact[*ncred].defresult)
2991
(*cred)[*ncred].defresult = interact[ninteract].defresult;
2992
(*cred)[*ncred].result = NULL;
3002
* @param cred the populated libvirt credentials
3003
* @param interact the SASL interactions to fill in results for
3005
* Fills the SASL interactions with the result from the libvirt
3008
static void remoteAuthFillInteract(virConnectCredentialPtr cred,
3009
sasl_interact_t *interact)
3011
int ninteract, ncred;
3012
for (ninteract = 0, ncred = 0 ; interact[ninteract].id != 0 ; ninteract++) {
3013
if (interact[ninteract].result)
3015
interact[ninteract].result = cred[ncred].result;
3016
interact[ninteract].len = cred[ncred].resultlen;
3021
struct remoteAuthInteractState {
3022
sasl_interact_t *interact;
3023
virConnectCredentialPtr cred;
3025
virAuthConfigPtr config;
3030
static int remoteAuthFillFromConfig(virConnectPtr conn,
3031
struct remoteAuthInteractState *state)
3035
const char *credname;
3038
VIR_DEBUG("Trying to fill auth parameters from config file");
3040
if (!state->config) {
3041
if (virAuthGetConfigFilePath(conn, &path) < 0)
3048
if (!(state->config = virAuthConfigNew(path)))
3052
for (ninteract = 0 ; state->interact[ninteract].id != 0 ; ninteract++) {
3053
const char *value = NULL;
3055
switch (state->interact[ninteract].id) {
3057
credname = "username";
3059
case SASL_CB_AUTHNAME:
3060
credname = "authname";
3063
credname = "password";
3065
case SASL_CB_GETREALM:
3073
if (virAuthConfigLookup(state->config,
3081
state->interact[ninteract].result = value;
3082
state->interact[ninteract].len = strlen(value);
3094
static void remoteAuthInteractStateClear(struct remoteAuthInteractState *state,
3101
for (i = 0 ; i < state->ncred ; i++)
3102
VIR_FREE(state->cred[i].result);
3103
VIR_FREE(state->cred);
3107
virAuthConfigFree(state->config);
3111
static int remoteAuthInteract(virConnectPtr conn,
3112
struct remoteAuthInteractState *state,
3113
virConnectAuthPtr auth)
3117
VIR_DEBUG("Starting SASL interaction");
3118
remoteAuthInteractStateClear(state, false);
3120
if (remoteAuthFillFromConfig(conn, state) < 0)
3123
if (remoteAuthMakeCredentials(state->interact, &state->cred, &state->ncred) < 0) {
3124
remoteError(VIR_ERR_AUTH_FAILED, "%s",
3125
_("Failed to make auth credentials"));
3129
/* Run the authentication callback */
3130
if (!auth || !auth->cb) {
3131
remoteError(VIR_ERR_AUTH_FAILED, "%s",
3132
_("No authentication callback available"));
3136
if ((*(auth->cb))(state->cred, state->ncred, auth->cbdata) < 0) {
3137
remoteError(VIR_ERR_AUTH_FAILED, "%s",
3138
_("Failed to collect auth credentials"));
3142
remoteAuthFillInteract(state->cred, state->interact);
3144
* 'interact' now has pointers to strings in 'state->cred'
3145
* so we must not free state->cred until the *next*
3146
* sasl_start/step function is complete. Hence we
3147
* call remoteAuthInteractStateClear() at the *start*
3148
* of this method, rather than the end.
3158
/* Perform the SASL authentication process
3161
remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
3162
virConnectAuthPtr auth, const char *wantmech)
3164
remote_auth_sasl_init_ret iret;
3165
remote_auth_sasl_start_args sargs;
3166
remote_auth_sasl_start_ret sret;
3167
remote_auth_sasl_step_args pargs;
3168
remote_auth_sasl_step_ret pret;
3169
const char *clientout;
3170
char *serverin = NULL;
3171
size_t clientoutlen, serverinlen;
3175
sasl_callback_t *saslcb = NULL;
3177
const char *mechlist;
3178
virNetSASLContextPtr saslCtxt;
3179
virNetSASLSessionPtr sasl = NULL;
3180
struct remoteAuthInteractState state;
3182
memset(&state, 0, sizeof(state));
3184
VIR_DEBUG("Client initialize SASL authentication");
3186
if (!(saslCtxt = virNetSASLContextNewClient()))
3190
if ((saslcb = remoteAuthMakeCallbacks(auth->credtype, auth->ncredtype)) == NULL)
3196
/* Setup a handle for being a client */
3197
if (!(sasl = virNetSASLSessionNewClient(saslCtxt,
3200
virNetClientLocalAddrString(priv->client),
3201
virNetClientRemoteAddrString(priv->client),
3205
/* Initialize some connection props we care about */
3207
if ((ssf = virNetClientGetTLSKeySize(priv->client)) < 0)
3210
ssf *= 8; /* key size is bytes, sasl wants bits */
3212
VIR_DEBUG("Setting external SSF %d", ssf);
3213
if (virNetSASLSessionExtKeySize(sasl, ssf) < 0)
3217
/* If we've got a secure channel (TLS or UNIX sock), we don't care about SSF */
3218
/* If we're not secure, then forbid any anonymous or trivially crackable auth */
3219
if (virNetSASLSessionSecProps(sasl,
3220
priv->is_secure ? 0 : 56, /* Equiv to DES supported by all Kerberos */
3221
priv->is_secure ? 0 : 100000, /* Very strong ! AES == 256 */
3222
priv->is_secure ? true : false) < 0)
3225
/* First call is to inquire about supported mechanisms in the server */
3226
memset (&iret, 0, sizeof(iret));
3227
if (call (conn, priv, 0, REMOTE_PROC_AUTH_SASL_INIT,
3228
(xdrproc_t) xdr_void, (char *)NULL,
3229
(xdrproc_t) xdr_remote_auth_sasl_init_ret, (char *) &iret) != 0)
3233
mechlist = iret.mechlist;
3235
if (strstr(mechlist, wantmech) == NULL) {
3236
remoteError(VIR_ERR_AUTH_FAILED,
3237
_("SASL mechanism %s not supported by server"),
3239
VIR_FREE(iret.mechlist);
3242
mechlist = wantmech;
3245
/* Start the auth negotiation on the client end first */
3246
VIR_DEBUG("Client start negotiation mechlist '%s'", mechlist);
3247
if ((err = virNetSASLSessionClientStart(sasl,
3255
/* Need to gather some credentials from the client */
3256
if (err == VIR_NET_SASL_INTERACT) {
3257
if (remoteAuthInteract(conn, &state, auth) < 0) {
3258
VIR_FREE(iret.mechlist);
3263
VIR_FREE(iret.mechlist);
3265
if (clientoutlen > REMOTE_AUTH_SASL_DATA_MAX) {
3266
remoteError(VIR_ERR_AUTH_FAILED,
3267
_("SASL negotiation data too long: %zu bytes"),
3271
/* NB, distinction of NULL vs "" is *critical* in SASL */
3272
memset(&sargs, 0, sizeof(sargs));
3273
sargs.nil = clientout ? 0 : 1;
3274
sargs.data.data_val = (char*)clientout;
3275
sargs.data.data_len = clientoutlen;
3276
sargs.mech = (char*)mech;
3277
VIR_DEBUG("Server start negotiation with mech %s. Data %zu bytes %p",
3278
mech, clientoutlen, clientout);
3280
/* Now send the initial auth data to the server */
3281
memset (&sret, 0, sizeof(sret));
3282
if (call (conn, priv, 0, REMOTE_PROC_AUTH_SASL_START,
3283
(xdrproc_t) xdr_remote_auth_sasl_start_args, (char *) &sargs,
3284
(xdrproc_t) xdr_remote_auth_sasl_start_ret, (char *) &sret) != 0)
3287
complete = sret.complete;
3288
/* NB, distinction of NULL vs "" is *critical* in SASL */
3289
serverin = sret.nil ? NULL : sret.data.data_val;
3290
serverinlen = sret.data.data_len;
3291
VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
3292
complete, serverinlen, serverin);
3295
* Even if the server has completed, the client must *always* do at least one step
3296
* in this loop to verify the server isn't lying about something. Mutual auth */
3299
if ((err = virNetSASLSessionClientStep(sasl,
3304
&clientoutlen)) < 0)
3307
/* Need to gather some credentials from the client */
3308
if (err == VIR_NET_SASL_INTERACT) {
3309
if (remoteAuthInteract(conn, &state, auth) < 0) {
3310
VIR_FREE(iret.mechlist);
3317
VIR_DEBUG("Client step result %d. Data %zu bytes %p",
3318
err, clientoutlen, clientout);
3320
/* Previous server call showed completion & we're now locally complete too */
3321
if (complete && err == VIR_NET_SASL_COMPLETE)
3324
/* Not done, prepare to talk with the server for another iteration */
3325
/* NB, distinction of NULL vs "" is *critical* in SASL */
3326
memset(&pargs, 0, sizeof(pargs));
3327
pargs.nil = clientout ? 0 : 1;
3328
pargs.data.data_val = (char*)clientout;
3329
pargs.data.data_len = clientoutlen;
3330
VIR_DEBUG("Server step with %zu bytes %p",
3331
clientoutlen, clientout);
3333
memset (&pret, 0, sizeof(pret));
3334
if (call (conn, priv, 0, REMOTE_PROC_AUTH_SASL_STEP,
3335
(xdrproc_t) xdr_remote_auth_sasl_step_args, (char *) &pargs,
3336
(xdrproc_t) xdr_remote_auth_sasl_step_ret, (char *) &pret) != 0)
3339
complete = pret.complete;
3340
/* NB, distinction of NULL vs "" is *critical* in SASL */
3341
serverin = pret.nil ? NULL : pret.data.data_val;
3342
serverinlen = pret.data.data_len;
3344
VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
3345
complete, serverinlen, serverin);
3347
/* This server call shows complete, and earlier client step was OK */
3348
if (complete && err == VIR_NET_SASL_COMPLETE) {
3354
/* Check for suitable SSF if not already secure (TLS or UNIX sock) */
3355
if (!priv->is_secure) {
3356
if ((ssf = virNetSASLSessionGetKeySize(sasl)) < 0)
3359
VIR_DEBUG("SASL SSF value %d", ssf);
3360
if (ssf < 56) { /* 56 == DES level, good for Kerberos */
3361
remoteError(VIR_ERR_AUTH_FAILED,
3362
_("negotiation SSF %d was not strong enough"), ssf);
3365
priv->is_secure = 1;
3368
VIR_DEBUG("SASL authentication complete");
3369
virNetClientSetSASLSession(priv->client, sasl);
3375
remoteAuthInteractStateClear(&state, true);
3377
virNetSASLSessionFree(sasl);
3378
virNetSASLContextFree(saslCtxt);
3382
#endif /* HAVE_SASL */
3388
remoteAuthPolkit (virConnectPtr conn, struct private_data *priv,
3389
virConnectAuthPtr auth ATTRIBUTE_UNUSED)
3391
remote_auth_polkit_ret ret;
3392
VIR_DEBUG("Client initialize PolicyKit-1 authentication");
3394
memset (&ret, 0, sizeof(ret));
3395
if (call (conn, priv, 0, REMOTE_PROC_AUTH_POLKIT,
3396
(xdrproc_t) xdr_void, (char *)NULL,
3397
(xdrproc_t) xdr_remote_auth_polkit_ret, (char *) &ret) != 0) {
3398
return -1; /* virError already set by call */
3401
VIR_DEBUG("PolicyKit-1 authentication complete");
3405
/* Perform the PolicyKit authentication process
3408
remoteAuthPolkit (virConnectPtr conn, struct private_data *priv,
3409
virConnectAuthPtr auth)
3411
remote_auth_polkit_ret ret;
3413
virConnectCredential cred = {
3415
conn->flags & VIR_CONNECT_RO ? "org.libvirt.unix.monitor" : "org.libvirt.unix.manage",
3421
VIR_DEBUG("Client initialize PolicyKit-0 authentication");
3423
/* Check auth first and if it succeeds we are done. */
3424
memset (&ret, 0, sizeof(ret));
3425
if (call (conn, priv, 0, REMOTE_PROC_AUTH_POLKIT,
3426
(xdrproc_t) xdr_void, (char *)NULL,
3427
(xdrproc_t) xdr_remote_auth_polkit_ret, (char *) &ret) == 0)
3430
/* Auth failed. Ask client to obtain it and check again. */
3431
if (auth && auth->cb) {
3432
/* Check if the necessary credential type for PolicyKit is supported */
3433
for (i = 0 ; i < auth->ncredtype ; i++) {
3434
if (auth->credtype[i] == VIR_CRED_EXTERNAL)
3439
VIR_DEBUG("Client run callback for PolicyKit authentication");
3440
/* Run the authentication callback */
3441
if ((*(auth->cb))(&cred, 1, auth->cbdata) < 0) {
3442
remoteError(VIR_ERR_AUTH_FAILED, "%s",
3443
_("Failed to collect auth credentials"));
3447
VIR_DEBUG("Client auth callback does not support PolicyKit");
3451
VIR_DEBUG("No auth callback provided");
3455
memset (&ret, 0, sizeof(ret));
3456
if (call (conn, priv, 0, REMOTE_PROC_AUTH_POLKIT,
3457
(xdrproc_t) xdr_void, (char *)NULL,
3458
(xdrproc_t) xdr_remote_auth_polkit_ret, (char *) &ret) != 0) {
3459
return -1; /* virError already set by call */
3463
VIR_DEBUG("PolicyKit-0 authentication complete");
3466
# endif /* HAVE_POLKIT0 */
3467
#endif /* HAVE_POLKIT */
3468
/*----------------------------------------------------------------------*/
3470
static int remoteDomainEventRegister(virConnectPtr conn,
3471
virConnectDomainEventCallback callback,
3473
virFreeCallback freecb)
3476
struct private_data *priv = conn->privateData;
3479
remoteDriverLock(priv);
3481
if ((count = virDomainEventStateRegister(conn, priv->domainEventState,
3482
callback, opaque, freecb)) < 0) {
3483
remoteError(VIR_ERR_RPC, "%s", _("adding cb to list"));
3488
/* Tell the server when we are the first callback deregistering */
3489
if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_REGISTER,
3490
(xdrproc_t) xdr_void, (char *) NULL,
3491
(xdrproc_t) xdr_void, (char *) NULL) == -1)
3498
remoteDriverUnlock(priv);
3502
static int remoteDomainEventDeregister(virConnectPtr conn,
3503
virConnectDomainEventCallback callback)
3505
struct private_data *priv = conn->privateData;
3509
remoteDriverLock(priv);
3511
if ((count = virDomainEventStateDeregister(conn,
3512
priv->domainEventState,
3517
/* Tell the server when we are the last callback deregistering */
3518
if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER,
3519
(xdrproc_t) xdr_void, (char *) NULL,
3520
(xdrproc_t) xdr_void, (char *) NULL) == -1)
3527
remoteDriverUnlock(priv);
3533
remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3534
virNetClientPtr client ATTRIBUTE_UNUSED,
3535
void *evdata, void *opaque)
3537
virConnectPtr conn = opaque;
3538
struct private_data *priv = conn->privateData;
3539
remote_domain_event_lifecycle_msg *msg = evdata;
3541
virDomainEventPtr event = NULL;
3543
dom = get_nonnull_domain(conn, msg->dom);
3547
event = virDomainEventNewFromDom(dom, msg->event, msg->detail);
3550
remoteDomainEventQueue(priv, event);
3555
remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3556
virNetClientPtr client ATTRIBUTE_UNUSED,
3557
void *evdata, void *opaque)
3559
virConnectPtr conn = opaque;
3560
struct private_data *priv = conn->privateData;
3561
remote_domain_event_reboot_msg *msg = evdata;
3563
virDomainEventPtr event = NULL;
3565
dom = get_nonnull_domain(conn, msg->dom);
3569
event = virDomainEventRebootNewFromDom(dom);
3572
remoteDomainEventQueue(priv, event);
3577
remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3578
virNetClientPtr client ATTRIBUTE_UNUSED,
3579
void *evdata, void *opaque)
3581
virConnectPtr conn = opaque;
3582
struct private_data *priv = conn->privateData;
3583
remote_domain_event_rtc_change_msg *msg = evdata;
3585
virDomainEventPtr event = NULL;
3587
dom = get_nonnull_domain(conn, msg->dom);
3591
event = virDomainEventRTCChangeNewFromDom(dom, msg->offset);
3594
remoteDomainEventQueue(priv, event);
3599
remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3600
virNetClientPtr client ATTRIBUTE_UNUSED,
3601
void *evdata, void *opaque)
3603
virConnectPtr conn = opaque;
3604
struct private_data *priv = conn->privateData;
3605
remote_domain_event_watchdog_msg *msg = evdata;
3607
virDomainEventPtr event = NULL;
3609
dom = get_nonnull_domain(conn, msg->dom);
3613
event = virDomainEventWatchdogNewFromDom(dom, msg->action);
3616
remoteDomainEventQueue(priv, event);
3621
remoteDomainBuildEventIOError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3622
virNetClientPtr client ATTRIBUTE_UNUSED,
3623
void *evdata, void *opaque)
3625
virConnectPtr conn = opaque;
3626
struct private_data *priv = conn->privateData;
3627
remote_domain_event_io_error_msg *msg = evdata;
3629
virDomainEventPtr event = NULL;
3631
dom = get_nonnull_domain(conn, msg->dom);
3635
event = virDomainEventIOErrorNewFromDom(dom,
3641
remoteDomainEventQueue(priv, event);
3646
remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3647
virNetClientPtr client ATTRIBUTE_UNUSED,
3648
void *evdata, void *opaque)
3650
virConnectPtr conn = opaque;
3651
struct private_data *priv = conn->privateData;
3652
remote_domain_event_io_error_reason_msg *msg = evdata;
3654
virDomainEventPtr event = NULL;
3656
dom = get_nonnull_domain(conn,msg->dom);
3660
event = virDomainEventIOErrorReasonNewFromDom(dom,
3668
remoteDomainEventQueue(priv, event);
3672
remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3673
virNetClientPtr client ATTRIBUTE_UNUSED,
3674
void *evdata, void *opaque)
3676
virConnectPtr conn = opaque;
3677
struct private_data *priv = conn->privateData;
3678
remote_domain_event_block_job_msg *msg = evdata;
3680
virDomainEventPtr event = NULL;
3682
dom = get_nonnull_domain(conn, msg->dom);
3686
event = virDomainEventBlockJobNewFromDom(dom, msg->path, msg->type,
3691
remoteDomainEventQueue(priv, event);
3695
remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3696
virNetClientPtr client ATTRIBUTE_UNUSED,
3697
void *evdata, void *opaque)
3699
virConnectPtr conn = opaque;
3700
struct private_data *priv = conn->privateData;
3701
remote_domain_event_graphics_msg *msg = evdata;
3703
virDomainEventPtr event = NULL;
3704
virDomainEventGraphicsAddressPtr localAddr = NULL;
3705
virDomainEventGraphicsAddressPtr remoteAddr = NULL;
3706
virDomainEventGraphicsSubjectPtr subject = NULL;
3709
dom = get_nonnull_domain(conn, msg->dom);
3713
if (VIR_ALLOC(localAddr) < 0)
3715
localAddr->family = msg->local.family;
3716
if (!(localAddr->service = strdup(msg->local.service)) ||
3717
!(localAddr->node = strdup(msg->local.node)))
3720
if (VIR_ALLOC(remoteAddr) < 0)
3722
remoteAddr->family = msg->remote.family;
3723
if (!(remoteAddr->service = strdup(msg->remote.service)) ||
3724
!(remoteAddr->node = strdup(msg->remote.node)))
3727
if (VIR_ALLOC(subject) < 0)
3729
if (VIR_ALLOC_N(subject->identities, msg->subject.subject_len) < 0)
3731
subject->nidentity = msg->subject.subject_len;
3732
for (i = 0 ; i < subject->nidentity ; i++) {
3733
if (!(subject->identities[i].type = strdup(msg->subject.subject_val[i].type)) ||
3734
!(subject->identities[i].name = strdup(msg->subject.subject_val[i].name)))
3738
event = virDomainEventGraphicsNewFromDom(dom,
3747
remoteDomainEventQueue(priv, event);
3752
VIR_FREE(localAddr->service);
3753
VIR_FREE(localAddr->node);
3754
VIR_FREE(localAddr);
3757
VIR_FREE(remoteAddr->service);
3758
VIR_FREE(remoteAddr->node);
3759
VIR_FREE(remoteAddr);
3762
for (i = 0 ; i < subject->nidentity ; i++) {
3763
VIR_FREE(subject->identities[i].type);
3764
VIR_FREE(subject->identities[i].name);
3766
VIR_FREE(subject->identities);
3775
remoteDomainBuildEventControlError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3776
virNetClientPtr client ATTRIBUTE_UNUSED,
3777
void *evdata, void *opaque)
3779
virConnectPtr conn = opaque;
3780
struct private_data *priv = conn->privateData;
3781
remote_domain_event_control_error_msg *msg = evdata;
3783
virDomainEventPtr event = NULL;
3785
dom = get_nonnull_domain(conn, msg->dom);
3789
event = virDomainEventControlErrorNewFromDom(dom);
3793
remoteDomainEventQueue(priv, event);
3798
remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3799
virNetClientPtr client ATTRIBUTE_UNUSED,
3800
void *evdata, void *opaque)
3802
virConnectPtr conn = opaque;
3803
struct private_data *priv = conn->privateData;
3804
remote_domain_event_disk_change_msg *msg = evdata;
3806
virDomainEventPtr event = NULL;
3808
dom = get_nonnull_domain(conn, msg->dom);
3812
event = virDomainEventDiskChangeNewFromDom(dom,
3813
msg->oldSrcPath ? *msg->oldSrcPath : NULL,
3814
msg->newSrcPath ? *msg->newSrcPath : NULL,
3820
remoteDomainEventQueue(priv, event);
3825
remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3826
virNetClientPtr client ATTRIBUTE_UNUSED,
3827
void *evdata, void *opaque)
3829
virConnectPtr conn = opaque;
3830
struct private_data *priv = conn->privateData;
3831
remote_domain_event_tray_change_msg *msg = evdata;
3833
virDomainEventPtr event = NULL;
3835
dom = get_nonnull_domain(conn, msg->dom);
3839
event = virDomainEventTrayChangeNewFromDom(dom,
3845
remoteDomainEventQueue(priv, event);
3849
remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3850
virNetClientPtr client ATTRIBUTE_UNUSED,
3851
void *evdata, void *opaque)
3853
virConnectPtr conn = opaque;
3854
struct private_data *priv = conn->privateData;
3855
remote_domain_event_pmwakeup_msg *msg = evdata;
3857
virDomainEventPtr event = NULL;
3859
dom = get_nonnull_domain(conn, msg->dom);
3863
event = virDomainEventPMWakeupNewFromDom(dom);
3867
remoteDomainEventQueue(priv, event);
3871
remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
3872
virNetClientPtr client ATTRIBUTE_UNUSED,
3873
void *evdata, void *opaque)
3875
virConnectPtr conn = opaque;
3876
struct private_data *priv = conn->privateData;
3877
remote_domain_event_pmsuspend_msg *msg = evdata;
3879
virDomainEventPtr event = NULL;
3881
dom = get_nonnull_domain(conn, msg->dom);
3885
event = virDomainEventPMSuspendNewFromDom(dom);
3889
remoteDomainEventQueue(priv, event);
3892
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
3893
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
3896
return remoteGenericOpen(conn, auth, flags, &conn->secretPrivateData);
3900
remoteSecretClose (virConnectPtr conn)
3902
return remoteGenericClose(conn, &conn->secretPrivateData);
3905
static unsigned char *
3906
remoteSecretGetValue (virSecretPtr secret, size_t *value_size,
3907
unsigned int flags, unsigned int internalFlags)
3909
unsigned char *rv = NULL;
3910
remote_secret_get_value_args args;
3911
remote_secret_get_value_ret ret;
3912
struct private_data *priv = secret->conn->secretPrivateData;
3914
remoteDriverLock (priv);
3916
/* internalFlags intentionally do not go over the wire */
3917
if (internalFlags) {
3918
remoteError(VIR_ERR_INTERNAL_ERROR, "%s", _("no internalFlags support"));
3922
make_nonnull_secret (&args.secret, secret);
3925
memset (&ret, 0, sizeof(ret));
3926
if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_VALUE,
3927
(xdrproc_t) xdr_remote_secret_get_value_args, (char *) &args,
3928
(xdrproc_t) xdr_remote_secret_get_value_ret, (char *) &ret) == -1)
3931
*value_size = ret.value.value_len;
3932
rv = (unsigned char *) ret.value.value_val; /* Caller frees. */
3935
remoteDriverUnlock (priv);
3941
remoteStreamSend(virStreamPtr st,
3945
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
3946
struct private_data *priv = st->conn->privateData;
3947
virNetClientStreamPtr privst = st->privateData;
3950
remoteDriverLock(priv);
3952
if (virNetClientStreamRaiseError(privst))
3955
rv = virNetClientStreamSendPacket(privst,
3962
remoteDriverUnlock(priv);
3969
remoteStreamRecv(virStreamPtr st,
3973
VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
3974
struct private_data *priv = st->conn->privateData;
3975
virNetClientStreamPtr privst = st->privateData;
3978
remoteDriverLock(priv);
3980
if (virNetClientStreamRaiseError(privst))
3983
rv = virNetClientStreamRecvPacket(privst,
3987
(st->flags & VIR_STREAM_NONBLOCK));
3989
VIR_DEBUG("Done %d", rv);
3992
remoteDriverUnlock(priv);
3997
struct remoteStreamCallbackData {
3999
virStreamEventCallback cb;
4004
static void remoteStreamEventCallback(virNetClientStreamPtr stream ATTRIBUTE_UNUSED,
4008
struct remoteStreamCallbackData *cbdata = opaque;
4010
(cbdata->cb)(cbdata->st, events, cbdata->opaque);
4014
static void remoteStreamCallbackFree(void *opaque)
4016
struct remoteStreamCallbackData *cbdata = opaque;
4018
if (!cbdata->cb && cbdata->ff)
4019
(cbdata->ff)(cbdata->opaque);
4021
virStreamFree(cbdata->st);
4027
remoteStreamEventAddCallback(virStreamPtr st,
4029
virStreamEventCallback cb,
4033
struct private_data *priv = st->conn->privateData;
4034
virNetClientStreamPtr privst = st->privateData;
4036
struct remoteStreamCallbackData *cbdata;
4038
if (VIR_ALLOC(cbdata) < 0) {
4039
virReportOOMError();
4043
cbdata->opaque = opaque;
4048
remoteDriverLock(priv);
4050
if ((ret = virNetClientStreamEventAddCallback(privst,
4052
remoteStreamEventCallback,
4054
remoteStreamCallbackFree)) < 0) {
4060
remoteDriverUnlock(priv);
4066
remoteStreamEventUpdateCallback(virStreamPtr st,
4069
struct private_data *priv = st->conn->privateData;
4070
virNetClientStreamPtr privst = st->privateData;
4073
remoteDriverLock(priv);
4075
ret = virNetClientStreamEventUpdateCallback(privst, events);
4077
remoteDriverUnlock(priv);
4083
remoteStreamEventRemoveCallback(virStreamPtr st)
4085
struct private_data *priv = st->conn->privateData;
4086
virNetClientStreamPtr privst = st->privateData;
4089
remoteDriverLock(priv);
4091
ret = virNetClientStreamEventRemoveCallback(privst);
4093
remoteDriverUnlock(priv);
4099
remoteStreamFinish(virStreamPtr st)
4101
struct private_data *priv = st->conn->privateData;
4102
virNetClientStreamPtr privst = st->privateData;
4105
remoteDriverLock(priv);
4107
if (virNetClientStreamRaiseError(privst))
4110
ret = virNetClientStreamSendPacket(privst,
4117
virNetClientRemoveStream(priv->client, privst);
4118
virNetClientStreamFree(privst);
4119
st->privateData = NULL;
4122
remoteDriverUnlock(priv);
4128
remoteStreamAbort(virStreamPtr st)
4130
struct private_data *priv = st->conn->privateData;
4131
virNetClientStreamPtr privst = st->privateData;
4134
remoteDriverLock(priv);
4136
if (virNetClientStreamRaiseError(privst))
4139
ret = virNetClientStreamSendPacket(privst,
4146
virNetClientRemoveStream(priv->client, privst);
4147
virNetClientStreamFree(privst);
4148
st->privateData = NULL;
4151
remoteDriverUnlock(priv);
4156
static virStreamDriver remoteStreamDrv = {
4157
.streamRecv = remoteStreamRecv,
4158
.streamSend = remoteStreamSend,
4159
.streamFinish = remoteStreamFinish,
4160
.streamAbort = remoteStreamAbort,
4161
.streamAddCallback = remoteStreamEventAddCallback,
4162
.streamUpdateCallback = remoteStreamEventUpdateCallback,
4163
.streamRemoveCallback = remoteStreamEventRemoveCallback,
4167
static int remoteDomainEventRegisterAny(virConnectPtr conn,
4170
virConnectDomainEventGenericCallback callback,
4172
virFreeCallback freecb)
4175
struct private_data *priv = conn->privateData;
4176
remote_domain_events_register_any_args args;
4180
remoteDriverLock(priv);
4182
if ((count = virDomainEventStateRegisterID(conn,
4183
priv->domainEventState,
4185
callback, opaque, freecb,
4186
&callbackID)) < 0) {
4187
remoteError(VIR_ERR_RPC, "%s", _("adding cb to list"));
4191
/* If this is the first callback for this eventID, we need to enable
4192
* events on the server */
4194
args.eventID = eventID;
4196
if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_REGISTER_ANY,
4197
(xdrproc_t) xdr_remote_domain_events_register_any_args, (char *) &args,
4198
(xdrproc_t) xdr_void, (char *)NULL) == -1) {
4199
virDomainEventStateDeregisterID(conn,
4200
priv->domainEventState,
4209
remoteDriverUnlock(priv);
4214
static int remoteDomainEventDeregisterAny(virConnectPtr conn,
4217
struct private_data *priv = conn->privateData;
4219
remote_domain_events_deregister_any_args args;
4223
remoteDriverLock(priv);
4225
if ((eventID = virDomainEventStateEventID(conn,
4226
priv->domainEventState,
4228
remoteError(VIR_ERR_RPC, _("unable to find callback ID %d"), callbackID);
4232
if ((count = virDomainEventStateDeregisterID(conn,
4233
priv->domainEventState,
4235
remoteError(VIR_ERR_RPC, _("unable to find callback ID %d"), callbackID);
4239
/* If that was the last callback for this eventID, we need to disable
4240
* events on the server */
4242
args.eventID = callbackID;
4244
if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER_ANY,
4245
(xdrproc_t) xdr_remote_domain_events_deregister_any_args, (char *) &args,
4246
(xdrproc_t) xdr_void, (char *) NULL) == -1)
4253
remoteDriverUnlock(priv);
4258
/*----------------------------------------------------------------------*/
4261
remoteQemuDomainMonitorCommand (virDomainPtr domain, const char *cmd,
4262
char **result, unsigned int flags)
4265
qemu_monitor_command_args args;
4266
qemu_monitor_command_ret ret;
4267
struct private_data *priv = domain->conn->privateData;
4269
remoteDriverLock(priv);
4271
make_nonnull_domain(&args.dom, domain);
4272
args.cmd = (char *)cmd;
4275
memset (&ret, 0, sizeof(ret));
4276
if (call (domain->conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_MONITOR_COMMAND,
4277
(xdrproc_t) xdr_qemu_monitor_command_args, (char *) &args,
4278
(xdrproc_t) xdr_qemu_monitor_command_ret, (char *) &ret) == -1)
4281
*result = strdup(ret.result);
4282
if (*result == NULL) {
4283
virReportOOMError();
4290
xdr_free ((xdrproc_t) xdr_qemu_monitor_command_ret, (char *) &ret);
4293
remoteDriverUnlock(priv);
4299
remoteDomainMigrateBegin3(virDomainPtr domain,
4303
unsigned long flags,
4305
unsigned long resource)
4308
remote_domain_migrate_begin3_args args;
4309
remote_domain_migrate_begin3_ret ret;
4310
struct private_data *priv = domain->conn->privateData;
4312
remoteDriverLock(priv);
4314
memset(&args, 0, sizeof(args));
4315
memset(&ret, 0, sizeof(ret));
4317
make_nonnull_domain (&args.dom, domain);
4318
args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
4320
args.dname = dname == NULL ? NULL : (char **) &dname;
4321
args.resource = resource;
4323
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3,
4324
(xdrproc_t) xdr_remote_domain_migrate_begin3_args, (char *) &args,
4325
(xdrproc_t) xdr_remote_domain_migrate_begin3_ret, (char *) &ret) == -1)
4328
if (ret.cookie_out.cookie_out_len > 0) {
4329
if (!cookieout || !cookieoutlen) {
4330
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4331
_("caller ignores cookieout or cookieoutlen"));
4334
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
4335
*cookieoutlen = ret.cookie_out.cookie_out_len;
4338
rv = ret.xml; /* caller frees */
4341
remoteDriverUnlock(priv);
4345
VIR_FREE(ret.cookie_out.cookie_out_val);
4351
remoteDomainMigratePrepare3(virConnectPtr dconn,
4352
const char *cookiein,
4358
unsigned long flags,
4360
unsigned long resource,
4361
const char *dom_xml)
4364
remote_domain_migrate_prepare3_args args;
4365
remote_domain_migrate_prepare3_ret ret;
4366
struct private_data *priv = dconn->privateData;
4368
remoteDriverLock(priv);
4370
memset(&args, 0, sizeof(args));
4371
memset(&ret, 0, sizeof(ret));
4373
args.cookie_in.cookie_in_val = (char *)cookiein;
4374
args.cookie_in.cookie_in_len = cookieinlen;
4375
args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
4377
args.dname = dname == NULL ? NULL : (char **) &dname;
4378
args.resource = resource;
4379
args.dom_xml = (char *) dom_xml;
4381
memset (&ret, 0, sizeof(ret));
4382
if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3,
4383
(xdrproc_t) xdr_remote_domain_migrate_prepare3_args, (char *) &args,
4384
(xdrproc_t) xdr_remote_domain_migrate_prepare3_ret, (char *) &ret) == -1)
4387
if (ret.cookie_out.cookie_out_len > 0) {
4388
if (!cookieout || !cookieoutlen) {
4389
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4390
_("caller ignores cookieout or cookieoutlen"));
4393
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
4394
*cookieoutlen = ret.cookie_out.cookie_out_len;
4398
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4399
_("caller ignores uri_out"));
4402
*uri_out = *ret.uri_out; /* Caller frees. */
4408
VIR_FREE(ret.uri_out);
4409
remoteDriverUnlock(priv);
4412
VIR_FREE(ret.cookie_out.cookie_out_val);
4414
VIR_FREE(*ret.uri_out);
4420
remoteDomainMigratePrepareTunnel3(virConnectPtr dconn,
4422
const char *cookiein,
4426
unsigned long flags,
4428
unsigned long resource,
4429
const char *dom_xml)
4431
struct private_data *priv = dconn->privateData;
4433
remote_domain_migrate_prepare_tunnel3_args args;
4434
remote_domain_migrate_prepare_tunnel3_ret ret;
4435
virNetClientStreamPtr netst;
4437
remoteDriverLock(priv);
4439
memset(&args, 0, sizeof(args));
4440
memset(&ret, 0, sizeof(ret));
4442
if (!(netst = virNetClientStreamNew(priv->remoteProgram,
4443
REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
4447
if (virNetClientAddStream(priv->client, netst) < 0) {
4448
virNetClientStreamFree(netst);
4452
st->driver = &remoteStreamDrv;
4453
st->privateData = netst;
4455
args.cookie_in.cookie_in_val = (char *)cookiein;
4456
args.cookie_in.cookie_in_len = cookieinlen;
4458
args.dname = dname == NULL ? NULL : (char **) &dname;
4459
args.resource = resource;
4460
args.dom_xml = (char *) dom_xml;
4462
if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
4463
(xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_args, (char *) &args,
4464
(xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_ret, (char *) &ret) == -1) {
4465
virNetClientRemoveStream(priv->client, netst);
4466
virNetClientStreamFree(netst);
4470
if (ret.cookie_out.cookie_out_len > 0) {
4471
if (!cookieout || !cookieoutlen) {
4472
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4473
_("caller ignores cookieout or cookieoutlen"));
4476
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
4477
*cookieoutlen = ret.cookie_out.cookie_out_len;
4483
remoteDriverUnlock(priv);
4487
VIR_FREE(ret.cookie_out.cookie_out_val);
4493
remoteDomainMigratePerform3(virDomainPtr dom,
4495
const char *cookiein,
4499
const char *dconnuri,
4501
unsigned long flags,
4503
unsigned long resource)
4506
remote_domain_migrate_perform3_args args;
4507
remote_domain_migrate_perform3_ret ret;
4508
struct private_data *priv = dom->conn->privateData;
4510
remoteDriverLock(priv);
4512
memset(&args, 0, sizeof(args));
4513
memset(&ret, 0, sizeof(ret));
4515
make_nonnull_domain(&args.dom, dom);
4517
args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
4518
args.cookie_in.cookie_in_val = (char *)cookiein;
4519
args.cookie_in.cookie_in_len = cookieinlen;
4521
args.dname = dname == NULL ? NULL : (char **) &dname;
4522
args.uri = uri == NULL ? NULL : (char **) &uri;
4523
args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
4524
args.resource = resource;
4526
if (call (dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3,
4527
(xdrproc_t) xdr_remote_domain_migrate_perform3_args, (char *) &args,
4528
(xdrproc_t) xdr_remote_domain_migrate_perform3_ret, (char *) &ret) == -1)
4531
if (ret.cookie_out.cookie_out_len > 0) {
4532
if (!cookieout || !cookieoutlen) {
4533
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4534
_("caller ignores cookieout or cookieoutlen"));
4537
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
4538
*cookieoutlen = ret.cookie_out.cookie_out_len;
4544
remoteDriverUnlock(priv);
4548
VIR_FREE(ret.cookie_out.cookie_out_val);
4554
remoteDomainMigrateFinish3(virConnectPtr dconn,
4556
const char *cookiein,
4560
const char *dconnuri,
4562
unsigned long flags,
4565
remote_domain_migrate_finish3_args args;
4566
remote_domain_migrate_finish3_ret ret;
4567
struct private_data *priv = dconn->privateData;
4568
virDomainPtr rv = NULL;
4570
remoteDriverLock(priv);
4572
memset(&args, 0, sizeof(args));
4573
memset(&ret, 0, sizeof(ret));
4575
args.cookie_in.cookie_in_val = (char *)cookiein;
4576
args.cookie_in.cookie_in_len = cookieinlen;
4577
args.dname = (char *) dname;
4578
args.uri = uri == NULL ? NULL : (char **) &uri;
4579
args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
4581
args.cancelled = cancelled;
4583
if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH3,
4584
(xdrproc_t) xdr_remote_domain_migrate_finish3_args, (char *) &args,
4585
(xdrproc_t) xdr_remote_domain_migrate_finish3_ret, (char *) &ret) == -1)
4588
rv = get_nonnull_domain(dconn, ret.dom);
4590
if (ret.cookie_out.cookie_out_len > 0) {
4591
if (!cookieout || !cookieoutlen) {
4592
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4593
_("caller ignores cookieout or cookieoutlen"));
4596
*cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
4597
*cookieoutlen = ret.cookie_out.cookie_out_len;
4598
ret.cookie_out.cookie_out_val = NULL;
4599
ret.cookie_out.cookie_out_len = 0;
4602
xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish3_ret, (char *) &ret);
4605
remoteDriverUnlock(priv);
4609
VIR_FREE(ret.cookie_out.cookie_out_val);
4615
remoteDomainMigrateConfirm3(virDomainPtr domain,
4616
const char *cookiein,
4618
unsigned long flags,
4622
remote_domain_migrate_confirm3_args args;
4623
struct private_data *priv = domain->conn->privateData;
4625
remoteDriverLock(priv);
4627
memset(&args, 0, sizeof(args));
4629
make_nonnull_domain (&args.dom, domain);
4630
args.cookie_in.cookie_in_len = cookieinlen;
4631
args.cookie_in.cookie_in_val = (char *) cookiein;
4633
args.cancelled = cancelled;
4635
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3,
4636
(xdrproc_t) xdr_remote_domain_migrate_confirm3_args, (char *) &args,
4637
(xdrproc_t) xdr_void, (char *) NULL) == -1)
4643
remoteDriverUnlock(priv);
4649
remoteDomainOpenGraphics(virDomainPtr dom,
4655
remote_domain_open_graphics_args args;
4656
struct private_data *priv = dom->conn->privateData;
4658
remoteDriverLock(priv);
4660
make_nonnull_domain (&args.dom, dom);
4664
if (callWithFD(dom->conn, priv, 0, fd, REMOTE_PROC_DOMAIN_OPEN_GRAPHICS,
4665
(xdrproc_t) xdr_remote_domain_open_graphics_args, (char *) &args,
4666
(xdrproc_t) xdr_void, NULL) == -1)
4672
remoteDriverUnlock(priv);
4679
remoteSetKeepAlive(virConnectPtr conn, int interval, unsigned int count)
4681
struct private_data *priv = conn->privateData;
4684
remoteDriverLock(priv);
4685
if (!virNetClientKeepAliveIsSupported(priv->client)) {
4686
remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
4687
_("the caller doesn't support keepalive protocol;"
4688
" perhaps it's missing event loop implementation"));
4692
if (!priv->serverKeepAlive) {
4698
ret = virNetClientKeepAliveStart(priv->client, interval, count);
4700
virNetClientKeepAliveStop(priv->client);
4705
remoteDriverUnlock(priv);
4711
remoteIsAlive(virConnectPtr conn)
4713
struct private_data *priv = conn->privateData;
4716
remoteDriverLock(priv);
4717
ret = virNetClientIsOpen(priv->client);
4718
remoteDriverUnlock(priv);
4728
remoteDomainGetDiskErrors(virDomainPtr dom,
4729
virDomainDiskErrorPtr errors,
4730
unsigned int maxerrors,
4734
struct private_data *priv = dom->conn->privateData;
4735
remote_domain_get_disk_errors_args args;
4736
remote_domain_get_disk_errors_ret ret;
4738
remoteDriverLock(priv);
4740
make_nonnull_domain(&args.dom, dom);
4741
args.maxerrors = maxerrors;
4744
memset(&ret, 0, sizeof(ret));
4746
if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_DISK_ERRORS,
4747
(xdrproc_t) xdr_remote_domain_get_disk_errors_args,
4749
(xdrproc_t) xdr_remote_domain_get_disk_errors_ret,
4750
(char *) &ret) == -1)
4753
if (remoteDeserializeDomainDiskErrors(ret.errors.errors_val,
4754
ret.errors.errors_len,
4755
REMOTE_DOMAIN_DISK_ERRORS_MAX,
4763
xdr_free((xdrproc_t) xdr_remote_domain_get_disk_errors_ret, (char *) &ret);
4766
remoteDriverUnlock(priv);
4770
#include "remote_client_bodies.h"
4771
#include "qemu_client_bodies.h"
4774
* Serial a set of arguments into a method call message,
4775
* send that to the server and wait for reply
4778
callWithFD(virConnectPtr conn ATTRIBUTE_UNUSED,
4779
struct private_data *priv,
4783
xdrproc_t args_filter, char *args,
4784
xdrproc_t ret_filter, char *ret)
4787
virNetClientProgramPtr prog = flags & REMOTE_CALL_QEMU ? priv->qemuProgram : priv->remoteProgram;
4788
int counter = priv->counter++;
4789
virNetClientPtr client = priv->client;
4791
size_t nfds = fd == -1 ? 0 : 1;
4794
/* Unlock, so that if we get any async events/stream data
4795
* while processing the RPC, we don't deadlock when our
4796
* callbacks for those are invoked
4798
remoteDriverUnlock(priv);
4799
rv = virNetClientProgramCall(prog,
4803
nfds, nfds ? fds : NULL, NULL, NULL,
4806
remoteDriverLock(priv);
4813
call (virConnectPtr conn,
4814
struct private_data *priv,
4817
xdrproc_t args_filter, char *args,
4818
xdrproc_t ret_filter, char *ret)
4820
return callWithFD(conn, priv, flags, -1, proc_nr,
4827
remoteDomainGetInterfaceParameters (virDomainPtr domain,
4829
virTypedParameterPtr params, int *nparams,
4833
remote_domain_get_interface_parameters_args args;
4834
remote_domain_get_interface_parameters_ret ret;
4835
struct private_data *priv = domain->conn->privateData;
4837
remoteDriverLock(priv);
4839
make_nonnull_domain (&args.dom, domain);
4840
args.device = (char *)device;
4841
args.nparams = *nparams;
4844
memset (&ret, 0, sizeof(ret));
4845
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS,
4846
(xdrproc_t) xdr_remote_domain_get_interface_parameters_args, (char *) &args,
4847
(xdrproc_t) xdr_remote_domain_get_interface_parameters_ret, (char *) &ret) == -1)
4850
/* Handle the case when the caller does not know the number of parameters
4851
* and is asking for the number of parameters supported
4853
if (*nparams == 0) {
4854
*nparams = ret.nparams;
4859
if (remoteDeserializeTypedParameters(ret.params.params_val,
4860
ret.params.params_len,
4861
REMOTE_DOMAIN_INTERFACE_PARAMETERS_MAX,
4869
xdr_free ((xdrproc_t) xdr_remote_domain_get_interface_parameters_ret,
4872
remoteDriverUnlock(priv);
4877
remoteDomainListAllSnapshots(virDomainPtr dom,
4878
virDomainSnapshotPtr **snapshots,
4883
virDomainSnapshotPtr *snaps = NULL;
4884
remote_domain_list_all_snapshots_args args;
4885
remote_domain_list_all_snapshots_ret ret;
4887
struct private_data *priv = dom->conn->privateData;
4889
remoteDriverLock(priv);
4891
args.need_results = !!snapshots;
4894
memset(&ret, 0, sizeof(ret));
4895
if (call (dom->conn,
4898
REMOTE_PROC_DOMAIN_LIST_ALL_SNAPSHOTS,
4899
(xdrproc_t) xdr_remote_domain_list_all_snapshots_args,
4901
(xdrproc_t) xdr_remote_domain_list_all_snapshots_ret,
4902
(char *) &ret) == -1)
4906
if (VIR_ALLOC_N(snaps, ret.snapshots.snapshots_len + 1) < 0) {
4907
virReportOOMError();
4910
for (i = 0; i < ret.snapshots.snapshots_len; i++) {
4911
snaps[i] = get_nonnull_domain_snapshot(dom, ret.snapshots.snapshots_val[i]);
4913
virReportOOMError();
4925
for (i = 0; i < ret.snapshots.snapshots_len; i++)
4927
virDomainSnapshotFree(snaps[i]);
4931
xdr_free((xdrproc_t) xdr_remote_domain_list_all_snapshots_ret, (char *) &ret);
4934
remoteDriverUnlock(priv);
4939
remoteDomainSnapshotListAllChildren(virDomainSnapshotPtr parent,
4940
virDomainSnapshotPtr **snapshots,
4945
virDomainSnapshotPtr *snaps = NULL;
4946
remote_domain_snapshot_list_all_children_args args;
4947
remote_domain_snapshot_list_all_children_ret ret;
4949
struct private_data *priv = parent->domain->conn->privateData;
4951
remoteDriverLock(priv);
4953
args.need_results = !!snapshots;
4956
memset(&ret, 0, sizeof(ret));
4957
if (call (parent->domain->conn,
4960
REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN,
4961
(xdrproc_t) xdr_remote_domain_snapshot_list_all_children_args,
4963
(xdrproc_t) xdr_remote_domain_snapshot_list_all_children_ret,
4964
(char *) &ret) == -1)
4968
if (VIR_ALLOC_N(snaps, ret.snapshots.snapshots_len + 1) < 0) {
4969
virReportOOMError();
4972
for (i = 0; i < ret.snapshots.snapshots_len; i++) {
4973
snaps[i] = get_nonnull_domain_snapshot(parent->domain, ret.snapshots.snapshots_val[i]);
4975
virReportOOMError();
4987
for (i = 0; i < ret.snapshots.snapshots_len; i++)
4989
virDomainSnapshotFree(snaps[i]);
4993
xdr_free((xdrproc_t) xdr_remote_domain_snapshot_list_all_children_ret, (char *) &ret);
4996
remoteDriverUnlock(priv);
5001
remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event)
5003
virDomainEventStateQueue(priv->domainEventState, event);
5006
/* get_nonnull_domain and get_nonnull_network turn an on-wire
5007
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
5008
* These can return NULL if underlying memory allocations fail,
5009
* but if they do then virterror_internal.has been set.
5012
get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain)
5015
dom = virGetDomain (conn, domain.name, BAD_CAST domain.uuid);
5016
if (dom) dom->id = domain.id;
5020
static virNetworkPtr
5021
get_nonnull_network (virConnectPtr conn, remote_nonnull_network network)
5023
return virGetNetwork (conn, network.name, BAD_CAST network.uuid);
5026
static virInterfacePtr
5027
get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface iface)
5029
return virGetInterface (conn, iface.name, iface.mac);
5032
static virStoragePoolPtr
5033
get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool)
5035
return virGetStoragePool (conn, pool.name, BAD_CAST pool.uuid);
5038
static virStorageVolPtr
5039
get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol)
5041
return virGetStorageVol (conn, vol.pool, vol.name, vol.key);
5044
static virNodeDevicePtr
5045
get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev)
5047
return virGetNodeDevice(conn, dev.name);
5051
get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
5053
return virGetSecret(conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID);
5056
static virNWFilterPtr
5057
get_nonnull_nwfilter (virConnectPtr conn, remote_nonnull_nwfilter nwfilter)
5059
return virGetNWFilter (conn, nwfilter.name, BAD_CAST nwfilter.uuid);
5062
static virDomainSnapshotPtr
5063
get_nonnull_domain_snapshot (virDomainPtr domain, remote_nonnull_domain_snapshot snapshot)
5065
return virGetDomainSnapshot(domain, snapshot.name);
5069
/* Make remote_nonnull_domain and remote_nonnull_network. */
5071
make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
5073
dom_dst->id = dom_src->id;
5074
dom_dst->name = dom_src->name;
5075
memcpy (dom_dst->uuid, dom_src->uuid, VIR_UUID_BUFLEN);
5079
make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src)
5081
net_dst->name = net_src->name;
5082
memcpy (net_dst->uuid, net_src->uuid, VIR_UUID_BUFLEN);
5086
make_nonnull_interface (remote_nonnull_interface *interface_dst,
5087
virInterfacePtr interface_src)
5089
interface_dst->name = interface_src->name;
5090
interface_dst->mac = interface_src->mac;
5094
make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src)
5096
pool_dst->name = pool_src->name;
5097
memcpy (pool_dst->uuid, pool_src->uuid, VIR_UUID_BUFLEN);
5101
make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src)
5103
vol_dst->pool = vol_src->pool;
5104
vol_dst->name = vol_src->name;
5105
vol_dst->key = vol_src->key;
5109
make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
5111
memcpy (secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
5112
secret_dst->usageType = secret_src->usageType;
5113
secret_dst->usageID = secret_src->usageID;
5117
make_nonnull_nwfilter (remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src)
5119
nwfilter_dst->name = nwfilter_src->name;
5120
memcpy (nwfilter_dst->uuid, nwfilter_src->uuid, VIR_UUID_BUFLEN);
5124
make_nonnull_domain_snapshot (remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src)
5126
snapshot_dst->name = snapshot_src->name;
5127
make_nonnull_domain(&snapshot_dst->dom, snapshot_src->domain);
5130
/*----------------------------------------------------------------------*/
5132
unsigned long remoteVersion(void)
5134
return REMOTE_PROTOCOL_VERSION;
5137
static virDriver remote_driver = {
5138
.no = VIR_DRV_REMOTE,
5140
.open = remoteOpen, /* 0.3.0 */
5141
.close = remoteClose, /* 0.3.0 */
5142
.supports_feature = remoteSupportsFeature, /* 0.3.0 */
5143
.type = remoteType, /* 0.3.0 */
5144
.version = remoteGetVersion, /* 0.3.0 */
5145
.libvirtVersion = remoteGetLibVersion, /* 0.7.3 */
5146
.getHostname = remoteGetHostname, /* 0.3.0 */
5147
.getSysinfo = remoteGetSysinfo, /* 0.8.8 */
5148
.getMaxVcpus = remoteGetMaxVcpus, /* 0.3.0 */
5149
.nodeGetInfo = remoteNodeGetInfo, /* 0.3.0 */
5150
.getCapabilities = remoteGetCapabilities, /* 0.3.0 */
5151
.listDomains = remoteListDomains, /* 0.3.0 */
5152
.numOfDomains = remoteNumOfDomains, /* 0.3.0 */
5153
.listAllDomains = remoteConnectListAllDomains, /* 0.9.13 */
5154
.domainCreateXML = remoteDomainCreateXML, /* 0.3.0 */
5155
.domainLookupByID = remoteDomainLookupByID, /* 0.3.0 */
5156
.domainLookupByUUID = remoteDomainLookupByUUID, /* 0.3.0 */
5157
.domainLookupByName = remoteDomainLookupByName, /* 0.3.0 */
5158
.domainSuspend = remoteDomainSuspend, /* 0.3.0 */
5159
.domainResume = remoteDomainResume, /* 0.3.0 */
5160
.domainPMSuspendForDuration = remoteDomainPMSuspendForDuration, /* 0.9.10 */
5161
.domainPMWakeup = remoteDomainPMWakeup, /* 0.9.11 */
5162
.domainShutdown = remoteDomainShutdown, /* 0.3.0 */
5163
.domainShutdownFlags = remoteDomainShutdownFlags, /* 0.9.10 */
5164
.domainReboot = remoteDomainReboot, /* 0.3.0 */
5165
.domainReset = remoteDomainReset, /* 0.9.7 */
5166
.domainDestroy = remoteDomainDestroy, /* 0.3.0 */
5167
.domainDestroyFlags = remoteDomainDestroyFlags, /* 0.9.4 */
5168
.domainGetOSType = remoteDomainGetOSType, /* 0.3.0 */
5169
.domainGetMaxMemory = remoteDomainGetMaxMemory, /* 0.3.0 */
5170
.domainSetMaxMemory = remoteDomainSetMaxMemory, /* 0.3.0 */
5171
.domainSetMemory = remoteDomainSetMemory, /* 0.3.0 */
5172
.domainSetMemoryFlags = remoteDomainSetMemoryFlags, /* 0.9.0 */
5173
.domainSetMemoryParameters = remoteDomainSetMemoryParameters, /* 0.8.5 */
5174
.domainGetMemoryParameters = remoteDomainGetMemoryParameters, /* 0.8.5 */
5175
.domainSetBlkioParameters = remoteDomainSetBlkioParameters, /* 0.9.0 */
5176
.domainGetBlkioParameters = remoteDomainGetBlkioParameters, /* 0.9.0 */
5177
.domainGetInfo = remoteDomainGetInfo, /* 0.3.0 */
5178
.domainGetState = remoteDomainGetState, /* 0.9.2 */
5179
.domainGetControlInfo = remoteDomainGetControlInfo, /* 0.9.3 */
5180
.domainSave = remoteDomainSave, /* 0.3.0 */
5181
.domainSaveFlags = remoteDomainSaveFlags, /* 0.9.4 */
5182
.domainRestore = remoteDomainRestore, /* 0.3.0 */
5183
.domainRestoreFlags = remoteDomainRestoreFlags, /* 0.9.4 */
5184
.domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */
5185
.domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */
5186
.domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */
5187
.domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */
5188
.domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */
5189
.domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */
5190
.domainGetVcpusFlags = remoteDomainGetVcpusFlags, /* 0.8.5 */
5191
.domainPinVcpu = remoteDomainPinVcpu, /* 0.3.0 */
5192
.domainPinVcpuFlags = remoteDomainPinVcpuFlags, /* 0.9.3 */
5193
.domainGetVcpuPinInfo = remoteDomainGetVcpuPinInfo, /* 0.9.3 */
5194
.domainGetVcpus = remoteDomainGetVcpus, /* 0.3.0 */
5195
.domainGetMaxVcpus = remoteDomainGetMaxVcpus, /* 0.3.0 */
5196
.domainGetSecurityLabel = remoteDomainGetSecurityLabel, /* 0.6.1 */
5197
.nodeGetSecurityModel = remoteNodeGetSecurityModel, /* 0.6.1 */
5198
.domainGetXMLDesc = remoteDomainGetXMLDesc, /* 0.3.0 */
5199
.domainXMLFromNative = remoteDomainXMLFromNative, /* 0.6.4 */
5200
.domainXMLToNative = remoteDomainXMLToNative, /* 0.6.4 */
5201
.listDefinedDomains = remoteListDefinedDomains, /* 0.3.0 */
5202
.numOfDefinedDomains = remoteNumOfDefinedDomains, /* 0.3.0 */
5203
.domainCreate = remoteDomainCreate, /* 0.3.0 */
5204
.domainCreateWithFlags = remoteDomainCreateWithFlags, /* 0.8.2 */
5205
.domainDefineXML = remoteDomainDefineXML, /* 0.3.0 */
5206
.domainUndefine = remoteDomainUndefine, /* 0.3.0 */
5207
.domainUndefineFlags = remoteDomainUndefineFlags, /* 0.9.4 */
5208
.domainAttachDevice = remoteDomainAttachDevice, /* 0.3.0 */
5209
.domainAttachDeviceFlags = remoteDomainAttachDeviceFlags, /* 0.7.7 */
5210
.domainDetachDevice = remoteDomainDetachDevice, /* 0.3.0 */
5211
.domainDetachDeviceFlags = remoteDomainDetachDeviceFlags, /* 0.7.7 */
5212
.domainUpdateDeviceFlags = remoteDomainUpdateDeviceFlags, /* 0.8.0 */
5213
.domainGetAutostart = remoteDomainGetAutostart, /* 0.3.0 */
5214
.domainSetAutostart = remoteDomainSetAutostart, /* 0.3.0 */
5215
.domainGetSchedulerType = remoteDomainGetSchedulerType, /* 0.3.0 */
5216
.domainGetSchedulerParameters = remoteDomainGetSchedulerParameters, /* 0.3.0 */
5217
.domainGetSchedulerParametersFlags = remoteDomainGetSchedulerParametersFlags, /* 0.9.2 */
5218
.domainSetSchedulerParameters = remoteDomainSetSchedulerParameters, /* 0.3.0 */
5219
.domainSetSchedulerParametersFlags = remoteDomainSetSchedulerParametersFlags, /* 0.9.2 */
5220
.domainMigratePrepare = remoteDomainMigratePrepare, /* 0.3.2 */
5221
.domainMigratePerform = remoteDomainMigratePerform, /* 0.3.2 */
5222
.domainMigrateFinish = remoteDomainMigrateFinish, /* 0.3.2 */
5223
.domainBlockResize = remoteDomainBlockResize, /* 0.9.8 */
5224
.domainBlockStats = remoteDomainBlockStats, /* 0.3.2 */
5225
.domainBlockStatsFlags = remoteDomainBlockStatsFlags, /* 0.9.5 */
5226
.domainInterfaceStats = remoteDomainInterfaceStats, /* 0.3.2 */
5227
.domainSetInterfaceParameters = remoteDomainSetInterfaceParameters, /* 0.9.9 */
5228
.domainGetInterfaceParameters = remoteDomainGetInterfaceParameters, /* 0.9.9 */
5229
.domainMemoryStats = remoteDomainMemoryStats, /* 0.7.5 */
5230
.domainBlockPeek = remoteDomainBlockPeek, /* 0.4.2 */
5231
.domainMemoryPeek = remoteDomainMemoryPeek, /* 0.4.2 */
5232
.domainGetBlockInfo = remoteDomainGetBlockInfo, /* 0.8.1 */
5233
.nodeGetCPUStats = remoteNodeGetCPUStats, /* 0.9.3 */
5234
.nodeGetMemoryStats = remoteNodeGetMemoryStats, /* 0.9.3 */
5235
.nodeGetCellsFreeMemory = remoteNodeGetCellsFreeMemory, /* 0.3.3 */
5236
.nodeGetFreeMemory = remoteNodeGetFreeMemory, /* 0.3.3 */
5237
.domainEventRegister = remoteDomainEventRegister, /* 0.5.0 */
5238
.domainEventDeregister = remoteDomainEventDeregister, /* 0.5.0 */
5239
.domainMigratePrepare2 = remoteDomainMigratePrepare2, /* 0.5.0 */
5240
.domainMigrateFinish2 = remoteDomainMigrateFinish2, /* 0.5.0 */
5241
.nodeDeviceDettach = remoteNodeDeviceDettach, /* 0.6.1 */
5242
.nodeDeviceReAttach = remoteNodeDeviceReAttach, /* 0.6.1 */
5243
.nodeDeviceReset = remoteNodeDeviceReset, /* 0.6.1 */
5244
.domainMigratePrepareTunnel = remoteDomainMigratePrepareTunnel, /* 0.7.2 */
5245
.isEncrypted = remoteIsEncrypted, /* 0.7.3 */
5246
.isSecure = remoteIsSecure, /* 0.7.3 */
5247
.domainIsActive = remoteDomainIsActive, /* 0.7.3 */
5248
.domainIsPersistent = remoteDomainIsPersistent, /* 0.7.3 */
5249
.domainIsUpdated = remoteDomainIsUpdated, /* 0.8.6 */
5250
.cpuCompare = remoteCPUCompare, /* 0.7.5 */
5251
.cpuBaseline = remoteCPUBaseline, /* 0.7.7 */
5252
.domainGetJobInfo = remoteDomainGetJobInfo, /* 0.7.7 */
5253
.domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */
5254
.domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */
5255
.domainMigrateSetMaxSpeed = remoteDomainMigrateSetMaxSpeed, /* 0.9.0 */
5256
.domainMigrateGetMaxSpeed = remoteDomainMigrateGetMaxSpeed, /* 0.9.5 */
5257
.domainEventRegisterAny = remoteDomainEventRegisterAny, /* 0.8.0 */
5258
.domainEventDeregisterAny = remoteDomainEventDeregisterAny, /* 0.8.0 */
5259
.domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */
5260
.domainHasManagedSaveImage = remoteDomainHasManagedSaveImage, /* 0.8.0 */
5261
.domainManagedSaveRemove = remoteDomainManagedSaveRemove, /* 0.8.0 */
5262
.domainSnapshotCreateXML = remoteDomainSnapshotCreateXML, /* 0.8.0 */
5263
.domainSnapshotGetXMLDesc = remoteDomainSnapshotGetXMLDesc, /* 0.8.0 */
5264
.domainSnapshotNum = remoteDomainSnapshotNum, /* 0.8.0 */
5265
.domainSnapshotListNames = remoteDomainSnapshotListNames, /* 0.8.0 */
5266
.domainListAllSnapshots = remoteDomainListAllSnapshots, /* 0.9.13 */
5267
.domainSnapshotNumChildren = remoteDomainSnapshotNumChildren, /* 0.9.7 */
5268
.domainSnapshotListAllChildren = remoteDomainSnapshotListAllChildren, /* 0.9.13 */
5269
.domainSnapshotListChildrenNames = remoteDomainSnapshotListChildrenNames, /* 0.9.7 */
5270
.domainSnapshotLookupByName = remoteDomainSnapshotLookupByName, /* 0.8.0 */
5271
.domainHasCurrentSnapshot = remoteDomainHasCurrentSnapshot, /* 0.8.0 */
5272
.domainSnapshotGetParent = remoteDomainSnapshotGetParent, /* 0.9.7 */
5273
.domainSnapshotCurrent = remoteDomainSnapshotCurrent, /* 0.8.0 */
5274
.domainRevertToSnapshot = remoteDomainRevertToSnapshot, /* 0.8.0 */
5275
.domainSnapshotIsCurrent = remoteDomainSnapshotIsCurrent, /* 0.9.13 */
5276
.domainSnapshotHasMetadata = remoteDomainSnapshotHasMetadata, /* 0.9.13 */
5277
.domainSnapshotDelete = remoteDomainSnapshotDelete, /* 0.8.0 */
5278
.qemuDomainMonitorCommand = remoteQemuDomainMonitorCommand, /* 0.8.3 */
5279
.qemuDomainAttach = qemuDomainAttach, /* 0.9.4 */
5280
.domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */
5281
.domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */
5282
.domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */
5283
.domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */
5284
.domainMigratePrepare3 = remoteDomainMigratePrepare3, /* 0.9.2 */
5285
.domainMigratePrepareTunnel3 = remoteDomainMigratePrepareTunnel3, /* 0.9.2 */
5286
.domainMigratePerform3 = remoteDomainMigratePerform3, /* 0.9.2 */
5287
.domainMigrateFinish3 = remoteDomainMigrateFinish3, /* 0.9.2 */
5288
.domainMigrateConfirm3 = remoteDomainMigrateConfirm3, /* 0.9.2 */
5289
.domainSendKey = remoteDomainSendKey, /* 0.9.3 */
5290
.domainBlockJobAbort = remoteDomainBlockJobAbort, /* 0.9.4 */
5291
.domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */
5292
.domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
5293
.domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
5294
.domainBlockRebase = remoteDomainBlockRebase, /* 0.9.10 */
5295
.setKeepAlive = remoteSetKeepAlive, /* 0.9.8 */
5296
.isAlive = remoteIsAlive, /* 0.9.8 */
5297
.nodeSuspendForDuration = remoteNodeSuspendForDuration, /* 0.9.8 */
5298
.domainSetBlockIoTune = remoteDomainSetBlockIoTune, /* 0.9.8 */
5299
.domainGetBlockIoTune = remoteDomainGetBlockIoTune, /* 0.9.8 */
5300
.domainSetNumaParameters = remoteDomainSetNumaParameters, /* 0.9.9 */
5301
.domainGetNumaParameters = remoteDomainGetNumaParameters, /* 0.9.9 */
5302
.domainGetCPUStats = remoteDomainGetCPUStats, /* 0.9.10 */
5303
.domainGetDiskErrors = remoteDomainGetDiskErrors, /* 0.9.10 */
5304
.domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */
5305
.domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */
5308
static virNetworkDriver network_driver = {
5310
.open = remoteNetworkOpen, /* 0.3.0 */
5311
.close = remoteNetworkClose, /* 0.3.0 */
5312
.numOfNetworks = remoteNumOfNetworks, /* 0.3.0 */
5313
.listNetworks = remoteListNetworks, /* 0.3.0 */
5314
.numOfDefinedNetworks = remoteNumOfDefinedNetworks, /* 0.3.0 */
5315
.listDefinedNetworks = remoteListDefinedNetworks, /* 0.3.0 */
5316
.networkLookupByUUID = remoteNetworkLookupByUUID, /* 0.3.0 */
5317
.networkLookupByName = remoteNetworkLookupByName, /* 0.3.0 */
5318
.networkCreateXML = remoteNetworkCreateXML, /* 0.3.0 */
5319
.networkDefineXML = remoteNetworkDefineXML, /* 0.3.0 */
5320
.networkUndefine = remoteNetworkUndefine, /* 0.3.0 */
5321
.networkCreate = remoteNetworkCreate, /* 0.3.0 */
5322
.networkDestroy = remoteNetworkDestroy, /* 0.3.0 */
5323
.networkGetXMLDesc = remoteNetworkGetXMLDesc, /* 0.3.0 */
5324
.networkGetBridgeName = remoteNetworkGetBridgeName, /* 0.3.0 */
5325
.networkGetAutostart = remoteNetworkGetAutostart, /* 0.3.0 */
5326
.networkSetAutostart = remoteNetworkSetAutostart, /* 0.3.0 */
5327
.networkIsActive = remoteNetworkIsActive, /* 0.7.3 */
5328
.networkIsPersistent = remoteNetworkIsPersistent, /* 0.7.3 */
5331
static virInterfaceDriver interface_driver = {
5333
.open = remoteInterfaceOpen, /* 0.7.2 */
5334
.close = remoteInterfaceClose, /* 0.7.2 */
5335
.numOfInterfaces = remoteNumOfInterfaces, /* 0.7.2 */
5336
.listInterfaces = remoteListInterfaces, /* 0.7.2 */
5337
.numOfDefinedInterfaces = remoteNumOfDefinedInterfaces, /* 0.7.2 */
5338
.listDefinedInterfaces = remoteListDefinedInterfaces, /* 0.7.2 */
5339
.interfaceLookupByName = remoteInterfaceLookupByName, /* 0.7.2 */
5340
.interfaceLookupByMACString = remoteInterfaceLookupByMACString, /* 0.7.2 */
5341
.interfaceGetXMLDesc = remoteInterfaceGetXMLDesc, /* 0.7.2 */
5342
.interfaceDefineXML = remoteInterfaceDefineXML, /* 0.7.2 */
5343
.interfaceUndefine = remoteInterfaceUndefine, /* 0.7.2 */
5344
.interfaceCreate = remoteInterfaceCreate, /* 0.7.2 */
5345
.interfaceDestroy = remoteInterfaceDestroy, /* 0.7.2 */
5346
.interfaceIsActive = remoteInterfaceIsActive, /* 0.7.3 */
5347
.interfaceChangeBegin = remoteInterfaceChangeBegin, /* 0.9.2 */
5348
.interfaceChangeCommit = remoteInterfaceChangeCommit, /* 0.9.2 */
5349
.interfaceChangeRollback = remoteInterfaceChangeRollback, /* 0.9.2 */
5352
static virStorageDriver storage_driver = {
5354
.open = remoteStorageOpen, /* 0.4.1 */
5355
.close = remoteStorageClose, /* 0.4.1 */
5356
.numOfPools = remoteNumOfStoragePools, /* 0.4.1 */
5357
.listPools = remoteListStoragePools, /* 0.4.1 */
5358
.numOfDefinedPools = remoteNumOfDefinedStoragePools, /* 0.4.1 */
5359
.listDefinedPools = remoteListDefinedStoragePools, /* 0.4.1 */
5360
.findPoolSources = remoteFindStoragePoolSources, /* 0.4.5 */
5361
.poolLookupByName = remoteStoragePoolLookupByName, /* 0.4.1 */
5362
.poolLookupByUUID = remoteStoragePoolLookupByUUID, /* 0.4.1 */
5363
.poolLookupByVolume = remoteStoragePoolLookupByVolume, /* 0.4.1 */
5364
.poolCreateXML = remoteStoragePoolCreateXML, /* 0.4.1 */
5365
.poolDefineXML = remoteStoragePoolDefineXML, /* 0.4.1 */
5366
.poolBuild = remoteStoragePoolBuild, /* 0.4.1 */
5367
.poolUndefine = remoteStoragePoolUndefine, /* 0.4.1 */
5368
.poolCreate = remoteStoragePoolCreate, /* 0.4.1 */
5369
.poolDestroy = remoteStoragePoolDestroy, /* 0.4.1 */
5370
.poolDelete = remoteStoragePoolDelete, /* 0.4.1 */
5371
.poolRefresh = remoteStoragePoolRefresh, /* 0.4.1 */
5372
.poolGetInfo = remoteStoragePoolGetInfo, /* 0.4.1 */
5373
.poolGetXMLDesc = remoteStoragePoolGetXMLDesc, /* 0.4.1 */
5374
.poolGetAutostart = remoteStoragePoolGetAutostart, /* 0.4.1 */
5375
.poolSetAutostart = remoteStoragePoolSetAutostart, /* 0.4.1 */
5376
.poolNumOfVolumes = remoteStoragePoolNumOfVolumes, /* 0.4.1 */
5377
.poolListVolumes = remoteStoragePoolListVolumes, /* 0.4.1 */
5379
.volLookupByName = remoteStorageVolLookupByName, /* 0.4.1 */
5380
.volLookupByKey = remoteStorageVolLookupByKey, /* 0.4.1 */
5381
.volLookupByPath = remoteStorageVolLookupByPath, /* 0.4.1 */
5382
.volCreateXML = remoteStorageVolCreateXML, /* 0.4.1 */
5383
.volCreateXMLFrom = remoteStorageVolCreateXMLFrom, /* 0.6.4 */
5384
.volDownload = remoteStorageVolDownload, /* 0.9.0 */
5385
.volUpload = remoteStorageVolUpload, /* 0.9.0 */
5386
.volDelete = remoteStorageVolDelete, /* 0.4.1 */
5387
.volWipe = remoteStorageVolWipe, /* 0.8.0 */
5388
.volWipePattern = remoteStorageVolWipePattern, /* 0.9.10 */
5389
.volGetInfo = remoteStorageVolGetInfo, /* 0.4.1 */
5390
.volGetXMLDesc = remoteStorageVolGetXMLDesc, /* 0.4.1 */
5391
.volGetPath = remoteStorageVolGetPath, /* 0.4.1 */
5392
.volResize = remoteStorageVolResize, /* 0.9.10 */
5393
.poolIsActive = remoteStoragePoolIsActive, /* 0.7.3 */
5394
.poolIsPersistent = remoteStoragePoolIsPersistent, /* 0.7.3 */
5397
static virSecretDriver secret_driver = {
5399
.open = remoteSecretOpen, /* 0.7.1 */
5400
.close = remoteSecretClose, /* 0.7.1 */
5401
.numOfSecrets = remoteNumOfSecrets, /* 0.7.1 */
5402
.listSecrets = remoteListSecrets, /* 0.7.1 */
5403
.lookupByUUID = remoteSecretLookupByUUID, /* 0.7.1 */
5404
.lookupByUsage = remoteSecretLookupByUsage, /* 0.7.1 */
5405
.defineXML = remoteSecretDefineXML, /* 0.7.1 */
5406
.getXMLDesc = remoteSecretGetXMLDesc, /* 0.7.1 */
5407
.setValue = remoteSecretSetValue, /* 0.7.1 */
5408
.getValue = remoteSecretGetValue, /* 0.7.1 */
5409
.undefine = remoteSecretUndefine /* 0.7.1 */
5412
static virDeviceMonitor dev_monitor = {
5414
.open = remoteDevMonOpen, /* 0.5.0 */
5415
.close = remoteDevMonClose, /* 0.5.0 */
5416
.numOfDevices = remoteNodeNumOfDevices, /* 0.5.0 */
5417
.listDevices = remoteNodeListDevices, /* 0.5.0 */
5418
.deviceLookupByName = remoteNodeDeviceLookupByName, /* 0.5.0 */
5419
.deviceGetXMLDesc = remoteNodeDeviceGetXMLDesc, /* 0.5.0 */
5420
.deviceGetParent = remoteNodeDeviceGetParent, /* 0.5.0 */
5421
.deviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
5422
.deviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
5423
.deviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
5424
.deviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
5427
static virNWFilterDriver nwfilter_driver = {
5429
.open = remoteNWFilterOpen, /* 0.8.0 */
5430
.close = remoteNWFilterClose, /* 0.8.0 */
5431
.nwfilterLookupByUUID = remoteNWFilterLookupByUUID, /* 0.8.0 */
5432
.nwfilterLookupByName = remoteNWFilterLookupByName, /* 0.8.0 */
5433
.getXMLDesc = remoteNWFilterGetXMLDesc, /* 0.8.0 */
5434
.defineXML = remoteNWFilterDefineXML, /* 0.8.0 */
5435
.undefine = remoteNWFilterUndefine, /* 0.8.0 */
5436
.numOfNWFilters = remoteNumOfNWFilters, /* 0.8.0 */
5437
.listNWFilters = remoteListNWFilters, /* 0.8.0 */
5441
#ifdef WITH_LIBVIRTD
5442
static virStateDriver state_driver = {
5444
.initialize = remoteStartup,
5451
* Register driver with libvirt driver system.
5453
* Returns -1 on error.
5456
remoteRegister (void)
5458
remoteDriver = &remote_driver;
5460
if (virRegisterDriver (&remote_driver) == -1) return -1;
5461
if (virRegisterNetworkDriver (&network_driver) == -1) return -1;
5462
if (virRegisterInterfaceDriver (&interface_driver) == -1) return -1;
5463
if (virRegisterStorageDriver (&storage_driver) == -1) return -1;
5464
if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1;
5465
if (virRegisterSecretDriver (&secret_driver) == -1) return -1;
5466
if (virRegisterNWFilterDriver(&nwfilter_driver) == -1) return -1;
5467
#ifdef WITH_LIBVIRTD
5468
if (virRegisterStateDriver (&state_driver) == -1) return -1;