1 /*
2 * remote_driver.c: driver to provide access to libvirtd running
3 * on a remote machine
4 *
5 * Copyright (C) 2007-2015 Red Hat, Inc.
6 *
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.
11 *
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.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23
24 #include <unistd.h>
25
26 #include "virnetclient.h"
27 #include "virnetclientprogram.h"
28 #include "virnetclientstream.h"
29 #include "virerror.h"
30 #include "virlog.h"
31 #include "datatypes.h"
32 #include "domain_event.h"
33 #include "network_event.h"
34 #include "storage_event.h"
35 #include "node_device_event.h"
36 #include "secret_event.h"
37 #include "driver.h"
38 #include "virbuffer.h"
39 #include "remote_driver.h"
40 #include "remote_protocol.h"
41 #include "remote_sockets.h"
42 #include "lxc_protocol.h"
43 #include "qemu_protocol.h"
44 #include "viralloc.h"
45 #include "virfile.h"
46 #include "vircommand.h"
47 #include "virtypedparam.h"
48 #include "viruri.h"
49 #include "virauth.h"
50 #include "virauthconfig.h"
51 #include "virstring.h"
52 #include "virutil.h"
53
54 #define VIR_FROM_THIS VIR_FROM_REMOTE
55
56 VIR_LOG_INIT("remote.remote_driver");
57
58
59 #if SIZEOF_LONG < 8
60 # define HYPER_TO_TYPE(_type, _to, _from) \
61 do { \
62 if ((_from) != (_type)(_from)) { \
63 virReportError(VIR_ERR_INTERNAL_ERROR, \
64 _("conversion from hyper to %s overflowed"), #_type); \
65 goto done; \
66 } \
67 (_to) = (_from); \
68 } while (0)
69
70 # define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
71 # define HYPER_TO_ULONG(_to, _from) HYPER_TO_TYPE(unsigned long, _to, _from)
72 #else
73 # define HYPER_TO_LONG(_to, _from) (_to) = (_from)
74 # define HYPER_TO_ULONG(_to, _from) (_to) = (_from)
75 #endif
76
77 static bool inside_daemon;
78
79 struct private_data {
80 virMutex lock;
81
82 virNetClient *client;
83 virNetClientProgram *remoteProgram;
84 virNetClientProgram *qemuProgram;
85 virNetClientProgram *lxcProgram;
86
87 int counter; /* Serial number for RPC */
88
89 virNetTLSContext *tls;
90
91 int is_secure; /* Secure if TLS or SASL or UNIX sockets */
92 char *type; /* Cached return from remoteType. */
93 int localUses; /* Ref count for private data */
94 char *hostname; /* Original hostname */
95 bool serverKeepAlive; /* Does server support keepalive protocol? */
96 bool serverEventFilter; /* Does server support modern event filtering */
97 bool serverCloseCallback; /* Does server support driver close callback */
98
99 virObjectEventState *eventState;
100 virConnectCloseCallbackData *closeCallback;
101 };
102
103 enum {
104 REMOTE_CALL_QEMU = (1 << 0),
105 REMOTE_CALL_LXC = (1 << 1),
106 };
107
108
remoteDriverLock(struct private_data * driver)109 static void remoteDriverLock(struct private_data *driver)
110 {
111 virMutexLock(&driver->lock);
112 }
113
remoteDriverUnlock(struct private_data * driver)114 static void remoteDriverUnlock(struct private_data *driver)
115 {
116 virMutexUnlock(&driver->lock);
117 }
118
119 static int call(virConnectPtr conn, struct private_data *priv,
120 unsigned int flags, int proc_nr,
121 xdrproc_t args_filter, char *args,
122 xdrproc_t ret_filter, char *ret);
123 static int callFull(virConnectPtr conn, struct private_data *priv,
124 unsigned int flags,
125 int *fdin, size_t fdinlen,
126 int **fdout, size_t *fdoutlen,
127 int proc_nr,
128 xdrproc_t args_filter, char *args,
129 xdrproc_t ret_filter, char *ret);
130 static int remoteAuthenticate(virConnectPtr conn, struct private_data *priv,
131 virConnectAuthPtr auth, const char *authtype);
132 #if WITH_SASL
133 static int remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
134 virConnectAuthPtr auth, const char *mech);
135 #endif /* WITH_SASL */
136 static int remoteAuthPolkit(virConnectPtr conn, struct private_data *priv,
137 virConnectAuthPtr auth);
138
139 static virDomainPtr get_nonnull_domain(virConnectPtr conn, remote_nonnull_domain domain);
140 static virNetworkPtr get_nonnull_network(virConnectPtr conn, remote_nonnull_network network);
141 static virNetworkPortPtr get_nonnull_network_port(virConnectPtr conn, remote_nonnull_network_port port);
142 static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
143 static virNWFilterBindingPtr get_nonnull_nwfilter_binding(virConnectPtr conn, remote_nonnull_nwfilter_binding binding);
144 static virInterfacePtr get_nonnull_interface(virConnectPtr conn, remote_nonnull_interface iface);
145 static virStoragePoolPtr get_nonnull_storage_pool(virConnectPtr conn, remote_nonnull_storage_pool pool);
146 static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnull_storage_vol vol);
147 static virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev);
148 static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
149 static virDomainCheckpointPtr get_nonnull_domain_checkpoint(virDomainPtr domain, remote_nonnull_domain_checkpoint checkpoint);
150 static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot);
151 static void make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
152 static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src);
153 static void make_nonnull_network_port(remote_nonnull_network_port *port_dst, virNetworkPortPtr port_src);
154 static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
155 static void make_nonnull_storage_pool(remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src);
156 static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
157 static void
158 make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src);
159 static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
160 static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
161 static void make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding *binding_dst, virNWFilterBindingPtr binding_src);
162 static void make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint *checkpoint_dst, virDomainCheckpointPtr checkpoint_src);
163 static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
164
165 /*----------------------------------------------------------------------*/
166
167 /* Helper functions for remoteOpen. */
168
169
170 static int
remoteStateInitialize(bool privileged G_GNUC_UNUSED,const char * root G_GNUC_UNUSED,virStateInhibitCallback callback G_GNUC_UNUSED,void * opaque G_GNUC_UNUSED)171 remoteStateInitialize(bool privileged G_GNUC_UNUSED,
172 const char *root G_GNUC_UNUSED,
173 virStateInhibitCallback callback G_GNUC_UNUSED,
174 void *opaque G_GNUC_UNUSED)
175 {
176 /* Mark that we're inside the daemon so we can avoid
177 * re-entering ourselves
178 */
179 inside_daemon = true;
180 return VIR_DRV_STATE_INIT_COMPLETE;
181 }
182
183
184 static void
185 remoteDomainBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
186 virNetClient *client G_GNUC_UNUSED,
187 void *evdata, void *opaque);
188 static void
189 remoteDomainBuildEventCallbackLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
190 virNetClient *client G_GNUC_UNUSED,
191 void *evdata, void *opaque);
192
193 static void
194 remoteDomainBuildEventReboot(virNetClientProgram *prog G_GNUC_UNUSED,
195 virNetClient *client G_GNUC_UNUSED,
196 void *evdata, void *opaque);
197 static void
198 remoteDomainBuildEventCallbackReboot(virNetClientProgram *prog G_GNUC_UNUSED,
199 virNetClient *client G_GNUC_UNUSED,
200 void *evdata, void *opaque);
201
202 static void
203 remoteDomainBuildEventRTCChange(virNetClientProgram *prog,
204 virNetClient *client,
205 void *evdata, void *opaque);
206 static void
207 remoteDomainBuildEventCallbackRTCChange(virNetClientProgram *prog,
208 virNetClient *client,
209 void *evdata, void *opaque);
210
211 static void
212 remoteDomainBuildEventWatchdog(virNetClientProgram *prog,
213 virNetClient *client,
214 void *evdata, void *opaque);
215 static void
216 remoteDomainBuildEventCallbackWatchdog(virNetClientProgram *prog,
217 virNetClient *client,
218 void *evdata, void *opaque);
219
220 static void
221 remoteDomainBuildEventIOError(virNetClientProgram *prog,
222 virNetClient *client,
223 void *evdata, void *opaque);
224 static void
225 remoteDomainBuildEventCallbackIOError(virNetClientProgram *prog,
226 virNetClient *client,
227 void *evdata, void *opaque);
228
229 static void
230 remoteDomainBuildEventIOErrorReason(virNetClientProgram *prog,
231 virNetClient *client,
232 void *evdata, void *opaque);
233 static void
234 remoteDomainBuildEventCallbackIOErrorReason(virNetClientProgram *prog,
235 virNetClient *client,
236 void *evdata, void *opaque);
237
238 static void
239 remoteDomainBuildEventGraphics(virNetClientProgram *prog,
240 virNetClient *client,
241 void *evdata, void *opaque);
242 static void
243 remoteDomainBuildEventCallbackGraphics(virNetClientProgram *prog,
244 virNetClient *client,
245 void *evdata, void *opaque);
246
247 static void
248 remoteDomainBuildEventControlError(virNetClientProgram *prog,
249 virNetClient *client,
250 void *evdata, void *opaque);
251 static void
252 remoteDomainBuildEventCallbackControlError(virNetClientProgram *prog,
253 virNetClient *client,
254 void *evdata, void *opaque);
255
256 static void
257 remoteDomainBuildEventBlockJob(virNetClientProgram *prog,
258 virNetClient *client,
259 void *evdata, void *opaque);
260 static void
261 remoteDomainBuildEventCallbackBlockJob(virNetClientProgram *prog,
262 virNetClient *client,
263 void *evdata, void *opaque);
264
265
266 static void
267 remoteDomainBuildEventDiskChange(virNetClientProgram *prog,
268 virNetClient *client,
269 void *evdata, void *opaque);
270 static void
271 remoteDomainBuildEventCallbackDiskChange(virNetClientProgram *prog,
272 virNetClient *client,
273 void *evdata, void *opaque);
274
275 static void
276 remoteDomainBuildEventTrayChange(virNetClientProgram *prog,
277 virNetClient *client,
278 void *evdata, void *opaque);
279 static void
280 remoteDomainBuildEventCallbackTrayChange(virNetClientProgram *prog,
281 virNetClient *client,
282 void *evdata, void *opaque);
283
284 static void
285 remoteDomainBuildEventPMWakeup(virNetClientProgram *prog,
286 virNetClient *client,
287 void *evdata, void *opaque);
288 static void
289 remoteDomainBuildEventCallbackPMWakeup(virNetClientProgram *prog,
290 virNetClient *client,
291 void *evdata, void *opaque);
292
293 static void
294 remoteDomainBuildEventPMSuspend(virNetClientProgram *prog,
295 virNetClient *client,
296 void *evdata, void *opaque);
297 static void
298 remoteDomainBuildEventCallbackPMSuspend(virNetClientProgram *prog,
299 virNetClient *client,
300 void *evdata, void *opaque);
301
302 static void
303 remoteDomainBuildEventBalloonChange(virNetClientProgram *prog,
304 virNetClient *client,
305 void *evdata, void *opaque);
306 static void
307 remoteDomainBuildEventCallbackBalloonChange(virNetClientProgram *prog,
308 virNetClient *client,
309 void *evdata, void *opaque);
310
311 static void
312 remoteDomainBuildEventPMSuspendDisk(virNetClientProgram *prog,
313 virNetClient *client,
314 void *evdata, void *opaque);
315 static void
316 remoteDomainBuildEventCallbackPMSuspendDisk(virNetClientProgram *prog,
317 virNetClient *client,
318 void *evdata, void *opaque);
319
320 static void
321 remoteDomainBuildEventDeviceRemoved(virNetClientProgram *prog,
322 virNetClient *client,
323 void *evdata, void *opaque);
324 static void
325 remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgram *prog,
326 virNetClient *client,
327 void *evdata, void *opaque);
328 static void
329 remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgram *prog,
330 virNetClient *client,
331 void *evdata, void *opaque);
332 static void
333 remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgram *prog,
334 virNetClient *client,
335 void *evdata, void *opaque);
336
337 static void
338 remoteDomainBuildEventBlockJob2(virNetClientProgram *prog,
339 virNetClient *client,
340 void *evdata, void *opaque);
341
342 static void
343 remoteDomainBuildEventCallbackTunable(virNetClientProgram *prog,
344 virNetClient *client,
345 void *evdata, void *opaque);
346
347 static void
348 remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgram *prog,
349 virNetClient *client,
350 void *evdata, void *opaque);
351
352 static void
353 remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgram *prog,
354 virNetClient *client,
355 void *evdata, void *opaque);
356
357 static void
358 remoteDomainBuildEventCallbackJobCompleted(virNetClientProgram *prog,
359 virNetClient *client,
360 void *evdata, void *opaque);
361
362 static void
363 remoteDomainBuildEventCallbackMetadataChange(virNetClientProgram *prog,
364 virNetClient *client,
365 void *evdata, void *opaque);
366
367 static void
368 remoteNetworkBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
369 virNetClient *client G_GNUC_UNUSED,
370 void *evdata, void *opaque);
371
372 static void
373 remoteStoragePoolBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
374 virNetClient *client G_GNUC_UNUSED,
375 void *evdata, void *opaque);
376
377 static void
378 remoteStoragePoolBuildEventRefresh(virNetClientProgram *prog G_GNUC_UNUSED,
379 virNetClient *client G_GNUC_UNUSED,
380 void *evdata, void *opaque);
381
382 static void
383 remoteNodeDeviceBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
384 virNetClient *client G_GNUC_UNUSED,
385 void *evdata, void *opaque);
386
387 static void
388 remoteNodeDeviceBuildEventUpdate(virNetClientProgram *prog G_GNUC_UNUSED,
389 virNetClient *client G_GNUC_UNUSED,
390 void *evdata, void *opaque);
391
392 static void
393 remoteSecretBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
394 virNetClient *client G_GNUC_UNUSED,
395 void *evdata, void *opaque);
396
397 static void
398 remoteSecretBuildEventValueChanged(virNetClientProgram *prog G_GNUC_UNUSED,
399 virNetClient *client G_GNUC_UNUSED,
400 void *evdata, void *opaque);
401
402 static void
403 remoteDomainBuildEventBlockThreshold(virNetClientProgram *prog,
404 virNetClient *client,
405 void *evdata, void *opaque);
406
407 static void
408 remoteDomainBuildEventMemoryFailure(virNetClientProgram *prog,
409 virNetClient *client,
410 void *evdata, void *opaque);
411
412 static void
413 remoteDomainBuildEventMemoryDeviceSizeChange(virNetClientProgram *prog,
414 virNetClient *client,
415 void *evdata, void *opaque);
416 static void
417 remoteConnectNotifyEventConnectionClosed(virNetClientProgram *prog G_GNUC_UNUSED,
418 virNetClient *client G_GNUC_UNUSED,
419 void *evdata, void *opaque);
420
421 static virNetClientProgramEvent remoteEvents[] = {
422 { REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
423 remoteDomainBuildEventLifecycle,
424 sizeof(remote_domain_event_lifecycle_msg),
425 (xdrproc_t)xdr_remote_domain_event_lifecycle_msg },
426 { REMOTE_PROC_DOMAIN_EVENT_REBOOT,
427 remoteDomainBuildEventReboot,
428 sizeof(remote_domain_event_reboot_msg),
429 (xdrproc_t)xdr_remote_domain_event_reboot_msg },
430 { REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
431 remoteDomainBuildEventRTCChange,
432 sizeof(remote_domain_event_rtc_change_msg),
433 (xdrproc_t)xdr_remote_domain_event_rtc_change_msg },
434 { REMOTE_PROC_DOMAIN_EVENT_WATCHDOG,
435 remoteDomainBuildEventWatchdog,
436 sizeof(remote_domain_event_watchdog_msg),
437 (xdrproc_t)xdr_remote_domain_event_watchdog_msg},
438 { REMOTE_PROC_DOMAIN_EVENT_IO_ERROR,
439 remoteDomainBuildEventIOError,
440 sizeof(remote_domain_event_io_error_msg),
441 (xdrproc_t)xdr_remote_domain_event_io_error_msg },
442 { REMOTE_PROC_DOMAIN_EVENT_GRAPHICS,
443 remoteDomainBuildEventGraphics,
444 sizeof(remote_domain_event_graphics_msg),
445 (xdrproc_t)xdr_remote_domain_event_graphics_msg },
446 { REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON,
447 remoteDomainBuildEventIOErrorReason,
448 sizeof(remote_domain_event_io_error_reason_msg),
449 (xdrproc_t)xdr_remote_domain_event_io_error_reason_msg },
450 { REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR,
451 remoteDomainBuildEventControlError,
452 sizeof(remote_domain_event_control_error_msg),
453 (xdrproc_t)xdr_remote_domain_event_control_error_msg },
454 { REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB,
455 remoteDomainBuildEventBlockJob,
456 sizeof(remote_domain_event_block_job_msg),
457 (xdrproc_t)xdr_remote_domain_event_block_job_msg },
458 { REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE,
459 remoteDomainBuildEventDiskChange,
460 sizeof(remote_domain_event_disk_change_msg),
461 (xdrproc_t)xdr_remote_domain_event_disk_change_msg },
462 { REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE,
463 remoteDomainBuildEventTrayChange,
464 sizeof(remote_domain_event_tray_change_msg),
465 (xdrproc_t)xdr_remote_domain_event_tray_change_msg },
466 { REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP,
467 remoteDomainBuildEventPMWakeup,
468 sizeof(remote_domain_event_pmwakeup_msg),
469 (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg },
470 { REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND,
471 remoteDomainBuildEventPMSuspend,
472 sizeof(remote_domain_event_pmsuspend_msg),
473 (xdrproc_t)xdr_remote_domain_event_pmsuspend_msg },
474 { REMOTE_PROC_DOMAIN_EVENT_BALLOON_CHANGE,
475 remoteDomainBuildEventBalloonChange,
476 sizeof(remote_domain_event_balloon_change_msg),
477 (xdrproc_t)xdr_remote_domain_event_balloon_change_msg },
478 { REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK,
479 remoteDomainBuildEventPMSuspendDisk,
480 sizeof(remote_domain_event_pmsuspend_disk_msg),
481 (xdrproc_t)xdr_remote_domain_event_pmsuspend_disk_msg },
482 { REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED,
483 remoteDomainBuildEventDeviceRemoved,
484 sizeof(remote_domain_event_device_removed_msg),
485 (xdrproc_t)xdr_remote_domain_event_device_removed_msg },
486 /* All events above here are legacy events, missing the callback
487 * ID, which means the server has a single global registration and
488 * we do full filtering in the client. If the server lacks
489 * VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK, those are the only
490 * events we should ever receive. Conversely, all events below
491 * here should only be triggered by modern servers, and all
492 * contain a callbackID. Although we have to duplicate the first
493 * 16 domain events in both styles for back-compat, any future
494 * domain event additions should only use the modern style. */
495 { REMOTE_PROC_NETWORK_EVENT_LIFECYCLE,
496 remoteNetworkBuildEventLifecycle,
497 sizeof(remote_network_event_lifecycle_msg),
498 (xdrproc_t)xdr_remote_network_event_lifecycle_msg },
499 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_LIFECYCLE,
500 remoteDomainBuildEventCallbackLifecycle,
501 sizeof(remote_domain_event_callback_lifecycle_msg),
502 (xdrproc_t)xdr_remote_domain_event_callback_lifecycle_msg },
503 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_REBOOT,
504 remoteDomainBuildEventCallbackReboot,
505 sizeof(remote_domain_event_callback_reboot_msg),
506 (xdrproc_t)xdr_remote_domain_event_callback_reboot_msg },
507 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_RTC_CHANGE,
508 remoteDomainBuildEventCallbackRTCChange,
509 sizeof(remote_domain_event_callback_rtc_change_msg),
510 (xdrproc_t)xdr_remote_domain_event_callback_rtc_change_msg },
511 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WATCHDOG,
512 remoteDomainBuildEventCallbackWatchdog,
513 sizeof(remote_domain_event_callback_watchdog_msg),
514 (xdrproc_t)xdr_remote_domain_event_callback_watchdog_msg},
515 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR,
516 remoteDomainBuildEventCallbackIOError,
517 sizeof(remote_domain_event_callback_io_error_msg),
518 (xdrproc_t)xdr_remote_domain_event_callback_io_error_msg },
519 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_GRAPHICS,
520 remoteDomainBuildEventCallbackGraphics,
521 sizeof(remote_domain_event_callback_graphics_msg),
522 (xdrproc_t)xdr_remote_domain_event_callback_graphics_msg },
523 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR_REASON,
524 remoteDomainBuildEventCallbackIOErrorReason,
525 sizeof(remote_domain_event_callback_io_error_reason_msg),
526 (xdrproc_t)xdr_remote_domain_event_callback_io_error_reason_msg },
527 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CONTROL_ERROR,
528 remoteDomainBuildEventCallbackControlError,
529 sizeof(remote_domain_event_callback_control_error_msg),
530 (xdrproc_t)xdr_remote_domain_event_callback_control_error_msg },
531 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BLOCK_JOB,
532 remoteDomainBuildEventCallbackBlockJob,
533 sizeof(remote_domain_event_callback_block_job_msg),
534 (xdrproc_t)xdr_remote_domain_event_callback_block_job_msg },
535 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DISK_CHANGE,
536 remoteDomainBuildEventCallbackDiskChange,
537 sizeof(remote_domain_event_callback_disk_change_msg),
538 (xdrproc_t)xdr_remote_domain_event_callback_disk_change_msg },
539 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TRAY_CHANGE,
540 remoteDomainBuildEventCallbackTrayChange,
541 sizeof(remote_domain_event_callback_tray_change_msg),
542 (xdrproc_t)xdr_remote_domain_event_callback_tray_change_msg },
543 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMWAKEUP,
544 remoteDomainBuildEventCallbackPMWakeup,
545 sizeof(remote_domain_event_callback_pmwakeup_msg),
546 (xdrproc_t)xdr_remote_domain_event_callback_pmwakeup_msg },
547 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND,
548 remoteDomainBuildEventCallbackPMSuspend,
549 sizeof(remote_domain_event_callback_pmsuspend_msg),
550 (xdrproc_t)xdr_remote_domain_event_callback_pmsuspend_msg },
551 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE,
552 remoteDomainBuildEventCallbackBalloonChange,
553 sizeof(remote_domain_event_callback_balloon_change_msg),
554 (xdrproc_t)xdr_remote_domain_event_callback_balloon_change_msg },
555 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK,
556 remoteDomainBuildEventCallbackPMSuspendDisk,
557 sizeof(remote_domain_event_callback_pmsuspend_disk_msg),
558 (xdrproc_t)xdr_remote_domain_event_callback_pmsuspend_disk_msg },
559 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED,
560 remoteDomainBuildEventCallbackDeviceRemoved,
561 sizeof(remote_domain_event_callback_device_removed_msg),
562 (xdrproc_t)xdr_remote_domain_event_callback_device_removed_msg },
563 { REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2,
564 remoteDomainBuildEventBlockJob2,
565 sizeof(remote_domain_event_block_job_2_msg),
566 (xdrproc_t)xdr_remote_domain_event_block_job_2_msg },
567 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE,
568 remoteDomainBuildEventCallbackTunable,
569 sizeof(remote_domain_event_callback_tunable_msg),
570 (xdrproc_t)xdr_remote_domain_event_callback_tunable_msg },
571 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
572 remoteDomainBuildEventCallbackAgentLifecycle,
573 sizeof(remote_domain_event_callback_agent_lifecycle_msg),
574 (xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg },
575 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED,
576 remoteDomainBuildEventCallbackDeviceAdded,
577 sizeof(remote_domain_event_callback_device_added_msg),
578 (xdrproc_t)xdr_remote_domain_event_callback_device_added_msg },
579 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION,
580 remoteDomainBuildEventCallbackMigrationIteration,
581 sizeof(remote_domain_event_callback_migration_iteration_msg),
582 (xdrproc_t)xdr_remote_domain_event_callback_migration_iteration_msg },
583 { REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED,
584 remoteConnectNotifyEventConnectionClosed,
585 sizeof(remote_connect_event_connection_closed_msg),
586 (xdrproc_t)xdr_remote_connect_event_connection_closed_msg },
587 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_JOB_COMPLETED,
588 remoteDomainBuildEventCallbackJobCompleted,
589 sizeof(remote_domain_event_callback_job_completed_msg),
590 (xdrproc_t)xdr_remote_domain_event_callback_job_completed_msg },
591 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED,
592 remoteDomainBuildEventCallbackDeviceRemovalFailed,
593 sizeof(remote_domain_event_callback_device_removal_failed_msg),
594 (xdrproc_t)xdr_remote_domain_event_callback_device_removal_failed_msg },
595 { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_METADATA_CHANGE,
596 remoteDomainBuildEventCallbackMetadataChange,
597 sizeof(remote_domain_event_callback_metadata_change_msg),
598 (xdrproc_t)xdr_remote_domain_event_callback_metadata_change_msg },
599 { REMOTE_PROC_STORAGE_POOL_EVENT_LIFECYCLE,
600 remoteStoragePoolBuildEventLifecycle,
601 sizeof(remote_storage_pool_event_lifecycle_msg),
602 (xdrproc_t)xdr_remote_storage_pool_event_lifecycle_msg },
603 { REMOTE_PROC_STORAGE_POOL_EVENT_REFRESH,
604 remoteStoragePoolBuildEventRefresh,
605 sizeof(remote_storage_pool_event_refresh_msg),
606 (xdrproc_t)xdr_remote_storage_pool_event_refresh_msg },
607 { REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE,
608 remoteNodeDeviceBuildEventLifecycle,
609 sizeof(remote_node_device_event_lifecycle_msg),
610 (xdrproc_t)xdr_remote_node_device_event_lifecycle_msg },
611 { REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE,
612 remoteNodeDeviceBuildEventUpdate,
613 sizeof(remote_node_device_event_update_msg),
614 (xdrproc_t)xdr_remote_node_device_event_update_msg },
615 { REMOTE_PROC_SECRET_EVENT_LIFECYCLE,
616 remoteSecretBuildEventLifecycle,
617 sizeof(remote_secret_event_lifecycle_msg),
618 (xdrproc_t)xdr_remote_secret_event_lifecycle_msg },
619 { REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED,
620 remoteSecretBuildEventValueChanged,
621 sizeof(remote_secret_event_value_changed_msg),
622 (xdrproc_t)xdr_remote_secret_event_value_changed_msg },
623 { REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD,
624 remoteDomainBuildEventBlockThreshold,
625 sizeof(remote_domain_event_block_threshold_msg),
626 (xdrproc_t)xdr_remote_domain_event_block_threshold_msg },
627 { REMOTE_PROC_DOMAIN_EVENT_MEMORY_FAILURE,
628 remoteDomainBuildEventMemoryFailure,
629 sizeof(remote_domain_event_memory_failure_msg),
630 (xdrproc_t)xdr_remote_domain_event_memory_failure_msg },
631 { REMOTE_PROC_DOMAIN_EVENT_MEMORY_DEVICE_SIZE_CHANGE,
632 remoteDomainBuildEventMemoryDeviceSizeChange,
633 sizeof(remote_domain_event_memory_device_size_change_msg),
634 (xdrproc_t)xdr_remote_domain_event_memory_device_size_change_msg },
635 };
636
637 static void
remoteConnectNotifyEventConnectionClosed(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)638 remoteConnectNotifyEventConnectionClosed(virNetClientProgram *prog G_GNUC_UNUSED,
639 virNetClient *client G_GNUC_UNUSED,
640 void *evdata, void *opaque)
641 {
642 virConnectPtr conn = opaque;
643 struct private_data *priv = conn->privateData;
644 remote_connect_event_connection_closed_msg *msg = evdata;
645
646 virConnectCloseCallbackDataCall(priv->closeCallback, msg->reason);
647 }
648
649 static void
650 remoteDomainBuildQemuMonitorEvent(virNetClientProgram *prog G_GNUC_UNUSED,
651 virNetClient *client G_GNUC_UNUSED,
652 void *evdata, void *opaque);
653
654 static virNetClientProgramEvent qemuEvents[] = {
655 { QEMU_PROC_DOMAIN_MONITOR_EVENT,
656 remoteDomainBuildQemuMonitorEvent,
657 sizeof(qemu_domain_monitor_event_msg),
658 (xdrproc_t)xdr_qemu_domain_monitor_event_msg },
659 };
660
661
662 static void
remoteClientCloseFunc(virNetClient * client G_GNUC_UNUSED,int reason,void * opaque)663 remoteClientCloseFunc(virNetClient *client G_GNUC_UNUSED,
664 int reason,
665 void *opaque)
666 {
667 virConnectCloseCallbackDataCall((virConnectCloseCallbackData *)opaque,
668 reason);
669 }
670
671 static bool
remoteConnectSupportsFeatureUnlocked(virConnectPtr conn,struct private_data * priv,int feature)672 remoteConnectSupportsFeatureUnlocked(virConnectPtr conn,
673 struct private_data *priv,
674 int feature)
675 {
676 remote_connect_supports_feature_args args = { feature };
677 remote_connect_supports_feature_ret ret = { 0 };
678 int rc;
679
680 rc = call(conn, priv, 0, REMOTE_PROC_CONNECT_SUPPORTS_FEATURE,
681 (xdrproc_t)xdr_remote_connect_supports_feature_args, (char *) &args,
682 (xdrproc_t)xdr_remote_connect_supports_feature_ret, (char *) &ret);
683
684 return rc != -1 && ret.supported;
685 }
686
687 /* helper macro to ease extraction of arguments from the URI */
688 #define EXTRACT_URI_ARG_STR(ARG_NAME, ARG_VAR) \
689 if (STRCASEEQ(var->name, ARG_NAME)) { \
690 VIR_FREE(ARG_VAR); \
691 ARG_VAR = g_strdup(var->value); \
692 var->ignore = 1; \
693 continue; \
694 }
695
696 #define EXTRACT_URI_ARG_BOOL(ARG_NAME, ARG_VAR) \
697 if (STRCASEEQ(var->name, ARG_NAME)) { \
698 int tmp; \
699 if (virStrToLong_i(var->value, NULL, 10, &tmp) < 0) { \
700 virReportError(VIR_ERR_INVALID_ARG, \
701 _("Failed to parse value of URI component %s"), \
702 var->name); \
703 goto failed; \
704 } \
705 ARG_VAR = tmp == 0; \
706 var->ignore = 1; \
707 continue; \
708 }
709
710
711 /*
712 * URIs that this driver needs to handle:
713 *
714 * The easy answer:
715 * - Everything that no one else has yet claimed, but nothing if
716 * we're inside the libvirtd daemon
717 *
718 * The hard answer:
719 * - Plain paths (///var/lib/xen/xend-socket) -> UNIX domain socket
720 * - xxx://servername/ -> TLS connection
721 * - xxx+tls://servername/ -> TLS connection
722 * - xxx+tls:/// -> TLS connection to localhost
723 * - xxx+tcp://servername/ -> TCP connection
724 * - xxx+tcp:/// -> TCP connection to localhost
725 * - xxx+unix:/// -> UNIX domain socket
726 * - xxx:/// -> UNIX domain socket
727 * - xxx+ssh:/// -> SSH connection (legacy)
728 * - xxx+libssh2:/// -> SSH connection (using libssh2)
729 * - xxx+libssh:/// -> SSH connection (using libssh)
730 */
731 static int
doRemoteOpen(virConnectPtr conn,struct private_data * priv,const char * driver_str,remoteDriverTransport transport,virConnectAuthPtr auth G_GNUC_UNUSED,virConf * conf,unsigned int flags)732 doRemoteOpen(virConnectPtr conn,
733 struct private_data *priv,
734 const char *driver_str,
735 remoteDriverTransport transport,
736 virConnectAuthPtr auth G_GNUC_UNUSED,
737 virConf *conf,
738 unsigned int flags)
739 {
740 g_autofree char *tls_priority = NULL;
741 g_autofree char *name = NULL;
742 g_autofree char *command = NULL;
743 g_autofree char *sockname = NULL;
744 g_autofree char *netcat = NULL;
745 g_autofree char *port = NULL;
746 g_autofree char *authtype = NULL;
747 g_autofree char *username = NULL;
748 g_autofree char *pkipath = NULL;
749 g_autofree char *keyfile = NULL;
750 g_autofree char *sshauth = NULL;
751 g_autofree char *knownHostsVerify = NULL;
752 g_autofree char *knownHosts = NULL;
753 g_autofree char *mode_str = NULL;
754 g_autofree char *daemon_path = NULL;
755 g_autofree char *proxy_str = NULL;
756 bool sanity = true;
757 bool verify = true;
758 #ifndef WIN32
759 bool tty = true;
760 #endif
761 int mode;
762 size_t i;
763 int proxy;
764
765 /* We handle *ALL* URIs here. The caller has rejected any
766 * URIs we don't care about */
767
768 /* Remote server defaults to "localhost" if not specified. */
769 if (conn->uri && conn->uri->port != 0) {
770 port = g_strdup_printf("%d", conn->uri->port);
771 } else if (transport == REMOTE_DRIVER_TRANSPORT_TLS) {
772 port = g_strdup(LIBVIRTD_TLS_PORT);
773 } else if (transport == REMOTE_DRIVER_TRANSPORT_TCP) {
774 port = g_strdup(LIBVIRTD_TCP_PORT);
775 } /* Port not used for unix, ext., default for ssh */
776
777 priv->hostname = g_strdup(conn->uri && conn->uri->server ? conn->uri->server : "localhost");
778
779 if (conn->uri)
780 username = g_strdup(conn->uri->user);
781
782 /* Get the variables from the query string.
783 * Then we need to reconstruct the query string (because
784 * feasibly it might contain variables needed by the real driver,
785 * although that won't be the case for now).
786 */
787 if (conn->uri) {
788 for (i = 0; i < conn->uri->paramsCount; i++) {
789 virURIParam *var = &conn->uri->params[i];
790 EXTRACT_URI_ARG_STR("name", name);
791 EXTRACT_URI_ARG_STR("command", command);
792 EXTRACT_URI_ARG_STR("socket", sockname);
793 EXTRACT_URI_ARG_STR("auth", authtype);
794 EXTRACT_URI_ARG_STR("sshauth", sshauth);
795 EXTRACT_URI_ARG_STR("netcat", netcat);
796 EXTRACT_URI_ARG_STR("keyfile", keyfile);
797 EXTRACT_URI_ARG_STR("pkipath", pkipath);
798 EXTRACT_URI_ARG_STR("known_hosts", knownHosts);
799 EXTRACT_URI_ARG_STR("known_hosts_verify", knownHostsVerify);
800 EXTRACT_URI_ARG_STR("tls_priority", tls_priority);
801 EXTRACT_URI_ARG_STR("mode", mode_str);
802 EXTRACT_URI_ARG_STR("proxy", proxy_str);
803 EXTRACT_URI_ARG_BOOL("no_sanity", sanity);
804 EXTRACT_URI_ARG_BOOL("no_verify", verify);
805 #ifndef WIN32
806 EXTRACT_URI_ARG_BOOL("no_tty", tty);
807 #endif
808
809 if (STRCASEEQ(var->name, "authfile")) {
810 /* Strip this param, used by virauth.c */
811 var->ignore = 1;
812 continue;
813 }
814
815 VIR_DEBUG("passing through variable '%s' ('%s') to remote end",
816 var->name, var->value);
817 }
818
819 /* Construct the original name. */
820 if (!name) {
821 if (conn->uri->scheme &&
822 (STREQ(conn->uri->scheme, "remote") ||
823 STRPREFIX(conn->uri->scheme, "remote+"))) {
824 /* Allow remote serve to probe */
825 name = g_strdup("");
826 } else {
827 virURI tmpuri = {
828 .scheme = (char *)driver_str,
829 .query = virURIFormatParams(conn->uri),
830 .path = conn->uri->path,
831 .fragment = conn->uri->fragment,
832 };
833
834 name = virURIFormat(&tmpuri);
835
836 VIR_FREE(tmpuri.query);
837
838 if (!name)
839 goto failed;
840 }
841 }
842 } else {
843 /* Probe URI server side */
844 name = g_strdup("");
845 }
846
847 if (conf && !mode_str &&
848 virConfGetValueString(conf, "remote_mode", &mode_str) < 0)
849 goto failed;
850
851 if (mode_str) {
852 if ((mode = remoteDriverModeTypeFromString(mode_str)) < 0) {
853 virReportError(VIR_ERR_INVALID_ARG,
854 _("Unknown remote mode '%s'"), mode_str);
855 goto failed;
856 }
857 } else {
858 if (inside_daemon && !conn->uri->server) {
859 mode = REMOTE_DRIVER_MODE_DIRECT;
860 } else {
861 mode = REMOTE_DRIVER_MODE_AUTO;
862 }
863 }
864
865 if (conf && !proxy_str &&
866 virConfGetValueString(conf, "remote_proxy", &proxy_str) < 0)
867 goto failed;
868
869 if (proxy_str) {
870 if ((proxy = virNetClientProxyTypeFromString(proxy_str)) < 0) {
871 virReportError(VIR_ERR_INVALID_ARG,
872 _("Unnkown proxy type '%s'"), proxy_str);
873 goto failed;
874 }
875 } else {
876 /*
877 * Goal is to maximise usage of virt-ssh-helper
878 *
879 * Historically tunnelling access for the session mode
880 * daemon did not automatically work, since we can't
881 * construct the accurate path remotely. Users could,
882 * however, specify the 'socket' URI parameter explicitly.
883 *
884 * If we see a 'socket' path we must always use netcat,
885 * since virt-ssh-helper won't handle an explicit socket.
886 * Autostart won't work for session mode, so we assume
887 * user started it manually on the remote host in this
888 * case.
889 *
890 * If we have a 'session' URI without explicit socket,
891 * we can just assume the use of virt-ssh-helper, since
892 * logic for constructing socket paths relies on env
893 * envs whose values have no guarantee of matching those
894 * on the remote host. It was explicitly blocked with an
895 * error check before virt-ssh-helper was introduced.
896 *
897 * For 'system' URIs, we need to try virt-ssh-helper but
898 * with fallback to netcat for back compat.
899 */
900 if (sockname)
901 proxy = VIR_NET_CLIENT_PROXY_NETCAT;
902 else if (flags & REMOTE_DRIVER_OPEN_USER)
903 proxy = VIR_NET_CLIENT_PROXY_NATIVE;
904 else
905 proxy = VIR_NET_CLIENT_PROXY_AUTO;
906 }
907
908 /* Sanity check that nothing requested !direct mode by mistake */
909 if (inside_daemon && !conn->uri->server && mode != REMOTE_DRIVER_MODE_DIRECT) {
910 virReportError(VIR_ERR_INVALID_ARG, "%s",
911 _("Connections from inside daemon must be direct"));
912 return VIR_DRV_OPEN_ERROR;
913 }
914
915 VIR_DEBUG("proceeding with name = %s", name);
916
917 /* For ext transport, command is required. */
918 if (transport == REMOTE_DRIVER_TRANSPORT_EXT && !command) {
919 virReportError(VIR_ERR_INVALID_ARG, "%s",
920 _("remote_open: for 'ext' transport, command is required"));
921 goto failed;
922 }
923
924 VIR_DEBUG("Connecting with transport %d", transport);
925
926 switch ((remoteDriverTransport)transport) {
927 case REMOTE_DRIVER_TRANSPORT_UNIX:
928 case REMOTE_DRIVER_TRANSPORT_SSH:
929 case REMOTE_DRIVER_TRANSPORT_LIBSSH:
930 case REMOTE_DRIVER_TRANSPORT_LIBSSH2:
931 if (!sockname &&
932 !(sockname = remoteGetUNIXSocket(transport, mode, driver_str,
933 flags, &daemon_path)))
934 goto failed;
935 break;
936
937 case REMOTE_DRIVER_TRANSPORT_TCP:
938 case REMOTE_DRIVER_TRANSPORT_TLS:
939 case REMOTE_DRIVER_TRANSPORT_EXT:
940 break;
941
942 case REMOTE_DRIVER_TRANSPORT_LAST:
943 default:
944 virReportEnumRangeError(remoteDriverTransport, transport);
945 goto failed;
946 }
947
948 VIR_DEBUG("Chosen UNIX socket %s", NULLSTR(sockname));
949
950 /* Connect to the remote service. */
951 switch ((remoteDriverTransport)transport) {
952 case REMOTE_DRIVER_TRANSPORT_TLS:
953 if (conf && !tls_priority &&
954 virConfGetValueString(conf, "tls_priority", &tls_priority) < 0)
955 goto failed;
956
957 priv->tls = virNetTLSContextNewClientPath(pkipath,
958 geteuid() != 0,
959 tls_priority,
960 sanity, verify);
961 if (!priv->tls)
962 goto failed;
963 priv->is_secure = 1;
964 G_GNUC_FALLTHROUGH;
965
966 case REMOTE_DRIVER_TRANSPORT_TCP:
967 priv->client = virNetClientNewTCP(priv->hostname, port, AF_UNSPEC);
968 if (!priv->client)
969 goto failed;
970
971 if (priv->tls) {
972 VIR_DEBUG("Starting TLS session");
973 if (virNetClientSetTLSSession(priv->client, priv->tls) < 0)
974 goto failed;
975 }
976
977 break;
978
979 case REMOTE_DRIVER_TRANSPORT_LIBSSH2:
980 VIR_DEBUG("Starting LibSSH2 session");
981
982 priv->client = virNetClientNewLibSSH2(priv->hostname,
983 port,
984 AF_UNSPEC,
985 username,
986 keyfile,
987 knownHosts,
988 knownHostsVerify,
989 sshauth,
990 proxy,
991 netcat,
992 sockname,
993 name,
994 flags & REMOTE_DRIVER_OPEN_RO,
995 auth,
996 conn->uri);
997 if (!priv->client)
998 goto failed;
999
1000 priv->is_secure = 1;
1001 break;
1002
1003 case REMOTE_DRIVER_TRANSPORT_LIBSSH:
1004 VIR_DEBUG("Starting libssh session");
1005
1006 priv->client = virNetClientNewLibssh(priv->hostname,
1007 port,
1008 AF_UNSPEC,
1009 username,
1010 keyfile,
1011 knownHosts,
1012 knownHostsVerify,
1013 sshauth,
1014 proxy,
1015 netcat,
1016 sockname,
1017 name,
1018 flags & REMOTE_DRIVER_OPEN_RO,
1019 auth,
1020 conn->uri);
1021 if (!priv->client)
1022 goto failed;
1023
1024 priv->is_secure = 1;
1025 break;
1026
1027 #ifndef WIN32
1028 case REMOTE_DRIVER_TRANSPORT_UNIX:
1029 if (!(priv->client = virNetClientNewUNIX(sockname,
1030 daemon_path)))
1031 goto failed;
1032
1033 priv->is_secure = 1;
1034 break;
1035
1036 case REMOTE_DRIVER_TRANSPORT_SSH:
1037 if (!command)
1038 command = g_strdup("ssh");
1039
1040 if (!(priv->client = virNetClientNewSSH(priv->hostname,
1041 port,
1042 command,
1043 username,
1044 !tty,
1045 !verify,
1046 keyfile,
1047 proxy,
1048 netcat,
1049 sockname,
1050 name,
1051 flags & REMOTE_DRIVER_OPEN_RO)))
1052 goto failed;
1053
1054 priv->is_secure = 1;
1055 break;
1056
1057 case REMOTE_DRIVER_TRANSPORT_EXT: {
1058 char const *cmd_argv[] = { command, NULL };
1059 if (!(priv->client = virNetClientNewExternal(cmd_argv)))
1060 goto failed;
1061
1062 /* Do not set 'is_secure' flag since we can't guarantee
1063 * an external program is secure, and this flag must be
1064 * pessimistic */
1065 } break;
1066
1067 #else /* WIN32 */
1068
1069 case REMOTE_DRIVER_TRANSPORT_UNIX:
1070 case REMOTE_DRIVER_TRANSPORT_SSH:
1071 case REMOTE_DRIVER_TRANSPORT_EXT:
1072 virReportError(VIR_ERR_INVALID_ARG, "%s",
1073 _("transport methods unix, ssh and ext are not supported "
1074 "under Windows"));
1075 goto failed;
1076
1077 #endif /* WIN32 */
1078
1079 case REMOTE_DRIVER_TRANSPORT_LAST:
1080 default:
1081 virReportEnumRangeError(remoteDriverTransport, transport);
1082 goto failed;
1083 } /* switch (transport) */
1084
1085
1086 if (virNetClientRegisterAsyncIO(priv->client) < 0) {
1087 VIR_DEBUG("Failed to add event watch, disabling events and support for"
1088 " keepalive messages");
1089 virResetLastError();
1090 } else {
1091 if (virNetClientRegisterKeepAlive(priv->client) < 0)
1092 goto failed;
1093 }
1094
1095 if (!(priv->closeCallback = virNewConnectCloseCallbackData()))
1096 goto failed;
1097 /* ref on behalf of netclient */
1098 virObjectRef(priv->closeCallback);
1099 virNetClientSetCloseCallback(priv->client,
1100 remoteClientCloseFunc,
1101 priv->closeCallback, virObjectFreeCallback);
1102
1103 if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM,
1104 REMOTE_PROTOCOL_VERSION,
1105 remoteEvents,
1106 G_N_ELEMENTS(remoteEvents),
1107 conn)))
1108 goto failed;
1109 if (!(priv->lxcProgram = virNetClientProgramNew(LXC_PROGRAM,
1110 LXC_PROTOCOL_VERSION,
1111 NULL,
1112 0,
1113 NULL)))
1114 goto failed;
1115 if (!(priv->qemuProgram = virNetClientProgramNew(QEMU_PROGRAM,
1116 QEMU_PROTOCOL_VERSION,
1117 qemuEvents,
1118 G_N_ELEMENTS(qemuEvents),
1119 conn)))
1120 goto failed;
1121
1122 if (virNetClientAddProgram(priv->client, priv->remoteProgram) < 0 ||
1123 virNetClientAddProgram(priv->client, priv->lxcProgram) < 0 ||
1124 virNetClientAddProgram(priv->client, priv->qemuProgram) < 0)
1125 goto failed;
1126
1127 /* Try and authenticate with server */
1128 VIR_DEBUG("Trying authentication");
1129 if (remoteAuthenticate(conn, priv, auth, authtype) == -1)
1130 goto failed;
1131
1132 if (virNetClientKeepAliveIsSupported(priv->client)) {
1133 priv->serverKeepAlive = remoteConnectSupportsFeatureUnlocked(conn,
1134 priv, VIR_DRV_FEATURE_PROGRAM_KEEPALIVE);
1135 if (!priv->serverKeepAlive) {
1136 VIR_INFO("Disabling keepalive protocol since it is not supported"
1137 " by the server");
1138 }
1139 }
1140
1141 /* Finally we can call the remote side's open function. */
1142 {
1143 remote_connect_open_args args = { &name, flags };
1144
1145 VIR_DEBUG("Trying to open URI '%s'", name);
1146 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_OPEN,
1147 (xdrproc_t) xdr_remote_connect_open_args, (char *) &args,
1148 (xdrproc_t) xdr_void, (char *) NULL) == -1)
1149 goto failed;
1150 }
1151
1152 /* Now try and find out what URI the daemon used */
1153 if (conn->uri == NULL) {
1154 remote_connect_get_uri_ret uriret;
1155
1156 VIR_DEBUG("Trying to query remote URI");
1157 memset(&uriret, 0, sizeof(uriret));
1158 if (call(conn, priv, 0,
1159 REMOTE_PROC_CONNECT_GET_URI,
1160 (xdrproc_t) xdr_void, (char *) NULL,
1161 (xdrproc_t) xdr_remote_connect_get_uri_ret, (char *) &uriret) < 0)
1162 goto failed;
1163
1164 VIR_DEBUG("Auto-probed URI is %s", uriret.uri);
1165 conn->uri = virURIParse(uriret.uri);
1166 VIR_FREE(uriret.uri);
1167 if (!conn->uri)
1168 goto failed;
1169 }
1170
1171 /* Set up events */
1172 if (!(priv->eventState = virObjectEventStateNew()))
1173 goto failed;
1174
1175 priv->serverEventFilter = remoteConnectSupportsFeatureUnlocked(conn,
1176 priv, VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK);
1177 if (!priv->serverEventFilter) {
1178 VIR_INFO("Avoiding server event filtering since it is not "
1179 "supported by the server");
1180 }
1181
1182 priv->serverCloseCallback = remoteConnectSupportsFeatureUnlocked(conn,
1183 priv, VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK);
1184 if (!priv->serverCloseCallback) {
1185 VIR_INFO("Close callback registering isn't supported "
1186 "by the remote side.");
1187 }
1188
1189 return VIR_DRV_OPEN_SUCCESS;
1190
1191 failed:
1192 virObjectUnref(priv->remoteProgram);
1193 virObjectUnref(priv->lxcProgram);
1194 virObjectUnref(priv->qemuProgram);
1195 virNetClientClose(priv->client);
1196 virObjectUnref(priv->client);
1197 priv->client = NULL;
1198 virObjectUnref(priv->closeCallback);
1199 priv->closeCallback = NULL;
1200 virObjectUnref(priv->tls);
1201 priv->tls = NULL;
1202
1203 VIR_FREE(priv->hostname);
1204 return VIR_DRV_OPEN_ERROR;
1205 }
1206 #undef EXTRACT_URI_ARG_STR
1207 #undef EXTRACT_URI_ARG_BOOL
1208
1209 static struct private_data *
remoteAllocPrivateData(void)1210 remoteAllocPrivateData(void)
1211 {
1212 struct private_data *priv;
1213 priv = g_new0(struct private_data, 1);
1214
1215 if (virMutexInit(&priv->lock) < 0) {
1216 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1217 _("cannot initialize mutex"));
1218 VIR_FREE(priv);
1219 return NULL;
1220 }
1221 remoteDriverLock(priv);
1222 priv->localUses = 1;
1223
1224 return priv;
1225 }
1226
1227 static virDrvOpenStatus
remoteConnectOpen(virConnectPtr conn,virConnectAuthPtr auth,virConf * conf,unsigned int flags)1228 remoteConnectOpen(virConnectPtr conn,
1229 virConnectAuthPtr auth,
1230 virConf *conf,
1231 unsigned int flags)
1232 {
1233 struct private_data *priv;
1234 int ret = VIR_DRV_OPEN_ERROR;
1235 unsigned int rflags = 0;
1236 char *driver = NULL;
1237 remoteDriverTransport transport;
1238
1239 if (conn->uri) {
1240 if (remoteSplitURIScheme(conn->uri, &driver, &transport) < 0)
1241 goto cleanup;
1242 } else {
1243 /* No URI, then must be probing so use UNIX socket */
1244 transport = REMOTE_DRIVER_TRANSPORT_UNIX;
1245 }
1246
1247
1248 if (inside_daemon) {
1249 if (!conn->uri) {
1250 ret = VIR_DRV_OPEN_DECLINED;
1251 goto cleanup;
1252 }
1253
1254 /* If there's a driver registered we must defer to that.
1255 * If there isn't a driver, we must connect in "direct"
1256 * mode - see doRemoteOpen.
1257 * One exception is if we are trying to connect to an
1258 * unknown socket path as that might be proxied to remote
1259 * host */
1260 if (!conn->uri->server &&
1261 virHasDriverForURIScheme(driver) &&
1262 !virURICheckUnixSocket(conn->uri)) {
1263 ret = VIR_DRV_OPEN_DECLINED;
1264 goto cleanup;
1265 }
1266 }
1267
1268 if (!(priv = remoteAllocPrivateData()))
1269 goto cleanup;
1270
1271
1272 remoteGetURIDaemonInfo(conn->uri, transport, &rflags);
1273 if (flags & VIR_CONNECT_RO)
1274 rflags |= REMOTE_DRIVER_OPEN_RO;
1275
1276 ret = doRemoteOpen(conn, priv, driver, transport, auth, conf, rflags);
1277 if (ret != VIR_DRV_OPEN_SUCCESS) {
1278 conn->privateData = NULL;
1279 remoteDriverUnlock(priv);
1280 VIR_FREE(priv);
1281 } else {
1282 conn->privateData = priv;
1283 remoteDriverUnlock(priv);
1284 }
1285
1286 cleanup:
1287 VIR_FREE(driver);
1288 return ret;
1289 }
1290
1291
1292 /*----------------------------------------------------------------------*/
1293
1294
1295 static int
doRemoteClose(virConnectPtr conn,struct private_data * priv)1296 doRemoteClose(virConnectPtr conn, struct private_data *priv)
1297 {
1298 int ret = 0;
1299
1300 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_CLOSE,
1301 (xdrproc_t) xdr_void, (char *) NULL,
1302 (xdrproc_t) xdr_void, (char *) NULL) == -1)
1303 ret = -1;
1304
1305 virObjectUnref(priv->tls);
1306 priv->tls = NULL;
1307
1308 virNetClientSetCloseCallback(priv->client,
1309 NULL,
1310 priv->closeCallback, virObjectFreeCallback);
1311
1312 virNetClientClose(priv->client);
1313 virObjectUnref(priv->client);
1314 priv->client = NULL;
1315 virObjectUnref(priv->closeCallback);
1316 priv->closeCallback = NULL;
1317 virObjectUnref(priv->remoteProgram);
1318 virObjectUnref(priv->lxcProgram);
1319 virObjectUnref(priv->qemuProgram);
1320 priv->remoteProgram = priv->qemuProgram = priv->lxcProgram = NULL;
1321
1322 /* Free hostname copy */
1323 VIR_FREE(priv->hostname);
1324
1325 /* See comment for remoteType. */
1326 VIR_FREE(priv->type);
1327
1328 virObjectUnref(priv->eventState);
1329 priv->eventState = NULL;
1330
1331 return ret;
1332 }
1333
1334 static int
remoteConnectClose(virConnectPtr conn)1335 remoteConnectClose(virConnectPtr conn)
1336 {
1337 int ret = 0;
1338 struct private_data *priv = conn->privateData;
1339
1340 remoteDriverLock(priv);
1341 priv->localUses--;
1342 if (!priv->localUses) {
1343 ret = doRemoteClose(conn, priv);
1344 conn->privateData = NULL;
1345 remoteDriverUnlock(priv);
1346 virMutexDestroy(&priv->lock);
1347 VIR_FREE(priv);
1348 }
1349 if (priv)
1350 remoteDriverUnlock(priv);
1351
1352 return ret;
1353 }
1354
1355
1356 /* Unfortunately this function is defined to return a static string.
1357 * Since the remote end always answers with the same type (for a
1358 * single connection anyway) we cache the type in the connection's
1359 * private data, and free it when we close the connection.
1360 *
1361 * See also:
1362 * https://www.redhat.com/archives/libvir-list/2007-February/msg00096.html
1363 */
1364 static const char *
remoteConnectGetType(virConnectPtr conn)1365 remoteConnectGetType(virConnectPtr conn)
1366 {
1367 char *rv = NULL;
1368 remote_connect_get_type_ret ret;
1369 struct private_data *priv = conn->privateData;
1370
1371 remoteDriverLock(priv);
1372
1373 /* Cached? */
1374 if (priv->type) {
1375 rv = priv->type;
1376 goto done;
1377 }
1378
1379 memset(&ret, 0, sizeof(ret));
1380 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_TYPE,
1381 (xdrproc_t) xdr_void, (char *) NULL,
1382 (xdrproc_t) xdr_remote_connect_get_type_ret, (char *) &ret) == -1)
1383 goto done;
1384
1385 /* Stash. */
1386 rv = priv->type = ret.type;
1387
1388 done:
1389 remoteDriverUnlock(priv);
1390 return rv;
1391 }
1392
remoteConnectIsSecure(virConnectPtr conn)1393 static int remoteConnectIsSecure(virConnectPtr conn)
1394 {
1395 int rv = -1;
1396 struct private_data *priv = conn->privateData;
1397 remote_connect_is_secure_ret ret;
1398 remoteDriverLock(priv);
1399
1400 memset(&ret, 0, sizeof(ret));
1401 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_IS_SECURE,
1402 (xdrproc_t) xdr_void, (char *) NULL,
1403 (xdrproc_t) xdr_remote_connect_is_secure_ret, (char *) &ret) == -1)
1404 goto done;
1405
1406 /* We claim to be secure, if the remote driver
1407 * transport itself is secure, and the remote
1408 * HV connection is secure
1409 *
1410 * ie, we don't want to claim to be secure if the
1411 * remote driver is used to connect to a XenD
1412 * driver using unencrypted HTTP:/// access
1413 */
1414 rv = priv->is_secure && ret.secure ? 1 : 0;
1415
1416 done:
1417 remoteDriverUnlock(priv);
1418 return rv;
1419 }
1420
remoteConnectIsEncrypted(virConnectPtr conn)1421 static int remoteConnectIsEncrypted(virConnectPtr conn)
1422 {
1423 int rv = -1;
1424 bool encrypted;
1425 struct private_data *priv = conn->privateData;
1426 remote_connect_is_secure_ret ret;
1427 remoteDriverLock(priv);
1428
1429 memset(&ret, 0, sizeof(ret));
1430 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_IS_SECURE,
1431 (xdrproc_t) xdr_void, (char *) NULL,
1432 (xdrproc_t) xdr_remote_connect_is_secure_ret, (char *) &ret) == -1)
1433 goto done;
1434
1435 encrypted = virNetClientIsEncrypted(priv->client);
1436
1437 /* We claim to be encrypted, if the remote driver
1438 * transport itself is encrypted, and the remote
1439 * HV connection is secure.
1440 *
1441 * Yes, we really don't check the remote 'encrypted'
1442 * option, since it will almost always be false,
1443 * even if secure (eg UNIX sockets).
1444 */
1445 rv = encrypted && ret.secure ? 1 : 0;
1446
1447 done:
1448 remoteDriverUnlock(priv);
1449 return rv;
1450 }
1451
1452 static int
remoteNodeGetCPUStats(virConnectPtr conn,int cpuNum,virNodeCPUStatsPtr params,int * nparams,unsigned int flags)1453 remoteNodeGetCPUStats(virConnectPtr conn,
1454 int cpuNum,
1455 virNodeCPUStatsPtr params, int *nparams,
1456 unsigned int flags)
1457 {
1458 int rv = -1;
1459 remote_node_get_cpu_stats_args args;
1460 remote_node_get_cpu_stats_ret ret;
1461 size_t i;
1462 struct private_data *priv = conn->privateData;
1463
1464 remoteDriverLock(priv);
1465
1466 args.nparams = *nparams;
1467 args.cpuNum = cpuNum;
1468 args.flags = flags;
1469
1470 memset(&ret, 0, sizeof(ret));
1471 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_CPU_STATS,
1472 (xdrproc_t) xdr_remote_node_get_cpu_stats_args,
1473 (char *) &args,
1474 (xdrproc_t) xdr_remote_node_get_cpu_stats_ret,
1475 (char *) &ret) == -1)
1476 goto done;
1477
1478 /* Check the length of the returned list carefully. */
1479 if (ret.params.params_len > REMOTE_NODE_CPU_STATS_MAX ||
1480 ret.params.params_len > *nparams) {
1481 virReportError(VIR_ERR_RPC, "%s",
1482 _("remoteNodeGetCPUStats: "
1483 "returned number of stats exceeds limit"));
1484 goto cleanup;
1485 }
1486 /* Handle the case when the caller does not know the number of stats
1487 * and is asking for the number of stats supported
1488 */
1489 if (*nparams == 0) {
1490 *nparams = ret.nparams;
1491 rv = 0;
1492 goto cleanup;
1493 }
1494
1495 *nparams = ret.params.params_len;
1496
1497 /* Deserialise the result. */
1498 for (i = 0; i < *nparams; ++i) {
1499 if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) < 0) {
1500 virReportError(VIR_ERR_INTERNAL_ERROR,
1501 _("Stats %s too big for destination"),
1502 ret.params.params_val[i].field);
1503 goto cleanup;
1504 }
1505 params[i].value = ret.params.params_val[i].value;
1506 }
1507
1508 rv = 0;
1509
1510 cleanup:
1511 xdr_free((xdrproc_t) xdr_remote_node_get_cpu_stats_ret, (char *) &ret);
1512 done:
1513 remoteDriverUnlock(priv);
1514 return rv;
1515 }
1516
1517 static int
remoteNodeGetMemoryStats(virConnectPtr conn,int cellNum,virNodeMemoryStatsPtr params,int * nparams,unsigned int flags)1518 remoteNodeGetMemoryStats(virConnectPtr conn,
1519 int cellNum,
1520 virNodeMemoryStatsPtr params,
1521 int *nparams,
1522 unsigned int flags)
1523 {
1524 int rv = -1;
1525 remote_node_get_memory_stats_args args;
1526 remote_node_get_memory_stats_ret ret;
1527 size_t i;
1528 struct private_data *priv = conn->privateData;
1529
1530 remoteDriverLock(priv);
1531
1532 args.nparams = *nparams;
1533 args.cellNum = cellNum;
1534 args.flags = flags;
1535
1536 memset(&ret, 0, sizeof(ret));
1537 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_MEMORY_STATS,
1538 (xdrproc_t) xdr_remote_node_get_memory_stats_args, (char *) &args,
1539 (xdrproc_t) xdr_remote_node_get_memory_stats_ret, (char *) &ret) == -1)
1540 goto done;
1541
1542 /* Check the length of the returned list carefully. */
1543 if (ret.params.params_len > REMOTE_NODE_MEMORY_STATS_MAX ||
1544 ret.params.params_len > *nparams) {
1545 virReportError(VIR_ERR_RPC, "%s",
1546 _("remoteNodeGetMemoryStats: "
1547 "returned number of stats exceeds limit"));
1548 goto cleanup;
1549 }
1550 /* Handle the case when the caller does not know the number of stats
1551 * and is asking for the number of stats supported
1552 */
1553 if (*nparams == 0) {
1554 *nparams = ret.nparams;
1555 rv = 0;
1556 goto cleanup;
1557 }
1558
1559 *nparams = ret.params.params_len;
1560
1561 /* Deserialise the result. */
1562 for (i = 0; i < *nparams; ++i) {
1563 if (virStrcpyStatic(params[i].field, ret.params.params_val[i].field) < 0) {
1564 virReportError(VIR_ERR_INTERNAL_ERROR,
1565 _("Stats %s too big for destination"),
1566 ret.params.params_val[i].field);
1567 goto cleanup;
1568 }
1569 params[i].value = ret.params.params_val[i].value;
1570 }
1571
1572 rv = 0;
1573
1574 cleanup:
1575 xdr_free((xdrproc_t) xdr_remote_node_get_memory_stats_ret, (char *) &ret);
1576 done:
1577 remoteDriverUnlock(priv);
1578 return rv;
1579 }
1580
1581 static int
remoteNodeGetCellsFreeMemory(virConnectPtr conn,unsigned long long * freeMems,int startCell,int maxCells)1582 remoteNodeGetCellsFreeMemory(virConnectPtr conn,
1583 unsigned long long *freeMems,
1584 int startCell,
1585 int maxCells)
1586 {
1587 int rv = -1;
1588 remote_node_get_cells_free_memory_args args;
1589 remote_node_get_cells_free_memory_ret ret;
1590 size_t i;
1591 struct private_data *priv = conn->privateData;
1592
1593 remoteDriverLock(priv);
1594
1595 if (maxCells > REMOTE_NODE_MAX_CELLS) {
1596 virReportError(VIR_ERR_RPC,
1597 _("too many NUMA cells: %d > %d"),
1598 maxCells, REMOTE_NODE_MAX_CELLS);
1599 goto done;
1600 }
1601
1602 args.startCell = startCell;
1603 args.maxcells = maxCells;
1604
1605 memset(&ret, 0, sizeof(ret));
1606 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_CELLS_FREE_MEMORY,
1607 (xdrproc_t) xdr_remote_node_get_cells_free_memory_args, (char *)&args,
1608 (xdrproc_t) xdr_remote_node_get_cells_free_memory_ret, (char *)&ret) == -1)
1609 goto done;
1610
1611 for (i = 0; i < ret.cells.cells_len; i++)
1612 freeMems[i] = ret.cells.cells_val[i];
1613
1614 xdr_free((xdrproc_t) xdr_remote_node_get_cells_free_memory_ret, (char *) &ret);
1615
1616 rv = ret.cells.cells_len;
1617
1618 done:
1619 remoteDriverUnlock(priv);
1620 return rv;
1621 }
1622
1623 static int
remoteConnectListDomains(virConnectPtr conn,int * ids,int maxids)1624 remoteConnectListDomains(virConnectPtr conn, int *ids, int maxids)
1625 {
1626 int rv = -1;
1627 size_t i;
1628 remote_connect_list_domains_args args;
1629 remote_connect_list_domains_ret ret;
1630 struct private_data *priv = conn->privateData;
1631
1632 remoteDriverLock(priv);
1633
1634 if (maxids > REMOTE_DOMAIN_LIST_MAX) {
1635 virReportError(VIR_ERR_RPC,
1636 _("Too many domains '%d' for limit '%d'"),
1637 maxids, REMOTE_DOMAIN_LIST_MAX);
1638 goto done;
1639 }
1640 args.maxids = maxids;
1641
1642 memset(&ret, 0, sizeof(ret));
1643 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_LIST_DOMAINS,
1644 (xdrproc_t) xdr_remote_connect_list_domains_args, (char *) &args,
1645 (xdrproc_t) xdr_remote_connect_list_domains_ret, (char *) &ret) == -1)
1646 goto done;
1647
1648 if (ret.ids.ids_len > maxids) {
1649 virReportError(VIR_ERR_RPC,
1650 _("Too many domains '%d' for limit '%d'"),
1651 ret.ids.ids_len, maxids);
1652 goto cleanup;
1653 }
1654
1655 for (i = 0; i < ret.ids.ids_len; ++i)
1656 ids[i] = ret.ids.ids_val[i];
1657
1658 rv = ret.ids.ids_len;
1659
1660 cleanup:
1661 xdr_free((xdrproc_t) xdr_remote_connect_list_domains_ret, (char *) &ret);
1662
1663 done:
1664 remoteDriverUnlock(priv);
1665 return rv;
1666 }
1667
1668 static int
remoteDeserializeDomainDiskErrors(remote_domain_disk_error * ret_errors_val,u_int ret_errors_len,int limit,virDomainDiskErrorPtr errors,int maxerrors)1669 remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val,
1670 u_int ret_errors_len,
1671 int limit,
1672 virDomainDiskErrorPtr errors,
1673 int maxerrors)
1674 {
1675 size_t i = 0;
1676 size_t j;
1677
1678 if (ret_errors_len > limit || ret_errors_len > maxerrors) {
1679 virReportError(VIR_ERR_RPC, "%s",
1680 _("returned number of disk errors exceeds limit"));
1681 goto error;
1682 }
1683
1684 for (i = 0; i < ret_errors_len; i++) {
1685 errors[i].disk = g_strdup(ret_errors_val[i].disk);
1686 errors[i].error = ret_errors_val[i].error;
1687 }
1688
1689 return 0;
1690
1691 error:
1692 for (j = 0; j < i; j++)
1693 VIR_FREE(errors[j].disk);
1694
1695 return -1;
1696 }
1697
1698 static int
remoteDomainBlockStatsFlags(virDomainPtr domain,const char * path,virTypedParameterPtr params,int * nparams,unsigned int flags)1699 remoteDomainBlockStatsFlags(virDomainPtr domain,
1700 const char *path,
1701 virTypedParameterPtr params,
1702 int *nparams,
1703 unsigned int flags)
1704 {
1705 int rv = -1;
1706 remote_domain_block_stats_flags_args args;
1707 remote_domain_block_stats_flags_ret ret;
1708 struct private_data *priv = domain->conn->privateData;
1709
1710 remoteDriverLock(priv);
1711
1712 make_nonnull_domain(&args.dom, domain);
1713 args.nparams = *nparams;
1714 args.path = (char *) path;
1715 args.flags = flags;
1716
1717 memset(&ret, 0, sizeof(ret));
1718 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS,
1719 (xdrproc_t) xdr_remote_domain_block_stats_flags_args, (char *) &args,
1720 (xdrproc_t) xdr_remote_domain_block_stats_flags_ret, (char *) &ret) == -1)
1721 goto done;
1722
1723 /* Check the length of the returned list carefully. */
1724 if (ret.params.params_len > REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX ||
1725 ret.params.params_len > *nparams) {
1726 virReportError(VIR_ERR_RPC, "%s",
1727 _("remoteDomainBlockStatsFlags: "
1728 "returned number of stats exceeds limit"));
1729 goto cleanup;
1730 }
1731
1732 /* Handle the case when the caller does not know the number of stats
1733 * and is asking for the number of stats supported
1734 */
1735 if (*nparams == 0) {
1736 *nparams = ret.nparams;
1737 rv = 0;
1738 goto cleanup;
1739 }
1740
1741 *nparams = ret.params.params_len;
1742
1743 /* Deserialize the result. */
1744 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
1745 ret.params.params_len,
1746 REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX,
1747 ¶ms,
1748 nparams) < 0)
1749 goto cleanup;
1750
1751 rv = 0;
1752
1753 cleanup:
1754 xdr_free((xdrproc_t) xdr_remote_domain_block_stats_flags_ret,
1755 (char *) &ret);
1756 done:
1757 remoteDriverUnlock(priv);
1758 return rv;
1759 }
1760
1761 static int
remoteDomainGetMemoryParameters(virDomainPtr domain,virTypedParameterPtr params,int * nparams,unsigned int flags)1762 remoteDomainGetMemoryParameters(virDomainPtr domain,
1763 virTypedParameterPtr params, int *nparams,
1764 unsigned int flags)
1765 {
1766 int rv = -1;
1767 remote_domain_get_memory_parameters_args args;
1768 remote_domain_get_memory_parameters_ret ret;
1769 struct private_data *priv = domain->conn->privateData;
1770
1771 remoteDriverLock(priv);
1772
1773 make_nonnull_domain(&args.dom, domain);
1774 args.nparams = *nparams;
1775 args.flags = flags;
1776
1777 memset(&ret, 0, sizeof(ret));
1778 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS,
1779 (xdrproc_t) xdr_remote_domain_get_memory_parameters_args, (char *) &args,
1780 (xdrproc_t) xdr_remote_domain_get_memory_parameters_ret, (char *) &ret) == -1)
1781 goto done;
1782
1783 /* Handle the case when the caller does not know the number of parameters
1784 * and is asking for the number of parameters supported
1785 */
1786 if (*nparams == 0) {
1787 *nparams = ret.nparams;
1788 rv = 0;
1789 goto cleanup;
1790 }
1791
1792 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
1793 ret.params.params_len,
1794 REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
1795 ¶ms,
1796 nparams) < 0)
1797 goto cleanup;
1798
1799 rv = 0;
1800
1801 cleanup:
1802 xdr_free((xdrproc_t) xdr_remote_domain_get_memory_parameters_ret,
1803 (char *) &ret);
1804 done:
1805 remoteDriverUnlock(priv);
1806 return rv;
1807 }
1808
1809 static int
remoteDomainGetNumaParameters(virDomainPtr domain,virTypedParameterPtr params,int * nparams,unsigned int flags)1810 remoteDomainGetNumaParameters(virDomainPtr domain,
1811 virTypedParameterPtr params, int *nparams,
1812 unsigned int flags)
1813 {
1814 int rv = -1;
1815 remote_domain_get_numa_parameters_args args;
1816 remote_domain_get_numa_parameters_ret ret;
1817 struct private_data *priv = domain->conn->privateData;
1818
1819 remoteDriverLock(priv);
1820
1821 make_nonnull_domain(&args.dom, domain);
1822 args.nparams = *nparams;
1823 args.flags = flags;
1824
1825 memset(&ret, 0, sizeof(ret));
1826 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_NUMA_PARAMETERS,
1827 (xdrproc_t) xdr_remote_domain_get_numa_parameters_args, (char *) &args,
1828 (xdrproc_t) xdr_remote_domain_get_numa_parameters_ret, (char *) &ret) == -1)
1829 goto done;
1830
1831 /* Handle the case when the caller does not know the number of parameters
1832 * and is asking for the number of parameters supported
1833 */
1834 if (*nparams == 0) {
1835 *nparams = ret.nparams;
1836 rv = 0;
1837 goto cleanup;
1838 }
1839
1840 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
1841 ret.params.params_len,
1842 REMOTE_DOMAIN_NUMA_PARAMETERS_MAX,
1843 ¶ms,
1844 nparams) < 0)
1845 goto cleanup;
1846
1847 rv = 0;
1848
1849 cleanup:
1850 xdr_free((xdrproc_t) xdr_remote_domain_get_numa_parameters_ret,
1851 (char *) &ret);
1852 done:
1853 remoteDriverUnlock(priv);
1854 return rv;
1855 }
1856
1857 static int
remoteDomainGetLaunchSecurityInfo(virDomainPtr domain,virTypedParameterPtr * params,int * nparams,unsigned int flags)1858 remoteDomainGetLaunchSecurityInfo(virDomainPtr domain,
1859 virTypedParameterPtr *params,
1860 int *nparams,
1861 unsigned int flags)
1862 {
1863 int rv = -1;
1864 remote_domain_get_launch_security_info_args args;
1865 remote_domain_get_launch_security_info_ret ret;
1866 struct private_data *priv = domain->conn->privateData;
1867
1868 remoteDriverLock(priv);
1869
1870 make_nonnull_domain(&args.dom, domain);
1871 args.flags = flags;
1872
1873 memset(&ret, 0, sizeof(ret));
1874 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_LAUNCH_SECURITY_INFO,
1875 (xdrproc_t) xdr_remote_domain_get_launch_security_info_args, (char *) &args,
1876 (xdrproc_t) xdr_remote_domain_get_launch_security_info_ret, (char *) &ret) == -1)
1877 goto done;
1878
1879 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
1880 ret.params.params_len,
1881 REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX,
1882 params,
1883 nparams) < 0)
1884 goto cleanup;
1885
1886 rv = 0;
1887
1888 cleanup:
1889 xdr_free((xdrproc_t) xdr_remote_domain_get_launch_security_info_ret,
1890 (char *) &ret);
1891 done:
1892 remoteDriverUnlock(priv);
1893 return rv;
1894 }
1895
1896 static int
remoteDomainGetPerfEvents(virDomainPtr domain,virTypedParameterPtr * params,int * nparams,unsigned int flags)1897 remoteDomainGetPerfEvents(virDomainPtr domain,
1898 virTypedParameterPtr *params,
1899 int *nparams,
1900 unsigned int flags)
1901 {
1902 int rv = -1;
1903 remote_domain_get_perf_events_args args;
1904 remote_domain_get_perf_events_ret ret;
1905 struct private_data *priv = domain->conn->privateData;
1906
1907 remoteDriverLock(priv);
1908
1909 make_nonnull_domain(&args.dom, domain);
1910 args.flags = flags;
1911
1912 memset(&ret, 0, sizeof(ret));
1913 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_PERF_EVENTS,
1914 (xdrproc_t) xdr_remote_domain_get_perf_events_args, (char *) &args,
1915 (xdrproc_t) xdr_remote_domain_get_perf_events_ret, (char *) &ret) == -1)
1916 goto done;
1917
1918 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
1919 ret.params.params_len,
1920 REMOTE_DOMAIN_PERF_EVENTS_MAX,
1921 params,
1922 nparams) < 0)
1923 goto cleanup;
1924
1925 rv = 0;
1926
1927 cleanup:
1928 xdr_free((xdrproc_t) xdr_remote_domain_get_perf_events_ret,
1929 (char *) &ret);
1930 done:
1931 remoteDriverUnlock(priv);
1932 return rv;
1933 }
1934
1935 static int
remoteDomainGetBlkioParameters(virDomainPtr domain,virTypedParameterPtr params,int * nparams,unsigned int flags)1936 remoteDomainGetBlkioParameters(virDomainPtr domain,
1937 virTypedParameterPtr params, int *nparams,
1938 unsigned int flags)
1939 {
1940 int rv = -1;
1941 remote_domain_get_blkio_parameters_args args;
1942 remote_domain_get_blkio_parameters_ret ret;
1943 struct private_data *priv = domain->conn->privateData;
1944
1945 remoteDriverLock(priv);
1946
1947 make_nonnull_domain(&args.dom, domain);
1948 args.nparams = *nparams;
1949 args.flags = flags;
1950
1951 memset(&ret, 0, sizeof(ret));
1952 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS,
1953 (xdrproc_t) xdr_remote_domain_get_blkio_parameters_args, (char *) &args,
1954 (xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret, (char *) &ret) == -1)
1955 goto done;
1956
1957 /* Handle the case when the caller does not know the number of parameters
1958 * and is asking for the number of parameters supported
1959 */
1960 if (*nparams == 0) {
1961 *nparams = ret.nparams;
1962 rv = 0;
1963 goto cleanup;
1964 }
1965
1966 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
1967 ret.params.params_len,
1968 REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX,
1969 ¶ms,
1970 nparams) < 0)
1971 goto cleanup;
1972
1973 rv = 0;
1974
1975 cleanup:
1976 xdr_free((xdrproc_t) xdr_remote_domain_get_blkio_parameters_ret,
1977 (char *) &ret);
1978 done:
1979 remoteDriverUnlock(priv);
1980 return rv;
1981 }
1982
1983 static int
remoteDomainGetVcpuPinInfo(virDomainPtr domain,int ncpumaps,unsigned char * cpumaps,int maplen,unsigned int flags)1984 remoteDomainGetVcpuPinInfo(virDomainPtr domain,
1985 int ncpumaps,
1986 unsigned char *cpumaps,
1987 int maplen,
1988 unsigned int flags)
1989 {
1990 int rv = -1;
1991 size_t i;
1992 remote_domain_get_vcpu_pin_info_args args;
1993 remote_domain_get_vcpu_pin_info_ret ret;
1994 struct private_data *priv = domain->conn->privateData;
1995
1996 remoteDriverLock(priv);
1997
1998 if (ncpumaps > REMOTE_VCPUINFO_MAX) {
1999 virReportError(VIR_ERR_RPC,
2000 _("vCPU count exceeds maximum: %d > %d"),
2001 ncpumaps, REMOTE_VCPUINFO_MAX);
2002 goto done;
2003 }
2004
2005 if (VIR_INT_MULTIPLY_OVERFLOW(ncpumaps, maplen) ||
2006 ncpumaps * maplen > REMOTE_CPUMAPS_MAX) {
2007 virReportError(VIR_ERR_RPC,
2008 _("vCPU map buffer length exceeds maximum: %d > %d"),
2009 ncpumaps * maplen, REMOTE_CPUMAPS_MAX);
2010 goto done;
2011 }
2012
2013 make_nonnull_domain(&args.dom, domain);
2014 args.ncpumaps = ncpumaps;
2015 args.maplen = maplen;
2016 args.flags = flags;
2017
2018 memset(&ret, 0, sizeof(ret));
2019
2020 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO,
2021 (xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_args,
2022 (char *) &args,
2023 (xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_ret,
2024 (char *) &ret) == -1)
2025 goto done;
2026
2027 if (ret.num > ncpumaps) {
2028 virReportError(VIR_ERR_RPC,
2029 _("host reports too many vCPUs: %d > %d"),
2030 ret.num, ncpumaps);
2031 goto cleanup;
2032 }
2033
2034 if (ret.cpumaps.cpumaps_len > ncpumaps * maplen) {
2035 virReportError(VIR_ERR_RPC,
2036 _("host reports map buffer length exceeds maximum: %d > %d"),
2037 ret.cpumaps.cpumaps_len, ncpumaps * maplen);
2038 goto cleanup;
2039 }
2040
2041 memset(cpumaps, 0, ncpumaps * maplen);
2042
2043 for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
2044 cpumaps[i] = ret.cpumaps.cpumaps_val[i];
2045
2046 rv = ret.num;
2047
2048 cleanup:
2049 xdr_free((xdrproc_t) xdr_remote_domain_get_vcpu_pin_info_ret, (char *) &ret);
2050
2051 done:
2052 remoteDriverUnlock(priv);
2053 return rv;
2054 }
2055
2056 static int
remoteDomainPinEmulator(virDomainPtr dom,unsigned char * cpumap,int cpumaplen,unsigned int flags)2057 remoteDomainPinEmulator(virDomainPtr dom,
2058 unsigned char *cpumap,
2059 int cpumaplen,
2060 unsigned int flags)
2061 {
2062 int rv = -1;
2063 struct private_data *priv = dom->conn->privateData;
2064 remote_domain_pin_emulator_args args;
2065
2066 remoteDriverLock(priv);
2067
2068 if (cpumaplen > REMOTE_CPUMAP_MAX) {
2069 virReportError(VIR_ERR_RPC,
2070 _("%s length greater than maximum: %d > %d"),
2071 "cpumap", cpumaplen, REMOTE_CPUMAP_MAX);
2072 goto done;
2073 }
2074
2075 make_nonnull_domain(&args.dom, dom);
2076 args.cpumap.cpumap_val = (char *)cpumap;
2077 args.cpumap.cpumap_len = cpumaplen;
2078 args.flags = flags;
2079
2080 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_PIN_EMULATOR,
2081 (xdrproc_t) xdr_remote_domain_pin_emulator_args,
2082 (char *) &args,
2083 (xdrproc_t) xdr_void, (char *) NULL) == -1) {
2084 goto done;
2085 }
2086
2087 rv = 0;
2088
2089 done:
2090 remoteDriverUnlock(priv);
2091 return rv;
2092 }
2093
2094
2095 static int
remoteDomainGetEmulatorPinInfo(virDomainPtr domain,unsigned char * cpumaps,int maplen,unsigned int flags)2096 remoteDomainGetEmulatorPinInfo(virDomainPtr domain,
2097 unsigned char *cpumaps,
2098 int maplen,
2099 unsigned int flags)
2100 {
2101 int rv = -1;
2102 size_t i;
2103 remote_domain_get_emulator_pin_info_args args;
2104 remote_domain_get_emulator_pin_info_ret ret;
2105 struct private_data *priv = domain->conn->privateData;
2106
2107 remoteDriverLock(priv);
2108
2109 /* There is only one cpumap for all emulator threads */
2110 if (maplen > REMOTE_CPUMAPS_MAX) {
2111 virReportError(VIR_ERR_RPC,
2112 _("vCPU map buffer length exceeds maximum: %d > %d"),
2113 maplen, REMOTE_CPUMAPS_MAX);
2114 goto done;
2115 }
2116
2117 make_nonnull_domain(&args.dom, domain);
2118 args.maplen = maplen;
2119 args.flags = flags;
2120
2121 memset(&ret, 0, sizeof(ret));
2122
2123 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_EMULATOR_PIN_INFO,
2124 (xdrproc_t) xdr_remote_domain_get_emulator_pin_info_args,
2125 (char *) &args,
2126 (xdrproc_t) xdr_remote_domain_get_emulator_pin_info_ret,
2127 (char *) &ret) == -1)
2128 goto done;
2129
2130 if (ret.cpumaps.cpumaps_len > maplen) {
2131 virReportError(VIR_ERR_RPC,
2132 _("host reports map buffer length exceeds maximum: %d > %d"),
2133 ret.cpumaps.cpumaps_len, maplen);
2134 goto cleanup;
2135 }
2136
2137 memset(cpumaps, 0, maplen);
2138
2139 for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
2140 cpumaps[i] = ret.cpumaps.cpumaps_val[i];
2141
2142 rv = ret.ret;
2143
2144 cleanup:
2145 xdr_free((xdrproc_t) xdr_remote_domain_get_emulator_pin_info_ret,
2146 (char *) &ret);
2147
2148 done:
2149 remoteDriverUnlock(priv);
2150 return rv;
2151 }
2152
2153 static int
remoteDomainGetVcpus(virDomainPtr domain,virVcpuInfoPtr info,int maxinfo,unsigned char * cpumaps,int maplen)2154 remoteDomainGetVcpus(virDomainPtr domain,
2155 virVcpuInfoPtr info,
2156 int maxinfo,
2157 unsigned char *cpumaps,
2158 int maplen)
2159 {
2160 int rv = -1;
2161 size_t i;
2162 remote_domain_get_vcpus_args args;
2163 remote_domain_get_vcpus_ret ret;
2164 struct private_data *priv = domain->conn->privateData;
2165
2166 remoteDriverLock(priv);
2167
2168 if (maxinfo > REMOTE_VCPUINFO_MAX) {
2169 virReportError(VIR_ERR_RPC,
2170 _("vCPU count exceeds maximum: %d > %d"),
2171 maxinfo, REMOTE_VCPUINFO_MAX);
2172 goto done;
2173 }
2174 if (VIR_INT_MULTIPLY_OVERFLOW(maxinfo, maplen) ||
2175 maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
2176 virReportError(VIR_ERR_RPC,
2177 _("vCPU map buffer length exceeds maximum: %d > %d"),
2178 maxinfo * maplen, REMOTE_CPUMAPS_MAX);
2179 goto done;
2180 }
2181
2182 make_nonnull_domain(&args.dom, domain);
2183 args.maxinfo = maxinfo;
2184 args.maplen = maplen;
2185
2186 memset(&ret, 0, sizeof(ret));
2187 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS,
2188 (xdrproc_t) xdr_remote_domain_get_vcpus_args, (char *) &args,
2189 (xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret) == -1)
2190 goto done;
2191
2192 if (ret.info.info_len > maxinfo) {
2193 virReportError(VIR_ERR_RPC,
2194 _("host reports too many vCPUs: %d > %d"),
2195 ret.info.info_len, maxinfo);
2196 goto cleanup;
2197 }
2198 if (ret.cpumaps.cpumaps_len > maxinfo * maplen) {
2199 virReportError(VIR_ERR_RPC,
2200 _("host reports map buffer length exceeds maximum: %d > %d"),
2201 ret.cpumaps.cpumaps_len, maxinfo * maplen);
2202 goto cleanup;
2203 }
2204
2205 memset(info, 0, sizeof(virVcpuInfo) * maxinfo);
2206 memset(cpumaps, 0, maxinfo * maplen);
2207
2208 for (i = 0; i < ret.info.info_len; ++i) {
2209 info[i].number = ret.info.info_val[i].number;
2210 info[i].state = ret.info.info_val[i].state;
2211 info[i].cpuTime = ret.info.info_val[i].cpu_time;
2212 info[i].cpu = ret.info.info_val[i].cpu;
2213 }
2214
2215 for (i = 0; i < ret.cpumaps.cpumaps_len; ++i)
2216 cpumaps[i] = ret.cpumaps.cpumaps_val[i];
2217
2218 rv = ret.info.info_len;
2219
2220 cleanup:
2221 xdr_free((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret);
2222
2223 done:
2224 remoteDriverUnlock(priv);
2225 return rv;
2226 }
2227
2228 static int
remoteDomainGetIOThreadInfo(virDomainPtr dom,virDomainIOThreadInfoPtr ** info,unsigned int flags)2229 remoteDomainGetIOThreadInfo(virDomainPtr dom,
2230 virDomainIOThreadInfoPtr **info,
2231 unsigned int flags)
2232 {
2233 int rv = -1;
2234 size_t i;
2235 struct private_data *priv = dom->conn->privateData;
2236 remote_domain_get_iothread_info_args args;
2237 remote_domain_get_iothread_info_ret ret;
2238 remote_domain_iothread_info *src;
2239
2240 remoteDriverLock(priv);
2241
2242 make_nonnull_domain(&args.dom, dom);
2243
2244 args.flags = flags;
2245
2246 memset(&ret, 0, sizeof(ret));
2247
2248 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_IOTHREAD_INFO,
2249 (xdrproc_t)xdr_remote_domain_get_iothread_info_args,
2250 (char *)&args,
2251 (xdrproc_t)xdr_remote_domain_get_iothread_info_ret,
2252 (char *)&ret) == -1)
2253 goto done;
2254
2255 if (ret.info.info_len > REMOTE_IOTHREAD_INFO_MAX) {
2256 virReportError(VIR_ERR_INTERNAL_ERROR,
2257 _("Too many IOThreads in info: %d for limit %d"),
2258 ret.info.info_len, REMOTE_IOTHREAD_INFO_MAX);
2259 goto cleanup;
2260 }
2261
2262 if (info) {
2263 virDomainIOThreadInfoPtr *info_ret = NULL;
2264
2265 if (!ret.info.info_len) {
2266 *info = NULL;
2267 rv = ret.ret;
2268 goto cleanup;
2269 }
2270
2271 info_ret = g_new0(virDomainIOThreadInfoPtr, ret.info.info_len);
2272
2273 for (i = 0; i < ret.info.info_len; i++) {
2274 src = &ret.info.info_val[i];
2275
2276 info_ret[i] = g_new0(virDomainIOThreadInfo, 1);
2277
2278 info_ret[i]->iothread_id = src->iothread_id;
2279 info_ret[i]->cpumap = g_new0(unsigned char, src->cpumap.cpumap_len);
2280 memcpy(info_ret[i]->cpumap, src->cpumap.cpumap_val,
2281 src->cpumap.cpumap_len);
2282 info_ret[i]->cpumaplen = src->cpumap.cpumap_len;
2283 }
2284 *info = info_ret;
2285 }
2286
2287 rv = ret.ret;
2288
2289 cleanup:
2290 xdr_free((xdrproc_t)xdr_remote_domain_get_iothread_info_ret,
2291 (char *) &ret);
2292
2293 done:
2294 remoteDriverUnlock(priv);
2295 return rv;
2296 }
2297
2298 static int
remoteDomainGetSecurityLabel(virDomainPtr domain,virSecurityLabelPtr seclabel)2299 remoteDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
2300 {
2301 remote_domain_get_security_label_args args;
2302 remote_domain_get_security_label_ret ret;
2303 struct private_data *priv = domain->conn->privateData;
2304 int rv = -1;
2305
2306 remoteDriverLock(priv);
2307
2308 make_nonnull_domain(&args.dom, domain);
2309 memset(&ret, 0, sizeof(ret));
2310 memset(seclabel, 0, sizeof(*seclabel));
2311
2312 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL,
2313 (xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args,
2314 (xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) == -1) {
2315 goto done;
2316 }
2317
2318 if (ret.label.label_val != NULL) {
2319 if (virStrcpyStatic(seclabel->label, ret.label.label_val) < 0) {
2320 virReportError(VIR_ERR_RPC, _("security label exceeds maximum: %zu"),
2321 sizeof(seclabel->label) - 1);
2322 goto cleanup;
2323 }
2324 seclabel->enforcing = ret.enforcing;
2325 }
2326
2327 rv = 0;
2328
2329 cleanup:
2330 xdr_free((xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret);
2331
2332 done:
2333 remoteDriverUnlock(priv);
2334 return rv;
2335 }
2336
2337 static int
remoteDomainGetSecurityLabelList(virDomainPtr domain,virSecurityLabelPtr * seclabels)2338 remoteDomainGetSecurityLabelList(virDomainPtr domain, virSecurityLabelPtr* seclabels)
2339 {
2340 remote_domain_get_security_label_list_args args;
2341 remote_domain_get_security_label_list_ret ret;
2342 struct private_data *priv = domain->conn->privateData;
2343 size_t i;
2344 int rv = -1;
2345
2346 remoteDriverLock(priv);
2347
2348 make_nonnull_domain(&args.dom, domain);
2349 memset(&ret, 0, sizeof(ret));
2350
2351 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST,
2352 (xdrproc_t) xdr_remote_domain_get_security_label_list_args, (char *)&args,
2353 (xdrproc_t) xdr_remote_domain_get_security_label_list_ret, (char *)&ret) == -1) {
2354 goto done;
2355 }
2356
2357 *seclabels = g_new0(virSecurityLabel, ret.labels.labels_len);
2358
2359 for (i = 0; i < ret.labels.labels_len; i++) {
2360 remote_domain_get_security_label_ret *cur = &ret.labels.labels_val[i];
2361 if (cur->label.label_val != NULL) {
2362 if (virStrcpyStatic((*seclabels)[i].label, cur->label.label_val) < 0) {
2363 virReportError(VIR_ERR_RPC, _("security label exceeds maximum: %zd"),
2364 sizeof((*seclabels)->label) - 1);
2365 VIR_FREE(*seclabels);
2366 goto cleanup;
2367 }
2368 (*seclabels)[i].enforcing = cur->enforcing;
2369 }
2370 }
2371 rv = ret.ret;
2372
2373 cleanup:
2374 xdr_free((xdrproc_t) xdr_remote_domain_get_security_label_list_ret, (char *)&ret);
2375
2376 done:
2377 remoteDriverUnlock(priv);
2378 return rv;
2379 }
2380
2381 static int
remoteDomainGetState(virDomainPtr domain,int * state,int * reason,unsigned int flags)2382 remoteDomainGetState(virDomainPtr domain,
2383 int *state,
2384 int *reason,
2385 unsigned int flags)
2386 {
2387 int rv = -1;
2388 remote_domain_get_state_args args;
2389 remote_domain_get_state_ret ret;
2390 struct private_data *priv = domain->conn->privateData;
2391
2392 remoteDriverLock(priv);
2393
2394 make_nonnull_domain(&args.dom, domain);
2395 args.flags = flags;
2396
2397 memset(&ret, 0, sizeof(ret));
2398 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_STATE,
2399 (xdrproc_t) xdr_remote_domain_get_state_args, (char *) &args,
2400 (xdrproc_t) xdr_remote_domain_get_state_ret, (char *) &ret) == -1)
2401 goto done;
2402
2403 *state = ret.state;
2404 if (reason)
2405 *reason = ret.reason;
2406
2407 rv = 0;
2408
2409 done:
2410 remoteDriverUnlock(priv);
2411 return rv;
2412 }
2413
2414 static int
remoteNodeGetSecurityModel(virConnectPtr conn,virSecurityModelPtr secmodel)2415 remoteNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
2416 {
2417 remote_node_get_security_model_ret ret;
2418 struct private_data *priv = conn->privateData;
2419 int rv = -1;
2420
2421 remoteDriverLock(priv);
2422
2423 memset(&ret, 0, sizeof(ret));
2424 memset(secmodel, 0, sizeof(*secmodel));
2425
2426 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL,
2427 (xdrproc_t) xdr_void, NULL,
2428 (xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) == -1) {
2429 goto done;
2430 }
2431
2432 if (ret.model.model_val != NULL) {
2433 if (virStrcpyStatic(secmodel->model, ret.model.model_val) < 0) {
2434 virReportError(VIR_ERR_RPC, _("security model exceeds maximum: %zu"),
2435 sizeof(secmodel->model) - 1);
2436 goto cleanup;
2437 }
2438 }
2439
2440 if (ret.doi.doi_val != NULL) {
2441 if (virStrcpyStatic(secmodel->doi, ret.doi.doi_val) < 0) {
2442 virReportError(VIR_ERR_RPC, _("security doi exceeds maximum: %zu"),
2443 sizeof(secmodel->doi) - 1);
2444 goto cleanup;
2445 }
2446 }
2447
2448 rv = 0;
2449
2450 cleanup:
2451 xdr_free((xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret);
2452
2453 done:
2454 remoteDriverUnlock(priv);
2455 return rv;
2456 }
2457
2458 static int
remoteDomainMigratePrepare(virConnectPtr dconn,char ** cookie,int * cookielen,const char * uri_in,char ** uri_out,unsigned long flags,const char * dname,unsigned long resource)2459 remoteDomainMigratePrepare(virConnectPtr dconn,
2460 char **cookie, int *cookielen,
2461 const char *uri_in, char **uri_out,
2462 unsigned long flags, const char *dname,
2463 unsigned long resource)
2464 {
2465 int rv = -1;
2466 remote_domain_migrate_prepare_args args;
2467 remote_domain_migrate_prepare_ret ret;
2468 struct private_data *priv = dconn->privateData;
2469
2470 remoteDriverLock(priv);
2471
2472 args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
2473 args.flags = flags;
2474 args.dname = dname == NULL ? NULL : (char **) &dname;
2475 args.resource = resource;
2476
2477 memset(&ret, 0, sizeof(ret));
2478 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE,
2479 (xdrproc_t) xdr_remote_domain_migrate_prepare_args, (char *) &args,
2480 (xdrproc_t) xdr_remote_domain_migrate_prepare_ret, (char *) &ret) == -1)
2481 goto done;
2482
2483 if (ret.cookie.cookie_len > 0) {
2484 *cookie = ret.cookie.cookie_val; /* Caller frees. */
2485 *cookielen = ret.cookie.cookie_len;
2486 }
2487 if (ret.uri_out)
2488 *uri_out = *ret.uri_out; /* Caller frees. */
2489
2490 VIR_FREE(ret.uri_out);
2491 rv = 0;
2492
2493 done:
2494 remoteDriverUnlock(priv);
2495 return rv;
2496 }
2497
2498 static int
remoteDomainMigratePrepare2(virConnectPtr dconn,char ** cookie,int * cookielen,const char * uri_in,char ** uri_out,unsigned long flags,const char * dname,unsigned long resource,const char * dom_xml)2499 remoteDomainMigratePrepare2(virConnectPtr dconn,
2500 char **cookie, int *cookielen,
2501 const char *uri_in, char **uri_out,
2502 unsigned long flags, const char *dname,
2503 unsigned long resource,
2504 const char *dom_xml)
2505 {
2506 int rv = -1;
2507 remote_domain_migrate_prepare2_args args;
2508 remote_domain_migrate_prepare2_ret ret;
2509 struct private_data *priv = dconn->privateData;
2510
2511 remoteDriverLock(priv);
2512
2513 args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
2514 args.flags = flags;
2515 args.dname = dname == NULL ? NULL : (char **) &dname;
2516 args.resource = resource;
2517 args.dom_xml = (char *) dom_xml;
2518
2519 memset(&ret, 0, sizeof(ret));
2520 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE2,
2521 (xdrproc_t) xdr_remote_domain_migrate_prepare2_args, (char *) &args,
2522 (xdrproc_t) xdr_remote_domain_migrate_prepare2_ret, (char *) &ret) == -1)
2523 goto done;
2524
2525 if (ret.cookie.cookie_len > 0) {
2526 if (!cookie || !cookielen) {
2527 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2528 _("caller ignores cookie or cookielen"));
2529 goto error;
2530 }
2531 *cookie = ret.cookie.cookie_val; /* Caller frees. */
2532 *cookielen = ret.cookie.cookie_len;
2533 }
2534 if (ret.uri_out) {
2535 if (!uri_out) {
2536 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2537 _("caller ignores uri_out"));
2538 goto error;
2539 }
2540 *uri_out = *ret.uri_out; /* Caller frees. */
2541 }
2542
2543 rv = 0;
2544
2545 done:
2546 VIR_FREE(ret.uri_out);
2547 remoteDriverUnlock(priv);
2548 return rv;
2549 error:
2550 if (ret.cookie.cookie_len)
2551 VIR_FREE(ret.cookie.cookie_val);
2552 if (ret.uri_out)
2553 VIR_FREE(*ret.uri_out);
2554 goto done;
2555 }
2556
2557 static int
remoteDomainCreate(virDomainPtr domain)2558 remoteDomainCreate(virDomainPtr domain)
2559 {
2560 int rv = -1;
2561 remote_domain_create_args args;
2562 remote_domain_lookup_by_uuid_args args2;
2563 remote_domain_lookup_by_uuid_ret ret2;
2564 struct private_data *priv = domain->conn->privateData;
2565
2566 remoteDriverLock(priv);
2567
2568 make_nonnull_domain(&args.dom, domain);
2569
2570 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_CREATE,
2571 (xdrproc_t) xdr_remote_domain_create_args, (char *) &args,
2572 (xdrproc_t) xdr_void, (char *) NULL) == -1)
2573 goto done;
2574
2575 /* Need to do a lookup figure out ID of newly started guest, because
2576 * bug in design of REMOTE_PROC_DOMAIN_CREATE means we aren't getting
2577 * it returned.
2578 */
2579 memcpy(args2.uuid, domain->uuid, VIR_UUID_BUFLEN);
2580 memset(&ret2, 0, sizeof(ret2));
2581 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID,
2582 (xdrproc_t) xdr_remote_domain_lookup_by_uuid_args, (char *) &args2,
2583 (xdrproc_t) xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2) == -1)
2584 goto done;
2585
2586 domain->id = ret2.dom.id;
2587 xdr_free((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret2);
2588
2589 rv = 0;
2590
2591 done:
2592 remoteDriverUnlock(priv);
2593 return rv;
2594 }
2595
2596 static char *
remoteDomainGetSchedulerType(virDomainPtr domain,int * nparams)2597 remoteDomainGetSchedulerType(virDomainPtr domain, int *nparams)
2598 {
2599 char *rv = NULL;
2600 remote_domain_get_scheduler_type_args args;
2601 remote_domain_get_scheduler_type_ret ret;
2602 struct private_data *priv = domain->conn->privateData;
2603
2604 remoteDriverLock(priv);
2605
2606 make_nonnull_domain(&args.dom, domain);
2607
2608 memset(&ret, 0, sizeof(ret));
2609 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE,
2610 (xdrproc_t) xdr_remote_domain_get_scheduler_type_args, (char *) &args,
2611 (xdrproc_t) xdr_remote_domain_get_scheduler_type_ret, (char *) &ret) == -1)
2612 goto done;
2613
2614 if (nparams) *nparams = ret.nparams;
2615
2616 /* Caller frees this. */
2617 rv = ret.type;
2618
2619 done:
2620 remoteDriverUnlock(priv);
2621 return rv;
2622 }
2623
2624 static int
remoteDomainMemoryStats(virDomainPtr domain,virDomainMemoryStatPtr stats,unsigned int nr_stats,unsigned int flags)2625 remoteDomainMemoryStats(virDomainPtr domain,
2626 virDomainMemoryStatPtr stats,
2627 unsigned int nr_stats,
2628 unsigned int flags)
2629 {
2630 int rv = -1;
2631 remote_domain_memory_stats_args args;
2632 remote_domain_memory_stats_ret ret;
2633 struct private_data *priv = domain->conn->privateData;
2634 size_t i;
2635
2636 remoteDriverLock(priv);
2637
2638 make_nonnull_domain(&args.dom, domain);
2639 if (nr_stats > REMOTE_DOMAIN_MEMORY_STATS_MAX) {
2640 virReportError(VIR_ERR_RPC,
2641 _("too many memory stats requested: %d > %d"), nr_stats,
2642 REMOTE_DOMAIN_MEMORY_STATS_MAX);
2643 goto done;
2644 }
2645 args.maxStats = nr_stats;
2646 args.flags = flags;
2647 memset(&ret, 0, sizeof(ret));
2648
2649 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_STATS,
2650 (xdrproc_t) xdr_remote_domain_memory_stats_args,
2651 (char *) &args,
2652 (xdrproc_t) xdr_remote_domain_memory_stats_ret,
2653 (char *) &ret) == -1)
2654 goto done;
2655
2656 for (i = 0; i < ret.stats.stats_len; i++) {
2657 stats[i].tag = ret.stats.stats_val[i].tag;
2658 stats[i].val = ret.stats.stats_val[i].val;
2659 }
2660 rv = ret.stats.stats_len;
2661 xdr_free((xdrproc_t) xdr_remote_domain_memory_stats_ret, (char *) &ret);
2662
2663 done:
2664 remoteDriverUnlock(priv);
2665 return rv;
2666 }
2667
2668 static int
remoteDomainBlockPeek(virDomainPtr domain,const char * path,unsigned long long offset,size_t size,void * buffer,unsigned int flags)2669 remoteDomainBlockPeek(virDomainPtr domain,
2670 const char *path,
2671 unsigned long long offset,
2672 size_t size,
2673 void *buffer,
2674 unsigned int flags)
2675 {
2676 int rv = -1;
2677 remote_domain_block_peek_args args;
2678 remote_domain_block_peek_ret ret;
2679 struct private_data *priv = domain->conn->privateData;
2680
2681 remoteDriverLock(priv);
2682
2683 if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
2684 virReportError(VIR_ERR_RPC,
2685 _("block peek request too large for remote protocol, %zi > %d"),
2686 size, REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX);
2687 goto done;
2688 }
2689
2690 make_nonnull_domain(&args.dom, domain);
2691 args.path = (char *) path;
2692 args.offset = offset;
2693 args.size = size;
2694 args.flags = flags;
2695
2696 memset(&ret, 0, sizeof(ret));
2697 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_PEEK,
2698 (xdrproc_t) xdr_remote_domain_block_peek_args,
2699 (char *) &args,
2700 (xdrproc_t) xdr_remote_domain_block_peek_ret,
2701 (char *) &ret) == -1)
2702 goto done;
2703
2704 if (ret.buffer.buffer_len != size) {
2705 virReportError(VIR_ERR_RPC, "%s",
2706 _("returned buffer is not same size as requested"));
2707 goto cleanup;
2708 }
2709
2710 memcpy(buffer, ret.buffer.buffer_val, size);
2711 rv = 0;
2712
2713 cleanup:
2714 VIR_FREE(ret.buffer.buffer_val);
2715
2716 done:
2717 remoteDriverUnlock(priv);
2718 return rv;
2719 }
2720
2721 static int
remoteDomainMemoryPeek(virDomainPtr domain,unsigned long long offset,size_t size,void * buffer,unsigned int flags)2722 remoteDomainMemoryPeek(virDomainPtr domain,
2723 unsigned long long offset,
2724 size_t size,
2725 void *buffer,
2726 unsigned int flags)
2727 {
2728 int rv = -1;
2729 remote_domain_memory_peek_args args;
2730 remote_domain_memory_peek_ret ret;
2731 struct private_data *priv = domain->conn->privateData;
2732
2733 remoteDriverLock(priv);
2734
2735 if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) {
2736 virReportError(VIR_ERR_RPC,
2737 _("memory peek request too large for remote protocol, %zi > %d"),
2738 size, REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX);
2739 goto done;
2740 }
2741
2742 make_nonnull_domain(&args.dom, domain);
2743 args.offset = offset;
2744 args.size = size;
2745 args.flags = flags;
2746
2747 memset(&ret, 0, sizeof(ret));
2748 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_PEEK,
2749 (xdrproc_t) xdr_remote_domain_memory_peek_args,
2750 (char *) &args,
2751 (xdrproc_t) xdr_remote_domain_memory_peek_ret,
2752 (char *) &ret) == -1)
2753 goto done;
2754
2755 if (ret.buffer.buffer_len != size) {
2756 virReportError(VIR_ERR_RPC, "%s",
2757 _("returned buffer is not same size as requested"));
2758 goto cleanup;
2759 }
2760
2761 memcpy(buffer, ret.buffer.buffer_val, size);
2762 rv = 0;
2763
2764 cleanup:
2765 VIR_FREE(ret.buffer.buffer_val);
2766
2767 done:
2768 remoteDriverUnlock(priv);
2769 return rv;
2770 }
2771
remoteDomainGetBlockJobInfo(virDomainPtr domain,const char * path,virDomainBlockJobInfoPtr info,unsigned int flags)2772 static int remoteDomainGetBlockJobInfo(virDomainPtr domain,
2773 const char *path,
2774 virDomainBlockJobInfoPtr info,
2775 unsigned int flags)
2776 {
2777 int rv = -1;
2778 remote_domain_get_block_job_info_args args;
2779 remote_domain_get_block_job_info_ret ret;
2780 struct private_data *priv = domain->conn->privateData;
2781
2782 remoteDriverLock(priv);
2783
2784 make_nonnull_domain(&args.dom, domain);
2785 args.path = (char *)path;
2786 args.flags = flags;
2787
2788 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO,
2789 (xdrproc_t)xdr_remote_domain_get_block_job_info_args,
2790 (char *)&args,
2791 (xdrproc_t)xdr_remote_domain_get_block_job_info_ret,
2792 (char *)&ret) == -1)
2793 goto done;
2794
2795 if (ret.found) {
2796 info->type = ret.type;
2797 info->bandwidth = ret.bandwidth;
2798 info->cur = ret.cur;
2799 info->end = ret.end;
2800 rv = 1;
2801 } else {
2802 rv = 0;
2803 }
2804
2805 done:
2806 remoteDriverUnlock(priv);
2807 return rv;
2808 }
2809
remoteDomainGetBlockIoTune(virDomainPtr domain,const char * disk,virTypedParameterPtr params,int * nparams,unsigned int flags)2810 static int remoteDomainGetBlockIoTune(virDomainPtr domain,
2811 const char *disk,
2812 virTypedParameterPtr params,
2813 int *nparams,
2814 unsigned int flags)
2815 {
2816 int rv = -1;
2817 remote_domain_get_block_io_tune_args args;
2818 remote_domain_get_block_io_tune_ret ret;
2819 struct private_data *priv = domain->conn->privateData;
2820
2821 remoteDriverLock(priv);
2822
2823 make_nonnull_domain(&args.dom, domain);
2824 args.disk = disk ? (char **)&disk : NULL;
2825 args.nparams = *nparams;
2826 args.flags = flags;
2827
2828 memset(&ret, 0, sizeof(ret));
2829
2830
2831 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_IO_TUNE,
2832 (xdrproc_t) xdr_remote_domain_get_block_io_tune_args,
2833 (char *) &args,
2834 (xdrproc_t) xdr_remote_domain_get_block_io_tune_ret,
2835 (char *) &ret) == -1) {
2836 goto done;
2837 }
2838
2839 /* Handle the case when the caller does not know the number of parameters
2840 * and is asking for the number of parameters supported
2841 */
2842 if (*nparams == 0) {
2843 *nparams = ret.nparams;
2844 rv = 0;
2845 goto cleanup;
2846 }
2847
2848 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
2849 ret.params.params_len,
2850 REMOTE_DOMAIN_BLOCK_IO_TUNE_PARAMETERS_MAX,
2851 ¶ms,
2852 nparams) < 0)
2853 goto cleanup;
2854
2855 rv = 0;
2856
2857 cleanup:
2858 xdr_free((xdrproc_t) xdr_remote_domain_get_block_io_tune_ret,
2859 (char *) &ret);
2860 done:
2861 remoteDriverUnlock(priv);
2862 return rv;
2863 }
2864
remoteDomainGetCPUStats(virDomainPtr domain,virTypedParameterPtr params,unsigned int nparams,int start_cpu,unsigned int ncpus,unsigned int flags)2865 static int remoteDomainGetCPUStats(virDomainPtr domain,
2866 virTypedParameterPtr params,
2867 unsigned int nparams,
2868 int start_cpu,
2869 unsigned int ncpus,
2870 unsigned int flags)
2871 {
2872 struct private_data *priv = domain->conn->privateData;
2873 remote_domain_get_cpu_stats_args args;
2874 remote_domain_get_cpu_stats_ret ret;
2875 int rv = -1;
2876 int cpu;
2877
2878 remoteDriverLock(priv);
2879
2880 if (nparams > REMOTE_NODE_CPU_STATS_MAX) {
2881 virReportError(VIR_ERR_RPC,
2882 _("nparams count exceeds maximum: %u > %u"),
2883 nparams, REMOTE_NODE_CPU_STATS_MAX);
2884 goto done;
2885 }
2886 if (ncpus > REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX) {
2887 virReportError(VIR_ERR_RPC,
2888 _("ncpus count exceeds maximum: %u > %u"),
2889 ncpus, REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX);
2890 goto done;
2891 }
2892
2893 make_nonnull_domain(&args.dom, domain);
2894 args.nparams = nparams;
2895 args.start_cpu = start_cpu;
2896 args.ncpus = ncpus;
2897 args.flags = flags;
2898
2899 memset(&ret, 0, sizeof(ret));
2900
2901 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_CPU_STATS,
2902 (xdrproc_t) xdr_remote_domain_get_cpu_stats_args,
2903 (char *) &args,
2904 (xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
2905 (char *) &ret) == -1)
2906 goto done;
2907
2908 /* Check the length of the returned list carefully. */
2909 if (ret.params.params_len > nparams * ncpus ||
2910 (ret.params.params_len &&
2911 ((ret.params.params_len % ret.nparams) || ret.nparams > nparams))) {
2912 virReportError(VIR_ERR_RPC, "%s",
2913 _("remoteDomainGetCPUStats: "
2914 "returned number of stats exceeds limit"));
2915 memset(params, 0, sizeof(*params) * nparams * ncpus);
2916 goto cleanup;
2917 }
2918
2919 /* Handle the case when the caller does not know the number of stats
2920 * and is asking for the number of stats supported
2921 */
2922 if (nparams == 0) {
2923 rv = ret.nparams;
2924 goto cleanup;
2925 }
2926
2927 /* The remote side did not send back any zero entries, so we have
2928 * to expand things back into a possibly sparse array, where the
2929 * tail of the array may be omitted.
2930 */
2931 memset(params, 0, sizeof(*params) * nparams * ncpus);
2932 ncpus = ret.params.params_len / ret.nparams;
2933 for (cpu = 0; cpu < ncpus; cpu++) {
2934 int tmp = nparams;
2935 virTypedParameterPtr cpu_params = ¶ms[cpu * nparams];
2936 remote_typed_param *stride = &ret.params.params_val[cpu * ret.nparams];
2937
2938 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) stride,
2939 ret.nparams,
2940 REMOTE_NODE_CPU_STATS_MAX,
2941 &cpu_params, &tmp) < 0)
2942 goto cleanup;
2943 }
2944
2945 rv = ret.nparams;
2946 cleanup:
2947 if (rv < 0)
2948 virTypedParamsClear(params, nparams * ncpus);
2949
2950 xdr_free((xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
2951 (char *) &ret);
2952 done:
2953 remoteDriverUnlock(priv);
2954 return rv;
2955 }
2956
2957
2958 static int
remoteConnectNetworkEventRegisterAny(virConnectPtr conn,virNetworkPtr net,int eventID,virConnectNetworkEventGenericCallback callback,void * opaque,virFreeCallback freecb)2959 remoteConnectNetworkEventRegisterAny(virConnectPtr conn,
2960 virNetworkPtr net,
2961 int eventID,
2962 virConnectNetworkEventGenericCallback callback,
2963 void *opaque,
2964 virFreeCallback freecb)
2965 {
2966 int rv = -1;
2967 struct private_data *priv = conn->privateData;
2968 remote_connect_network_event_register_any_args args;
2969 remote_connect_network_event_register_any_ret ret;
2970 int callbackID;
2971 int count;
2972 remote_nonnull_network network;
2973
2974 remoteDriverLock(priv);
2975
2976 if ((count = virNetworkEventStateRegisterClient(conn, priv->eventState,
2977 net, eventID, callback,
2978 opaque, freecb,
2979 &callbackID)) < 0)
2980 goto done;
2981
2982 /* If this is the first callback for this eventID, we need to enable
2983 * events on the server */
2984 if (count == 1) {
2985 args.eventID = eventID;
2986 if (net) {
2987 make_nonnull_network(&network, net);
2988 args.net = &network;
2989 } else {
2990 args.net = NULL;
2991 }
2992
2993 memset(&ret, 0, sizeof(ret));
2994 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY,
2995 (xdrproc_t) xdr_remote_connect_network_event_register_any_args, (char *) &args,
2996 (xdrproc_t) xdr_remote_connect_network_event_register_any_ret, (char *) &ret) == -1) {
2997 virObjectEventStateDeregisterID(conn, priv->eventState,
2998 callbackID, false);
2999 goto done;
3000 }
3001 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
3002 ret.callbackID);
3003 }
3004
3005 rv = callbackID;
3006
3007 done:
3008 remoteDriverUnlock(priv);
3009 return rv;
3010 }
3011
3012
3013 static int
remoteConnectNetworkEventDeregisterAny(virConnectPtr conn,int callbackID)3014 remoteConnectNetworkEventDeregisterAny(virConnectPtr conn,
3015 int callbackID)
3016 {
3017 struct private_data *priv = conn->privateData;
3018 int rv = -1;
3019 remote_connect_network_event_deregister_any_args args;
3020 int eventID;
3021 int remoteID;
3022 int count;
3023
3024 remoteDriverLock(priv);
3025
3026 if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
3027 callbackID, &remoteID)) < 0)
3028 goto done;
3029
3030 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
3031 callbackID, true)) < 0)
3032 goto done;
3033
3034 /* If that was the last callback for this eventID, we need to disable
3035 * events on the server */
3036 if (count == 0) {
3037 args.callbackID = remoteID;
3038
3039 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NETWORK_EVENT_DEREGISTER_ANY,
3040 (xdrproc_t) xdr_remote_connect_network_event_deregister_any_args, (char *) &args,
3041 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3042 goto done;
3043 }
3044
3045 rv = 0;
3046
3047 done:
3048 remoteDriverUnlock(priv);
3049 return rv;
3050 }
3051
3052 static int
remoteConnectStoragePoolEventRegisterAny(virConnectPtr conn,virStoragePoolPtr pool,int eventID,virConnectStoragePoolEventGenericCallback callback,void * opaque,virFreeCallback freecb)3053 remoteConnectStoragePoolEventRegisterAny(virConnectPtr conn,
3054 virStoragePoolPtr pool,
3055 int eventID,
3056 virConnectStoragePoolEventGenericCallback callback,
3057 void *opaque,
3058 virFreeCallback freecb)
3059 {
3060 int rv = -1;
3061 struct private_data *priv = conn->privateData;
3062 remote_connect_storage_pool_event_register_any_args args;
3063 remote_connect_storage_pool_event_register_any_ret ret;
3064 int callbackID;
3065 int count;
3066 remote_nonnull_storage_pool storage_pool;
3067
3068 remoteDriverLock(priv);
3069
3070 if ((count = virStoragePoolEventStateRegisterClient(conn, priv->eventState,
3071 pool, eventID, callback,
3072 opaque, freecb,
3073 &callbackID)) < 0)
3074 goto done;
3075
3076 /* If this is the first callback for this eventID, we need to enable
3077 * events on the server */
3078 if (count == 1) {
3079 args.eventID = eventID;
3080 if (pool) {
3081 make_nonnull_storage_pool(&storage_pool, pool);
3082 args.pool = &storage_pool;
3083 } else {
3084 args.pool = NULL;
3085 }
3086
3087 memset(&ret, 0, sizeof(ret));
3088 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_STORAGE_POOL_EVENT_REGISTER_ANY,
3089 (xdrproc_t) xdr_remote_connect_storage_pool_event_register_any_args, (char *) &args,
3090 (xdrproc_t) xdr_remote_connect_storage_pool_event_register_any_ret, (char *) &ret) == -1) {
3091 virObjectEventStateDeregisterID(conn, priv->eventState,
3092 callbackID, false);
3093 goto done;
3094 }
3095
3096 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
3097 ret.callbackID);
3098 }
3099
3100 rv = callbackID;
3101
3102 done:
3103 remoteDriverUnlock(priv);
3104 return rv;
3105 }
3106
3107 static int
remoteConnectStoragePoolEventDeregisterAny(virConnectPtr conn,int callbackID)3108 remoteConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
3109 int callbackID)
3110 {
3111 struct private_data *priv = conn->privateData;
3112 int rv = -1;
3113 remote_connect_storage_pool_event_deregister_any_args args;
3114 int eventID;
3115 int remoteID;
3116 int count;
3117
3118 remoteDriverLock(priv);
3119
3120 if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
3121 callbackID, &remoteID)) < 0)
3122 goto done;
3123
3124 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
3125 callbackID, true)) < 0)
3126 goto done;
3127
3128 /* If that was the last callback for this eventID, we need to disable
3129 * events on the server */
3130 if (count == 0) {
3131 args.callbackID = remoteID;
3132
3133 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_STORAGE_POOL_EVENT_DEREGISTER_ANY,
3134 (xdrproc_t) xdr_remote_connect_storage_pool_event_deregister_any_args, (char *) &args,
3135 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3136 goto done;
3137
3138 }
3139
3140 rv = 0;
3141
3142 done:
3143 remoteDriverUnlock(priv);
3144 return rv;
3145 }
3146
3147
3148 static int
remoteConnectNodeDeviceEventRegisterAny(virConnectPtr conn,virNodeDevicePtr dev,int eventID,virConnectNodeDeviceEventGenericCallback callback,void * opaque,virFreeCallback freecb)3149 remoteConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
3150 virNodeDevicePtr dev,
3151 int eventID,
3152 virConnectNodeDeviceEventGenericCallback callback,
3153 void *opaque,
3154 virFreeCallback freecb)
3155 {
3156 int rv = -1;
3157 struct private_data *priv = conn->privateData;
3158 remote_connect_node_device_event_register_any_args args;
3159 remote_connect_node_device_event_register_any_ret ret;
3160 int callbackID;
3161 int count;
3162 remote_nonnull_node_device node_device;
3163
3164 remoteDriverLock(priv);
3165
3166 if ((count = virNodeDeviceEventStateRegisterClient(conn, priv->eventState,
3167 dev, eventID, callback,
3168 opaque, freecb,
3169 &callbackID)) < 0)
3170 goto done;
3171
3172 /* If this is the first callback for this eventID, we need to enable
3173 * events on the server */
3174 if (count == 1) {
3175 args.eventID = eventID;
3176 if (dev) {
3177 make_nonnull_node_device(&node_device, dev);
3178 args.dev = &node_device;
3179 } else {
3180 args.dev = NULL;
3181 }
3182
3183 memset(&ret, 0, sizeof(ret));
3184 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_REGISTER_ANY,
3185 (xdrproc_t) xdr_remote_connect_node_device_event_register_any_args, (char *) &args,
3186 (xdrproc_t) xdr_remote_connect_node_device_event_register_any_ret, (char *) &ret) == -1) {
3187 virObjectEventStateDeregisterID(conn, priv->eventState,
3188 callbackID, false);
3189 goto done;
3190 }
3191
3192 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
3193 ret.callbackID);
3194 }
3195
3196 rv = callbackID;
3197
3198 done:
3199 remoteDriverUnlock(priv);
3200 return rv;
3201 }
3202
3203
3204 static int
remoteConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,int callbackID)3205 remoteConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
3206 int callbackID)
3207 {
3208 struct private_data *priv = conn->privateData;
3209 int rv = -1;
3210 remote_connect_node_device_event_deregister_any_args args;
3211 int eventID;
3212 int remoteID;
3213 int count;
3214
3215 remoteDriverLock(priv);
3216
3217 if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
3218 callbackID, &remoteID)) < 0)
3219 goto done;
3220
3221 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
3222 callbackID, true)) < 0)
3223 goto done;
3224
3225 /* If that was the last callback for this eventID, we need to disable
3226 * events on the server */
3227 if (count == 0) {
3228 args.callbackID = remoteID;
3229
3230 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_DEREGISTER_ANY,
3231 (xdrproc_t) xdr_remote_connect_node_device_event_deregister_any_args, (char *) &args,
3232 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3233 goto done;
3234
3235 }
3236
3237 rv = 0;
3238
3239 done:
3240 remoteDriverUnlock(priv);
3241 return rv;
3242 }
3243
3244
3245 static int
remoteConnectSecretEventRegisterAny(virConnectPtr conn,virSecretPtr secret,int eventID,virConnectSecretEventGenericCallback callback,void * opaque,virFreeCallback freecb)3246 remoteConnectSecretEventRegisterAny(virConnectPtr conn,
3247 virSecretPtr secret,
3248 int eventID,
3249 virConnectSecretEventGenericCallback callback,
3250 void *opaque,
3251 virFreeCallback freecb)
3252 {
3253 int rv = -1;
3254 struct private_data *priv = conn->privateData;
3255 remote_connect_secret_event_register_any_args args;
3256 remote_connect_secret_event_register_any_ret ret;
3257 int callbackID;
3258 int count;
3259 remote_nonnull_secret sec;
3260
3261 remoteDriverLock(priv);
3262
3263 if ((count = virSecretEventStateRegisterClient(conn, priv->eventState,
3264 secret, eventID, callback,
3265 opaque, freecb,
3266 &callbackID)) < 0)
3267 goto done;
3268
3269 /* If this is the first callback for this eventID, we need to enable
3270 * events on the server */
3271 if (count == 1) {
3272 args.eventID = eventID;
3273 if (secret) {
3274 make_nonnull_secret(&sec, secret);
3275 args.secret = &sec;
3276 } else {
3277 args.secret = NULL;
3278 }
3279
3280 memset(&ret, 0, sizeof(ret));
3281 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_SECRET_EVENT_REGISTER_ANY,
3282 (xdrproc_t) xdr_remote_connect_secret_event_register_any_args, (char *) &args,
3283 (xdrproc_t) xdr_remote_connect_secret_event_register_any_ret, (char *) &ret) == -1) {
3284 virObjectEventStateDeregisterID(conn, priv->eventState,
3285 callbackID, false);
3286 goto done;
3287 }
3288
3289 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
3290 ret.callbackID);
3291 }
3292
3293 rv = callbackID;
3294
3295 done:
3296 remoteDriverUnlock(priv);
3297 return rv;
3298 }
3299
3300
3301 static int
remoteConnectSecretEventDeregisterAny(virConnectPtr conn,int callbackID)3302 remoteConnectSecretEventDeregisterAny(virConnectPtr conn,
3303 int callbackID)
3304 {
3305 struct private_data *priv = conn->privateData;
3306 int rv = -1;
3307 remote_connect_secret_event_deregister_any_args args;
3308 int eventID;
3309 int remoteID;
3310 int count;
3311
3312 remoteDriverLock(priv);
3313
3314 if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
3315 callbackID, &remoteID)) < 0)
3316 goto done;
3317
3318 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
3319 callbackID, true)) < 0)
3320 goto done;
3321
3322 /* If that was the last callback for this eventID, we need to disable
3323 * events on the server */
3324 if (count == 0) {
3325 args.callbackID = remoteID;
3326
3327 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_SECRET_EVENT_DEREGISTER_ANY,
3328 (xdrproc_t) xdr_remote_connect_secret_event_deregister_any_args, (char *) &args,
3329 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3330 goto done;
3331
3332 }
3333
3334 rv = 0;
3335
3336 done:
3337 remoteDriverUnlock(priv);
3338 return rv;
3339 }
3340
3341
3342 static int
remoteConnectDomainQemuMonitorEventRegister(virConnectPtr conn,virDomainPtr dom,const char * event,virConnectDomainQemuMonitorEventCallback callback,void * opaque,virFreeCallback freecb,unsigned int flags)3343 remoteConnectDomainQemuMonitorEventRegister(virConnectPtr conn,
3344 virDomainPtr dom,
3345 const char *event,
3346 virConnectDomainQemuMonitorEventCallback callback,
3347 void *opaque,
3348 virFreeCallback freecb,
3349 unsigned int flags)
3350 {
3351 int rv = -1;
3352 struct private_data *priv = conn->privateData;
3353 qemu_connect_domain_monitor_event_register_args args;
3354 qemu_connect_domain_monitor_event_register_ret ret;
3355 int callbackID;
3356 int count;
3357 remote_nonnull_domain domain;
3358
3359 remoteDriverLock(priv);
3360
3361 if ((count = virDomainQemuMonitorEventStateRegisterID(conn,
3362 priv->eventState,
3363 dom, event, callback,
3364 opaque, freecb, -1,
3365 &callbackID)) < 0)
3366 goto done;
3367
3368 /* If this is the first callback for this event, we need to enable
3369 * events on the server */
3370 if (count == 1) {
3371 if (dom) {
3372 make_nonnull_domain(&domain, dom);
3373 args.dom = &domain;
3374 } else {
3375 args.dom = NULL;
3376 }
3377 args.event = event ? (char **) &event : NULL;
3378 args.flags = flags;
3379
3380 memset(&ret, 0, sizeof(ret));
3381 if (call(conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_REGISTER,
3382 (xdrproc_t) xdr_qemu_connect_domain_monitor_event_register_args, (char *) &args,
3383 (xdrproc_t) xdr_qemu_connect_domain_monitor_event_register_ret, (char *) &ret) == -1) {
3384 virObjectEventStateDeregisterID(conn, priv->eventState,
3385 callbackID, false);
3386 goto done;
3387 }
3388 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
3389 ret.callbackID);
3390 }
3391
3392 rv = callbackID;
3393
3394 done:
3395 remoteDriverUnlock(priv);
3396 return rv;
3397 }
3398
3399
3400 static int
remoteConnectDomainQemuMonitorEventDeregister(virConnectPtr conn,int callbackID)3401 remoteConnectDomainQemuMonitorEventDeregister(virConnectPtr conn,
3402 int callbackID)
3403 {
3404 struct private_data *priv = conn->privateData;
3405 int rv = -1;
3406 qemu_connect_domain_monitor_event_deregister_args args;
3407 int remoteID;
3408 int count;
3409
3410 remoteDriverLock(priv);
3411
3412 if (virObjectEventStateEventID(conn, priv->eventState,
3413 callbackID, &remoteID) < 0)
3414 goto done;
3415
3416 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
3417 callbackID, true)) < 0)
3418 goto done;
3419
3420 /* If that was the last callback for this event, we need to disable
3421 * events on the server */
3422 if (count == 0) {
3423 args.callbackID = remoteID;
3424
3425 if (call(conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_DEREGISTER,
3426 (xdrproc_t) xdr_qemu_connect_domain_monitor_event_deregister_args, (char *) &args,
3427 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3428 goto done;
3429 }
3430
3431 rv = 0;
3432
3433 done:
3434 remoteDriverUnlock(priv);
3435 return rv;
3436 }
3437
3438 /*----------------------------------------------------------------------*/
3439
3440 static char *
remoteConnectFindStoragePoolSources(virConnectPtr conn,const char * type,const char * srcSpec,unsigned int flags)3441 remoteConnectFindStoragePoolSources(virConnectPtr conn,
3442 const char *type,
3443 const char *srcSpec,
3444 unsigned int flags)
3445 {
3446 char *rv = NULL;
3447 remote_connect_find_storage_pool_sources_args args;
3448 remote_connect_find_storage_pool_sources_ret ret;
3449 struct private_data *priv = conn->privateData;
3450
3451 remoteDriverLock(priv);
3452
3453 args.type = (char*)type;
3454 args.srcSpec = srcSpec ? (char **)&srcSpec : NULL;
3455 args.flags = flags;
3456
3457 memset(&ret, 0, sizeof(ret));
3458 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_FIND_STORAGE_POOL_SOURCES,
3459 (xdrproc_t) xdr_remote_connect_find_storage_pool_sources_args, (char *) &args,
3460 (xdrproc_t) xdr_remote_connect_find_storage_pool_sources_ret, (char *) &ret) == -1)
3461 goto done;
3462
3463 rv = g_steal_pointer(&ret.xml); /* To stop xdr_free free'ing it */
3464
3465 xdr_free((xdrproc_t) xdr_remote_connect_find_storage_pool_sources_ret, (char *) &ret);
3466
3467 done:
3468 remoteDriverUnlock(priv);
3469 return rv;
3470 }
3471
3472 /*----------------------------------------------------------------------*/
3473
3474 static int
remoteNodeDeviceDettach(virNodeDevicePtr dev)3475 remoteNodeDeviceDettach(virNodeDevicePtr dev)
3476 {
3477 int rv = -1;
3478 remote_node_device_dettach_args args;
3479 struct private_data *priv = dev->conn->privateData;
3480
3481 remoteDriverLock(priv);
3482
3483 args.name = dev->name;
3484
3485 if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DETTACH,
3486 (xdrproc_t) xdr_remote_node_device_dettach_args, (char *) &args,
3487 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3488 goto done;
3489
3490 rv = 0;
3491
3492 done:
3493 remoteDriverUnlock(priv);
3494 return rv;
3495 }
3496
3497 static int
remoteNodeDeviceDetachFlags(virNodeDevicePtr dev,const char * driverName,unsigned int flags)3498 remoteNodeDeviceDetachFlags(virNodeDevicePtr dev,
3499 const char *driverName,
3500 unsigned int flags)
3501 {
3502 int rv = -1;
3503 remote_node_device_detach_flags_args args;
3504 struct private_data *priv = dev->conn->privateData;
3505
3506 remoteDriverLock(priv);
3507
3508 args.name = dev->name;
3509 args.driverName = driverName ? (char**)&driverName : NULL;
3510 args.flags = flags;
3511
3512 if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DETACH_FLAGS,
3513 (xdrproc_t) xdr_remote_node_device_detach_flags_args,
3514 (char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1)
3515 goto done;
3516
3517 rv = 0;
3518
3519 done:
3520 remoteDriverUnlock(priv);
3521 return rv;
3522 }
3523
3524 static int
remoteNodeDeviceReAttach(virNodeDevicePtr dev)3525 remoteNodeDeviceReAttach(virNodeDevicePtr dev)
3526 {
3527 int rv = -1;
3528 remote_node_device_re_attach_args args;
3529 struct private_data *priv = dev->conn->privateData;
3530
3531 remoteDriverLock(priv);
3532
3533 args.name = dev->name;
3534
3535 if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RE_ATTACH,
3536 (xdrproc_t) xdr_remote_node_device_re_attach_args, (char *) &args,
3537 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3538 goto done;
3539
3540 rv = 0;
3541
3542 done:
3543 remoteDriverUnlock(priv);
3544 return rv;
3545 }
3546
3547 static int
remoteNodeDeviceReset(virNodeDevicePtr dev)3548 remoteNodeDeviceReset(virNodeDevicePtr dev)
3549 {
3550 int rv = -1;
3551 remote_node_device_reset_args args;
3552 /* This method is unusual in that it uses the HV driver, not the devMon driver
3553 * hence its use of privateData, instead of nodeDevicePrivateData */
3554 struct private_data *priv = dev->conn->privateData;
3555
3556 remoteDriverLock(priv);
3557
3558 args.name = dev->name;
3559
3560 if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RESET,
3561 (xdrproc_t) xdr_remote_node_device_reset_args, (char *) &args,
3562 (xdrproc_t) xdr_void, (char *) NULL) == -1)
3563 goto done;
3564
3565 rv = 0;
3566
3567 done:
3568 remoteDriverUnlock(priv);
3569 return rv;
3570 }
3571
3572
3573 /*----------------------------------------------------------------------*/
3574
3575 static int
remoteAuthenticate(virConnectPtr conn,struct private_data * priv,virConnectAuthPtr auth G_GNUC_UNUSED,const char * authtype)3576 remoteAuthenticate(virConnectPtr conn, struct private_data *priv,
3577 virConnectAuthPtr auth G_GNUC_UNUSED,
3578 const char *authtype)
3579 {
3580 struct remote_auth_list_ret ret;
3581 int err, type = REMOTE_AUTH_NONE;
3582
3583 memset(&ret, 0, sizeof(ret));
3584 err = call(conn, priv, 0,
3585 REMOTE_PROC_AUTH_LIST,
3586 (xdrproc_t) xdr_void, (char *) NULL,
3587 (xdrproc_t) xdr_remote_auth_list_ret, (char *) &ret);
3588 if (err < 0) {
3589 if (virGetLastErrorCode() == VIR_ERR_NO_SUPPORT) {
3590 /* Missing RPC - old server - ignore */
3591 virResetLastError();
3592 return 0;
3593 }
3594 return -1;
3595 }
3596
3597 if (ret.types.types_len == 0)
3598 return 0;
3599
3600 if (authtype) {
3601 int want;
3602 size_t i;
3603 if (STRCASEEQ(authtype, "sasl") ||
3604 STRCASEEQLEN(authtype, "sasl.", 5)) {
3605 want = REMOTE_AUTH_SASL;
3606 } else if (STRCASEEQ(authtype, "polkit")) {
3607 want = REMOTE_AUTH_POLKIT;
3608 } else {
3609 virReportError(VIR_ERR_AUTH_FAILED,
3610 _("unknown authentication type %s"), authtype);
3611 return -1;
3612 }
3613 for (i = 0; i < ret.types.types_len; i++) {
3614 if (ret.types.types_val[i] == want)
3615 type = want;
3616 }
3617 if (type == REMOTE_AUTH_NONE) {
3618 virReportError(VIR_ERR_AUTH_FAILED,
3619 _("requested authentication type %s rejected"),
3620 authtype);
3621 return -1;
3622 }
3623 } else {
3624 type = ret.types.types_val[0];
3625 }
3626
3627 switch (type) {
3628 #if WITH_SASL
3629 case REMOTE_AUTH_SASL: {
3630 const char *mech = NULL;
3631 if (authtype &&
3632 STRCASEEQLEN(authtype, "sasl.", 5))
3633 mech = authtype + 5;
3634
3635 if (remoteAuthSASL(conn, priv, auth, mech) < 0) {
3636 VIR_FREE(ret.types.types_val);
3637 return -1;
3638 }
3639 break;
3640 }
3641 #endif
3642
3643 case REMOTE_AUTH_POLKIT:
3644 if (remoteAuthPolkit(conn, priv, auth) < 0) {
3645 VIR_FREE(ret.types.types_val);
3646 return -1;
3647 }
3648 break;
3649
3650 case REMOTE_AUTH_NONE:
3651 /* Nothing todo, hurrah ! */
3652 break;
3653
3654 default:
3655 virReportError(VIR_ERR_AUTH_FAILED,
3656 _("unsupported authentication type %d"),
3657 ret.types.types_val[0]);
3658 VIR_FREE(ret.types.types_val);
3659 return -1;
3660 }
3661
3662 VIR_FREE(ret.types.types_val);
3663
3664 return 0;
3665 }
3666
3667
3668
3669 #if WITH_SASL
remoteAuthCredVir2SASL(int vircred)3670 static int remoteAuthCredVir2SASL(int vircred)
3671 {
3672 switch (vircred) {
3673 case VIR_CRED_USERNAME:
3674 return SASL_CB_USER;
3675
3676 case VIR_CRED_AUTHNAME:
3677 return SASL_CB_AUTHNAME;
3678
3679 case VIR_CRED_LANGUAGE:
3680 return SASL_CB_LANGUAGE;
3681
3682 case VIR_CRED_CNONCE:
3683 return SASL_CB_CNONCE;
3684
3685 case VIR_CRED_PASSPHRASE:
3686 return SASL_CB_PASS;
3687
3688 case VIR_CRED_ECHOPROMPT:
3689 return SASL_CB_ECHOPROMPT;
3690
3691 case VIR_CRED_NOECHOPROMPT:
3692 return SASL_CB_NOECHOPROMPT;
3693
3694 case VIR_CRED_REALM:
3695 return SASL_CB_GETREALM;
3696 }
3697
3698 return 0;
3699 }
3700
remoteAuthCredSASL2Vir(int vircred)3701 static int remoteAuthCredSASL2Vir(int vircred)
3702 {
3703 switch (vircred) {
3704 case SASL_CB_USER:
3705 return VIR_CRED_USERNAME;
3706
3707 case SASL_CB_AUTHNAME:
3708 return VIR_CRED_AUTHNAME;
3709
3710 case SASL_CB_LANGUAGE:
3711 return VIR_CRED_LANGUAGE;
3712
3713 case SASL_CB_CNONCE:
3714 return VIR_CRED_CNONCE;
3715
3716 case SASL_CB_PASS:
3717 return VIR_CRED_PASSPHRASE;
3718
3719 case SASL_CB_ECHOPROMPT:
3720 return VIR_CRED_ECHOPROMPT;
3721
3722 case SASL_CB_NOECHOPROMPT:
3723 return VIR_CRED_NOECHOPROMPT;
3724
3725 case SASL_CB_GETREALM:
3726 return VIR_CRED_REALM;
3727 }
3728
3729 return 0;
3730 }
3731
3732 /*
3733 * @param credtype array of credential types client supports
3734 * @param ncredtype size of credtype array
3735 * @return the SASL callback structure, or NULL on error
3736 *
3737 * Build up the SASL callback structure. We register one callback for
3738 * each credential type that the libvirt client indicated they support.
3739 * We explicitly leave the callback function pointer at NULL though,
3740 * because we don't actually want to get SASL callbacks triggered.
3741 * Instead, we want the start/step functions to return SASL_INTERACT.
3742 * This lets us give the libvirt client a list of all required
3743 * credentials in one go, rather than triggering the callback one
3744 * credential at a time,
3745 */
remoteAuthMakeCallbacks(int * credtype,int ncredtype)3746 static sasl_callback_t *remoteAuthMakeCallbacks(int *credtype, int ncredtype)
3747 {
3748 sasl_callback_t *cbs;
3749 size_t i;
3750 int n;
3751 cbs = g_new0(sasl_callback_t, ncredtype + 1);
3752
3753 for (i = 0, n = 0; i < ncredtype; i++) {
3754 int id = remoteAuthCredVir2SASL(credtype[i]);
3755 if (id != 0)
3756 cbs[n++].id = id;
3757 /* Don't fill proc or context fields of sasl_callback_t
3758 * because we want to use interactions instead */
3759 }
3760 cbs[n].id = 0;
3761 return cbs;
3762 }
3763
3764
3765 /*
3766 * @param interact SASL interactions required
3767 * @param cred populated with libvirt credential metadata
3768 * @return the size of the cred array returned
3769 *
3770 * Builds up an array of libvirt credential structs, populating
3771 * with data from the SASL interaction struct. These two structs
3772 * are basically a 1-to-1 copy of each other.
3773 */
remoteAuthMakeCredentials(sasl_interact_t * interact,virConnectCredentialPtr * cred,size_t * ncred)3774 static int remoteAuthMakeCredentials(sasl_interact_t *interact,
3775 virConnectCredentialPtr *cred,
3776 size_t *ncred)
3777 {
3778 int ninteract;
3779 if (!cred)
3780 return -1;
3781
3782 for (ninteract = 0, *ncred = 0; interact[ninteract].id != 0; ninteract++) {
3783 if (interact[ninteract].result)
3784 continue;
3785 (*ncred)++;
3786 }
3787
3788 *cred = g_new0(virConnectCredential, *ncred);
3789
3790 for (ninteract = 0, *ncred = 0; interact[ninteract].id != 0; ninteract++) {
3791 if (interact[ninteract].result)
3792 continue;
3793
3794 (*cred)[*ncred].type = remoteAuthCredSASL2Vir(interact[ninteract].id);
3795 if (!(*cred)[*ncred].type) {
3796 *ncred = 0;
3797 VIR_FREE(*cred);
3798 return -1;
3799 }
3800 if (interact[*ncred].challenge)
3801 (*cred)[*ncred].challenge = interact[ninteract].challenge;
3802 (*cred)[*ncred].prompt = interact[ninteract].prompt;
3803 if (interact[*ncred].defresult)
3804 (*cred)[*ncred].defresult = interact[ninteract].defresult;
3805 (*cred)[*ncred].result = NULL;
3806
3807 (*ncred)++;
3808 }
3809
3810 return 0;
3811 }
3812
3813
3814 /*
3815 * @param cred the populated libvirt credentials
3816 * @param interact the SASL interactions to fill in results for
3817 *
3818 * Fills the SASL interactions with the result from the libvirt
3819 * callbacks
3820 */
remoteAuthFillInteract(virConnectCredentialPtr cred,sasl_interact_t * interact)3821 static void remoteAuthFillInteract(virConnectCredentialPtr cred,
3822 sasl_interact_t *interact)
3823 {
3824 int ninteract, ncred;
3825 for (ninteract = 0, ncred = 0; interact[ninteract].id != 0; ninteract++) {
3826 if (interact[ninteract].result)
3827 continue;
3828 interact[ninteract].result = cred[ncred].result;
3829 interact[ninteract].len = cred[ncred].resultlen;
3830 ncred++;
3831 }
3832 }
3833
3834 struct remoteAuthInteractState {
3835 sasl_interact_t *interact;
3836 virConnectCredentialPtr cred;
3837 size_t ncred;
3838 virAuthConfig *config;
3839 };
3840
3841
3842
remoteAuthFillFromConfig(virConnectPtr conn,struct remoteAuthInteractState * state)3843 static int remoteAuthFillFromConfig(virConnectPtr conn,
3844 struct remoteAuthInteractState *state)
3845 {
3846 int ret = -1;
3847 int ninteract;
3848 const char *credname;
3849 char *path = NULL;
3850
3851 VIR_DEBUG("Trying to fill auth parameters from config file");
3852
3853 if (!state->config) {
3854 if (virAuthGetConfigFilePath(conn, &path) < 0)
3855 goto cleanup;
3856 if (path == NULL) {
3857 ret = 0;
3858 goto cleanup;
3859 }
3860
3861 if (!(state->config = virAuthConfigNew(path)))
3862 goto cleanup;
3863 }
3864
3865 for (ninteract = 0; state->interact[ninteract].id != 0; ninteract++) {
3866 char *value = NULL;
3867
3868 switch (state->interact[ninteract].id) {
3869 case SASL_CB_USER:
3870 credname = "username";
3871 break;
3872 case SASL_CB_AUTHNAME:
3873 credname = "authname";
3874 break;
3875 case SASL_CB_PASS:
3876 credname = "password";
3877 break;
3878 case SASL_CB_GETREALM:
3879 credname = "realm";
3880 break;
3881 default:
3882 credname = NULL;
3883 break;
3884 }
3885
3886 if (credname &&
3887 virAuthConfigLookup(state->config,
3888 "libvirt",
3889 VIR_URI_SERVER(conn->uri),
3890 credname,
3891 &value) < 0)
3892 goto cleanup;
3893
3894 if (value) {
3895 state->interact[ninteract].result = value;
3896 state->interact[ninteract].len = strlen(value);
3897 }
3898 }
3899
3900 ret = 0;
3901
3902 cleanup:
3903 VIR_FREE(path);
3904 return ret;
3905 }
3906
3907
remoteAuthInteractStateClear(struct remoteAuthInteractState * state,bool final)3908 static void remoteAuthInteractStateClear(struct remoteAuthInteractState *state,
3909 bool final)
3910 {
3911 size_t i;
3912 if (!state)
3913 return;
3914
3915 for (i = 0; i < state->ncred; i++)
3916 VIR_FREE(state->cred[i].result);
3917 VIR_FREE(state->cred);
3918 state->ncred = 0;
3919
3920 if (final)
3921 virAuthConfigFree(state->config);
3922 }
3923
3924
remoteAuthInteract(virConnectPtr conn,struct remoteAuthInteractState * state,virConnectAuthPtr auth)3925 static int remoteAuthInteract(virConnectPtr conn,
3926 struct remoteAuthInteractState *state,
3927 virConnectAuthPtr auth)
3928 {
3929 VIR_DEBUG("Starting SASL interaction");
3930 remoteAuthInteractStateClear(state, false);
3931
3932 /* Fills state->interact with any values from the auth config file */
3933 if (remoteAuthFillFromConfig(conn, state) < 0)
3934 return -1;
3935
3936 /* Populates state->cred for anything not found in the auth config */
3937 if (remoteAuthMakeCredentials(state->interact, &state->cred, &state->ncred) < 0) {
3938 virReportError(VIR_ERR_AUTH_FAILED, "%s",
3939 _("Failed to make auth credentials"));
3940 return -1;
3941 }
3942
3943 /* If there was anything not in the auth config, we need to
3944 * run the interactive callback
3945 */
3946 if (state->ncred) {
3947 /* Run the authentication callback */
3948 if (!auth || !auth->cb) {
3949 virReportError(VIR_ERR_AUTH_FAILED, "%s",
3950 _("No authentication callback available"));
3951 return -1;
3952 }
3953
3954 if ((*(auth->cb))(state->cred, state->ncred, auth->cbdata) < 0) {
3955 virReportError(VIR_ERR_AUTH_FAILED, "%s",
3956 _("Failed to collect auth credentials"));
3957 return -1;
3958 }
3959
3960 /* Copy user's responses from cred into interact */
3961 remoteAuthFillInteract(state->cred, state->interact);
3962 }
3963
3964 /*
3965 * 'interact' now has pointers to strings in 'state->cred'
3966 * so we must not free state->cred until the *next*
3967 * sasl_start/step function is complete. Hence we
3968 * call remoteAuthInteractStateClear() at the *start*
3969 * of this method, rather than the end.
3970 */
3971
3972 return 0;
3973 }
3974
3975
3976 /* Perform the SASL authentication process
3977 */
3978 static int
remoteAuthSASL(virConnectPtr conn,struct private_data * priv,virConnectAuthPtr auth,const char * wantmech)3979 remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
3980 virConnectAuthPtr auth, const char *wantmech)
3981 {
3982 remote_auth_sasl_init_ret iret;
3983 remote_auth_sasl_start_args sargs;
3984 remote_auth_sasl_start_ret sret;
3985 remote_auth_sasl_step_args pargs;
3986 remote_auth_sasl_step_ret pret;
3987 const char *clientout;
3988 char *serverin = NULL;
3989 size_t clientoutlen, serverinlen;
3990 const char *mech;
3991 int err, complete;
3992 int ssf;
3993 sasl_callback_t *saslcb = NULL;
3994 int ret = -1;
3995 const char *mechlist;
3996 virNetSASLContext *saslCtxt;
3997 virNetSASLSession *sasl = NULL;
3998 struct remoteAuthInteractState state;
3999
4000 memset(&state, 0, sizeof(state));
4001
4002 VIR_DEBUG("Client initialize SASL authentication");
4003
4004 if (!(saslCtxt = virNetSASLContextNewClient()))
4005 goto cleanup;
4006
4007 if (auth) {
4008 if ((saslcb = remoteAuthMakeCallbacks(auth->credtype, auth->ncredtype)) == NULL)
4009 goto cleanup;
4010 } else {
4011 saslcb = NULL;
4012 }
4013
4014 /* Setup a handle for being a client */
4015 if (!(sasl = virNetSASLSessionNewClient(saslCtxt,
4016 "libvirt",
4017 priv->hostname,
4018 virNetClientLocalAddrStringSASL(priv->client),
4019 virNetClientRemoteAddrStringSASL(priv->client),
4020 saslcb)))
4021 goto cleanup;
4022 /* saslcb is now owned by sasl */
4023 saslcb = NULL;
4024
4025 /* Initialize some connection props we care about */
4026 if (priv->tls) {
4027 if ((ssf = virNetClientGetTLSKeySize(priv->client)) < 0)
4028 goto cleanup;
4029
4030 ssf *= 8; /* key size is bytes, sasl wants bits */
4031
4032 VIR_DEBUG("Setting external SSF %d", ssf);
4033 if (virNetSASLSessionExtKeySize(sasl, ssf) < 0)
4034 goto cleanup;
4035 }
4036
4037 /* If we've got a secure channel (TLS or UNIX sock), we don't care about SSF */
4038 /* If we're not secure, then forbid any anonymous or trivially crackable auth */
4039 if (virNetSASLSessionSecProps(sasl,
4040 priv->is_secure ? 0 : 56, /* Equiv to DES supported by all Kerberos */
4041 priv->is_secure ? 0 : 100000, /* Very strong ! AES == 256 */
4042 priv->is_secure ? true : false) < 0)
4043 goto cleanup;
4044
4045 /* First call is to inquire about supported mechanisms in the server */
4046 memset(&iret, 0, sizeof(iret));
4047 if (call(conn, priv, 0, REMOTE_PROC_AUTH_SASL_INIT,
4048 (xdrproc_t) xdr_void, (char *)NULL,
4049 (xdrproc_t) xdr_remote_auth_sasl_init_ret, (char *) &iret) != 0)
4050 goto cleanup;
4051
4052
4053 mechlist = iret.mechlist;
4054 if (wantmech) {
4055 if (strstr(mechlist, wantmech) == NULL) {
4056 virReportError(VIR_ERR_AUTH_FAILED,
4057 _("SASL mechanism %s not supported by server"),
4058 wantmech);
4059 VIR_FREE(iret.mechlist);
4060 goto cleanup;
4061 }
4062 mechlist = wantmech;
4063 }
4064 restart:
4065 /* Start the auth negotiation on the client end first */
4066 VIR_DEBUG("Client start negotiation mechlist '%s'", mechlist);
4067 if ((err = virNetSASLSessionClientStart(sasl,
4068 mechlist,
4069 &state.interact,
4070 &clientout,
4071 &clientoutlen,
4072 &mech)) < 0)
4073 goto cleanup;
4074
4075 /* Need to gather some credentials from the client */
4076 if (err == VIR_NET_SASL_INTERACT) {
4077 if (remoteAuthInteract(conn, &state, auth) < 0) {
4078 VIR_FREE(iret.mechlist);
4079 goto cleanup;
4080 }
4081 goto restart;
4082 }
4083 VIR_FREE(iret.mechlist);
4084
4085 if (clientoutlen > REMOTE_AUTH_SASL_DATA_MAX) {
4086 virReportError(VIR_ERR_AUTH_FAILED,
4087 _("SASL negotiation data too long: %zu bytes"),
4088 clientoutlen);
4089 goto cleanup;
4090 }
4091 /* NB, distinction of NULL vs "" is *critical* in SASL */
4092 memset(&sargs, 0, sizeof(sargs));
4093 sargs.nil = clientout ? 0 : 1;
4094 sargs.data.data_val = (char*)clientout;
4095 sargs.data.data_len = clientoutlen;
4096 sargs.mech = (char*)mech;
4097 VIR_DEBUG("Server start negotiation with mech %s. Data %zu bytes %p",
4098 mech, clientoutlen, clientout);
4099
4100 /* Now send the initial auth data to the server */
4101 memset(&sret, 0, sizeof(sret));
4102 if (call(conn, priv, 0, REMOTE_PROC_AUTH_SASL_START,
4103 (xdrproc_t) xdr_remote_auth_sasl_start_args, (char *) &sargs,
4104 (xdrproc_t) xdr_remote_auth_sasl_start_ret, (char *) &sret) != 0)
4105 goto cleanup;
4106
4107 complete = sret.complete;
4108 /* NB, distinction of NULL vs "" is *critical* in SASL */
4109 serverin = sret.nil ? NULL : sret.data.data_val;
4110 serverinlen = sret.data.data_len;
4111 VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
4112 complete, serverinlen, serverin);
4113
4114 /* Previous server call showed completion & sasl_client_start() told us
4115 * we are locally complete too */
4116 if (complete && err == VIR_NET_SASL_COMPLETE)
4117 goto done;
4118
4119 /* Loop-the-loop...
4120 * Even if the server has completed, the client must *always* do at least one step
4121 * in this loop to verify the server isn't lying about something. Mutual auth */
4122 for (;;) {
4123 if ((err = virNetSASLSessionClientStep(sasl,
4124 serverin,
4125 serverinlen,
4126 &state.interact,
4127 &clientout,
4128 &clientoutlen)) < 0)
4129 goto cleanup;
4130
4131 /* Need to gather some credentials from the client */
4132 if (err == VIR_NET_SASL_INTERACT) {
4133 if (remoteAuthInteract(conn, &state, auth) < 0) {
4134 VIR_FREE(iret.mechlist);
4135 goto cleanup;
4136 }
4137 continue;
4138 }
4139
4140 VIR_FREE(serverin);
4141 VIR_DEBUG("Client step result %d. Data %zu bytes %p",
4142 err, clientoutlen, clientout);
4143
4144 /* Previous server call showed completion & we're now locally complete too */
4145 if (complete && err == VIR_NET_SASL_COMPLETE)
4146 break;
4147
4148 /* Not done, prepare to talk with the server for another iteration */
4149 /* NB, distinction of NULL vs "" is *critical* in SASL */
4150 memset(&pargs, 0, sizeof(pargs));
4151 pargs.nil = clientout ? 0 : 1;
4152 pargs.data.data_val = (char*)clientout;
4153 pargs.data.data_len = clientoutlen;
4154 VIR_DEBUG("Server step with %zu bytes %p",
4155 clientoutlen, clientout);
4156
4157 memset(&pret, 0, sizeof(pret));
4158 if (call(conn, priv, 0, REMOTE_PROC_AUTH_SASL_STEP,
4159 (xdrproc_t) xdr_remote_auth_sasl_step_args, (char *) &pargs,
4160 (xdrproc_t) xdr_remote_auth_sasl_step_ret, (char *) &pret) != 0)
4161 goto cleanup;
4162
4163 complete = pret.complete;
4164 /* NB, distinction of NULL vs "" is *critical* in SASL */
4165 serverin = pret.nil ? NULL : pret.data.data_val;
4166 serverinlen = pret.data.data_len;
4167
4168 VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
4169 complete, serverinlen, serverin);
4170
4171 /* This server call shows complete, and earlier client step was OK */
4172 if (complete && err == VIR_NET_SASL_COMPLETE) {
4173 VIR_FREE(serverin);
4174 break;
4175 }
4176 }
4177
4178 /* Check for suitable SSF if not already secure (TLS or UNIX sock) */
4179 if (!priv->is_secure) {
4180 if ((ssf = virNetSASLSessionGetKeySize(sasl)) < 0)
4181 goto cleanup;
4182
4183 VIR_DEBUG("SASL SSF value %d", ssf);
4184 if (ssf < 56) { /* 56 == DES level, good for Kerberos */
4185 virReportError(VIR_ERR_AUTH_FAILED,
4186 _("negotiation SSF %d was not strong enough"), ssf);
4187 goto cleanup;
4188 }
4189 if (ssf < SSF_WARNING_LEVEL) {
4190 VIR_WARN("negotiation SSF %d lower than %d will be deprecated. "
4191 "Please upgrade your ciphers.",
4192 ssf, SSF_WARNING_LEVEL);
4193 }
4194 priv->is_secure = 1;
4195 }
4196
4197 done:
4198 VIR_DEBUG("SASL authentication complete");
4199 virNetClientSetSASLSession(priv->client, sasl);
4200 ret = 0;
4201
4202 cleanup:
4203 VIR_FREE(serverin);
4204
4205 remoteAuthInteractStateClear(&state, true);
4206 VIR_FREE(saslcb);
4207 virObjectUnref(sasl);
4208 virObjectUnref(saslCtxt);
4209
4210 return ret;
4211 }
4212 #endif /* WITH_SASL */
4213
4214
4215 static int
remoteAuthPolkit(virConnectPtr conn,struct private_data * priv,virConnectAuthPtr auth G_GNUC_UNUSED)4216 remoteAuthPolkit(virConnectPtr conn, struct private_data *priv,
4217 virConnectAuthPtr auth G_GNUC_UNUSED)
4218 {
4219 remote_auth_polkit_ret ret;
4220 VIR_DEBUG("Client initialize PolicyKit authentication");
4221
4222 memset(&ret, 0, sizeof(ret));
4223 if (call(conn, priv, 0, REMOTE_PROC_AUTH_POLKIT,
4224 (xdrproc_t) xdr_void, (char *)NULL,
4225 (xdrproc_t) xdr_remote_auth_polkit_ret, (char *) &ret) != 0) {
4226 return -1; /* virError already set by call */
4227 }
4228
4229 VIR_DEBUG("PolicyKit authentication complete");
4230 return 0;
4231 }
4232
4233 /*----------------------------------------------------------------------*/
4234
4235 static int
remoteConnectDomainEventRegister(virConnectPtr conn,virConnectDomainEventCallback callback,void * opaque,virFreeCallback freecb)4236 remoteConnectDomainEventRegister(virConnectPtr conn,
4237 virConnectDomainEventCallback callback,
4238 void *opaque,
4239 virFreeCallback freecb)
4240 {
4241 int callbackID;
4242 int rv = -1;
4243 struct private_data *priv = conn->privateData;
4244 int count;
4245
4246 remoteDriverLock(priv);
4247
4248 if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
4249 NULL,
4250 VIR_DOMAIN_EVENT_ID_LIFECYCLE,
4251 VIR_DOMAIN_EVENT_CALLBACK(callback),
4252 opaque, freecb, true,
4253 &callbackID,
4254 priv->serverEventFilter)) < 0)
4255 goto done;
4256
4257 if (count == 1) {
4258 /* Tell the server when we are the first callback registering */
4259 if (priv->serverEventFilter) {
4260 remote_connect_domain_event_callback_register_any_args args;
4261 remote_connect_domain_event_callback_register_any_ret ret;
4262
4263 args.eventID = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
4264 args.dom = NULL;
4265
4266 memset(&ret, 0, sizeof(ret));
4267 if (call(conn, priv, 0,
4268 REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_REGISTER_ANY,
4269 (xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_args, (char *) &args,
4270 (xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_ret, (char *) &ret) == -1) {
4271 virObjectEventStateDeregisterID(conn, priv->eventState,
4272 callbackID, false);
4273 goto done;
4274 }
4275 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
4276 ret.callbackID);
4277 } else {
4278 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER,
4279 (xdrproc_t) xdr_void, (char *) NULL,
4280 (xdrproc_t) xdr_void, (char *) NULL) == -1) {
4281 virObjectEventStateDeregisterID(conn, priv->eventState,
4282 callbackID, false);
4283 goto done;
4284 }
4285 }
4286 }
4287
4288 rv = 0;
4289
4290 done:
4291 remoteDriverUnlock(priv);
4292 return rv;
4293 }
4294
4295
4296 static int
remoteConnectDomainEventDeregister(virConnectPtr conn,virConnectDomainEventCallback callback)4297 remoteConnectDomainEventDeregister(virConnectPtr conn,
4298 virConnectDomainEventCallback callback)
4299 {
4300 struct private_data *priv = conn->privateData;
4301 int rv = -1;
4302 remote_connect_domain_event_callback_deregister_any_args args;
4303 int callbackID;
4304 int remoteID;
4305 int count;
4306
4307 remoteDriverLock(priv);
4308
4309 if ((callbackID = virDomainEventStateCallbackID(conn, priv->eventState,
4310 callback,
4311 &remoteID)) < 0)
4312 goto done;
4313
4314 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
4315 callbackID, true)) < 0)
4316 goto done;
4317
4318 if (count == 0) {
4319 /* Tell the server when we are the last callback deregistering */
4320 if (priv->serverEventFilter) {
4321 args.callbackID = remoteID;
4322
4323 if (call(conn, priv, 0,
4324 REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_DEREGISTER_ANY,
4325 (xdrproc_t) xdr_remote_connect_domain_event_callback_deregister_any_args, (char *) &args,
4326 (xdrproc_t) xdr_void, (char *) NULL) == -1)
4327 goto done;
4328 } else {
4329 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_DEREGISTER,
4330 (xdrproc_t) xdr_void, (char *) NULL,
4331 (xdrproc_t) xdr_void, (char *) NULL) == -1)
4332 goto done;
4333 }
4334 }
4335
4336 rv = 0;
4337
4338 done:
4339 remoteDriverUnlock(priv);
4340 return rv;
4341 }
4342
4343
4344 static void
remoteDomainBuildEventLifecycleHelper(virConnectPtr conn,remote_domain_event_lifecycle_msg * msg,int callbackID)4345 remoteDomainBuildEventLifecycleHelper(virConnectPtr conn,
4346 remote_domain_event_lifecycle_msg *msg,
4347 int callbackID)
4348 {
4349 struct private_data *priv = conn->privateData;
4350 virDomainPtr dom;
4351 virObjectEvent *event = NULL;
4352
4353 dom = get_nonnull_domain(conn, msg->dom);
4354 if (!dom)
4355 return;
4356
4357 event = virDomainEventLifecycleNewFromDom(dom, msg->event, msg->detail);
4358 virObjectUnref(dom);
4359
4360 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4361 }
4362 static void
remoteDomainBuildEventLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4363 remoteDomainBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
4364 virNetClient *client G_GNUC_UNUSED,
4365 void *evdata, void *opaque)
4366 {
4367 virConnectPtr conn = opaque;
4368 remote_domain_event_lifecycle_msg *msg = evdata;
4369 remoteDomainBuildEventLifecycleHelper(conn, msg, -1);
4370 }
4371 static void
remoteDomainBuildEventCallbackLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4372 remoteDomainBuildEventCallbackLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
4373 virNetClient *client G_GNUC_UNUSED,
4374 void *evdata, void *opaque)
4375 {
4376 virConnectPtr conn = opaque;
4377 remote_domain_event_callback_lifecycle_msg *msg = evdata;
4378 remoteDomainBuildEventLifecycleHelper(conn, &msg->msg, msg->callbackID);
4379 }
4380
4381
4382 static void
remoteDomainBuildEventRebootHelper(virConnectPtr conn,remote_domain_event_reboot_msg * msg,int callbackID)4383 remoteDomainBuildEventRebootHelper(virConnectPtr conn,
4384 remote_domain_event_reboot_msg *msg,
4385 int callbackID)
4386 {
4387 struct private_data *priv = conn->privateData;
4388 virDomainPtr dom;
4389 virObjectEvent *event = NULL;
4390
4391 dom = get_nonnull_domain(conn, msg->dom);
4392 if (!dom)
4393 return;
4394
4395 event = virDomainEventRebootNewFromDom(dom);
4396 virObjectUnref(dom);
4397
4398 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4399 }
4400 static void
remoteDomainBuildEventReboot(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4401 remoteDomainBuildEventReboot(virNetClientProgram *prog G_GNUC_UNUSED,
4402 virNetClient *client G_GNUC_UNUSED,
4403 void *evdata, void *opaque)
4404 {
4405 virConnectPtr conn = opaque;
4406 remote_domain_event_reboot_msg *msg = evdata;
4407 remoteDomainBuildEventRebootHelper(conn, msg, -1);
4408 }
4409 static void
remoteDomainBuildEventCallbackReboot(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4410 remoteDomainBuildEventCallbackReboot(virNetClientProgram *prog G_GNUC_UNUSED,
4411 virNetClient *client G_GNUC_UNUSED,
4412 void *evdata, void *opaque)
4413 {
4414 virConnectPtr conn = opaque;
4415 remote_domain_event_callback_reboot_msg *msg = evdata;
4416 remoteDomainBuildEventRebootHelper(conn, &msg->msg, msg->callbackID);
4417 }
4418
4419 static void
remoteDomainBuildEventRTCChangeHelper(virConnectPtr conn,remote_domain_event_rtc_change_msg * msg,int callbackID)4420 remoteDomainBuildEventRTCChangeHelper(virConnectPtr conn,
4421 remote_domain_event_rtc_change_msg *msg,
4422 int callbackID)
4423 {
4424 struct private_data *priv = conn->privateData;
4425 virDomainPtr dom;
4426 virObjectEvent *event = NULL;
4427
4428 dom = get_nonnull_domain(conn, msg->dom);
4429 if (!dom)
4430 return;
4431
4432 event = virDomainEventRTCChangeNewFromDom(dom, msg->offset);
4433 virObjectUnref(dom);
4434
4435 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4436 }
4437 static void
remoteDomainBuildEventRTCChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4438 remoteDomainBuildEventRTCChange(virNetClientProgram *prog G_GNUC_UNUSED,
4439 virNetClient *client G_GNUC_UNUSED,
4440 void *evdata, void *opaque)
4441 {
4442 virConnectPtr conn = opaque;
4443 remote_domain_event_rtc_change_msg *msg = evdata;
4444 remoteDomainBuildEventRTCChangeHelper(conn, msg, -1);
4445 }
4446 static void
remoteDomainBuildEventCallbackRTCChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4447 remoteDomainBuildEventCallbackRTCChange(virNetClientProgram *prog G_GNUC_UNUSED,
4448 virNetClient *client G_GNUC_UNUSED,
4449 void *evdata, void *opaque)
4450 {
4451 virConnectPtr conn = opaque;
4452 remote_domain_event_callback_rtc_change_msg *msg = evdata;
4453 remoteDomainBuildEventRTCChangeHelper(conn, &msg->msg, msg->callbackID);
4454 }
4455
4456 static void
remoteDomainBuildEventWatchdogHelper(virConnectPtr conn,remote_domain_event_watchdog_msg * msg,int callbackID)4457 remoteDomainBuildEventWatchdogHelper(virConnectPtr conn,
4458 remote_domain_event_watchdog_msg *msg,
4459 int callbackID)
4460 {
4461 struct private_data *priv = conn->privateData;
4462 virDomainPtr dom;
4463 virObjectEvent *event = NULL;
4464
4465 dom = get_nonnull_domain(conn, msg->dom);
4466 if (!dom)
4467 return;
4468
4469 event = virDomainEventWatchdogNewFromDom(dom, msg->action);
4470 virObjectUnref(dom);
4471
4472 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4473 }
4474 static void
remoteDomainBuildEventWatchdog(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4475 remoteDomainBuildEventWatchdog(virNetClientProgram *prog G_GNUC_UNUSED,
4476 virNetClient *client G_GNUC_UNUSED,
4477 void *evdata, void *opaque)
4478 {
4479 virConnectPtr conn = opaque;
4480 remote_domain_event_watchdog_msg *msg = evdata;
4481 remoteDomainBuildEventWatchdogHelper(conn, msg, -1);
4482 }
4483 static void
remoteDomainBuildEventCallbackWatchdog(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4484 remoteDomainBuildEventCallbackWatchdog(virNetClientProgram *prog G_GNUC_UNUSED,
4485 virNetClient *client G_GNUC_UNUSED,
4486 void *evdata, void *opaque)
4487 {
4488 virConnectPtr conn = opaque;
4489 remote_domain_event_callback_watchdog_msg *msg = evdata;
4490 remoteDomainBuildEventWatchdogHelper(conn, &msg->msg, msg->callbackID);
4491 }
4492
4493 static void
remoteDomainBuildEventIOErrorHelper(virConnectPtr conn,remote_domain_event_io_error_msg * msg,int callbackID)4494 remoteDomainBuildEventIOErrorHelper(virConnectPtr conn,
4495 remote_domain_event_io_error_msg *msg,
4496 int callbackID)
4497 {
4498 struct private_data *priv = conn->privateData;
4499 virDomainPtr dom;
4500 virObjectEvent *event = NULL;
4501
4502 dom = get_nonnull_domain(conn, msg->dom);
4503 if (!dom)
4504 return;
4505
4506 event = virDomainEventIOErrorNewFromDom(dom,
4507 msg->srcPath,
4508 msg->devAlias,
4509 msg->action);
4510 virObjectUnref(dom);
4511
4512 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4513 }
4514 static void
remoteDomainBuildEventIOError(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4515 remoteDomainBuildEventIOError(virNetClientProgram *prog G_GNUC_UNUSED,
4516 virNetClient *client G_GNUC_UNUSED,
4517 void *evdata, void *opaque)
4518 {
4519 virConnectPtr conn = opaque;
4520 remote_domain_event_io_error_msg *msg = evdata;
4521 remoteDomainBuildEventIOErrorHelper(conn, msg, -1);
4522 }
4523 static void
remoteDomainBuildEventCallbackIOError(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4524 remoteDomainBuildEventCallbackIOError(virNetClientProgram *prog G_GNUC_UNUSED,
4525 virNetClient *client G_GNUC_UNUSED,
4526 void *evdata, void *opaque)
4527 {
4528 virConnectPtr conn = opaque;
4529 remote_domain_event_callback_io_error_msg *msg = evdata;
4530 remoteDomainBuildEventIOErrorHelper(conn, &msg->msg, msg->callbackID);
4531 }
4532
4533 static void
remoteDomainBuildEventIOErrorReasonHelper(virConnectPtr conn,remote_domain_event_io_error_reason_msg * msg,int callbackID)4534 remoteDomainBuildEventIOErrorReasonHelper(virConnectPtr conn,
4535 remote_domain_event_io_error_reason_msg *msg,
4536 int callbackID)
4537 {
4538 struct private_data *priv = conn->privateData;
4539 virDomainPtr dom;
4540 virObjectEvent *event = NULL;
4541
4542 dom = get_nonnull_domain(conn, msg->dom);
4543 if (!dom)
4544 return;
4545
4546 event = virDomainEventIOErrorReasonNewFromDom(dom,
4547 msg->srcPath,
4548 msg->devAlias,
4549 msg->action,
4550 msg->reason);
4551
4552 virObjectUnref(dom);
4553
4554 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4555 }
4556 static void
remoteDomainBuildEventIOErrorReason(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4557 remoteDomainBuildEventIOErrorReason(virNetClientProgram *prog G_GNUC_UNUSED,
4558 virNetClient *client G_GNUC_UNUSED,
4559 void *evdata, void *opaque)
4560 {
4561 virConnectPtr conn = opaque;
4562 remote_domain_event_io_error_reason_msg *msg = evdata;
4563 remoteDomainBuildEventIOErrorReasonHelper(conn, msg, -1);
4564 }
4565 static void
remoteDomainBuildEventCallbackIOErrorReason(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4566 remoteDomainBuildEventCallbackIOErrorReason(virNetClientProgram *prog G_GNUC_UNUSED,
4567 virNetClient *client G_GNUC_UNUSED,
4568 void *evdata, void *opaque)
4569 {
4570 virConnectPtr conn = opaque;
4571 remote_domain_event_callback_io_error_reason_msg *msg = evdata;
4572 remoteDomainBuildEventIOErrorReasonHelper(conn, &msg->msg, msg->callbackID);
4573 }
4574
4575 static void
remoteDomainBuildEventBlockJobHelper(virConnectPtr conn,remote_domain_event_block_job_msg * msg,int callbackID)4576 remoteDomainBuildEventBlockJobHelper(virConnectPtr conn,
4577 remote_domain_event_block_job_msg *msg,
4578 int callbackID)
4579 {
4580 struct private_data *priv = conn->privateData;
4581 virDomainPtr dom;
4582 virObjectEvent *event = NULL;
4583
4584 dom = get_nonnull_domain(conn, msg->dom);
4585 if (!dom)
4586 return;
4587
4588 event = virDomainEventBlockJobNewFromDom(dom, msg->path, msg->type,
4589 msg->status);
4590
4591 virObjectUnref(dom);
4592
4593 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4594 }
4595 static void
remoteDomainBuildEventBlockJob(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4596 remoteDomainBuildEventBlockJob(virNetClientProgram *prog G_GNUC_UNUSED,
4597 virNetClient *client G_GNUC_UNUSED,
4598 void *evdata, void *opaque)
4599 {
4600 virConnectPtr conn = opaque;
4601 remote_domain_event_block_job_msg *msg = evdata;
4602 remoteDomainBuildEventBlockJobHelper(conn, msg, -1);
4603 }
4604 static void
remoteDomainBuildEventCallbackBlockJob(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4605 remoteDomainBuildEventCallbackBlockJob(virNetClientProgram *prog G_GNUC_UNUSED,
4606 virNetClient *client G_GNUC_UNUSED,
4607 void *evdata, void *opaque)
4608 {
4609 virConnectPtr conn = opaque;
4610 remote_domain_event_callback_block_job_msg *msg = evdata;
4611 remoteDomainBuildEventBlockJobHelper(conn, &msg->msg, msg->callbackID);
4612 }
4613 static void
remoteDomainBuildEventBlockJob2(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4614 remoteDomainBuildEventBlockJob2(virNetClientProgram *prog G_GNUC_UNUSED,
4615 virNetClient *client G_GNUC_UNUSED,
4616 void *evdata, void *opaque)
4617 {
4618 virConnectPtr conn = opaque;
4619 remote_domain_event_block_job_2_msg *msg = evdata;
4620 struct private_data *priv = conn->privateData;
4621 virDomainPtr dom;
4622 virObjectEvent *event = NULL;
4623
4624 dom = get_nonnull_domain(conn, msg->dom);
4625 if (!dom)
4626 return;
4627
4628 event = virDomainEventBlockJob2NewFromDom(dom, msg->dst, msg->type,
4629 msg->status);
4630
4631 virObjectUnref(dom);
4632
4633 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
4634 }
4635
4636 static void
remoteDomainBuildEventGraphicsHelper(virConnectPtr conn,remote_domain_event_graphics_msg * msg,int callbackID)4637 remoteDomainBuildEventGraphicsHelper(virConnectPtr conn,
4638 remote_domain_event_graphics_msg *msg,
4639 int callbackID)
4640 {
4641 struct private_data *priv = conn->privateData;
4642 virDomainPtr dom;
4643 virObjectEvent *event = NULL;
4644 virDomainEventGraphicsAddressPtr localAddr = NULL;
4645 virDomainEventGraphicsAddressPtr remoteAddr = NULL;
4646 virDomainEventGraphicsSubjectPtr subject = NULL;
4647 size_t i;
4648
4649 dom = get_nonnull_domain(conn, msg->dom);
4650 if (!dom)
4651 return;
4652
4653 localAddr = g_new0(virDomainEventGraphicsAddress, 1);
4654 localAddr->family = msg->local.family;
4655 localAddr->service = g_strdup(msg->local.service);
4656 localAddr->node = g_strdup(msg->local.node);
4657
4658 remoteAddr = g_new0(virDomainEventGraphicsAddress, 1);
4659 remoteAddr->family = msg->remote.family;
4660 remoteAddr->service = g_strdup(msg->remote.service);
4661 remoteAddr->node = g_strdup(msg->remote.node);
4662
4663 subject = g_new0(virDomainEventGraphicsSubject, 1);
4664 subject->identities = g_new0(virDomainEventGraphicsSubjectIdentity, msg->subject.subject_len);
4665 subject->nidentity = msg->subject.subject_len;
4666 for (i = 0; i < subject->nidentity; i++) {
4667 subject->identities[i].type = g_strdup(msg->subject.subject_val[i].type);
4668 subject->identities[i].name = g_strdup(msg->subject.subject_val[i].name);
4669 }
4670
4671 event = virDomainEventGraphicsNewFromDom(dom,
4672 msg->phase,
4673 localAddr,
4674 remoteAddr,
4675 msg->authScheme,
4676 subject);
4677
4678 virObjectUnref(dom);
4679
4680 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4681 return;
4682 }
4683 static void
remoteDomainBuildEventGraphics(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4684 remoteDomainBuildEventGraphics(virNetClientProgram *prog G_GNUC_UNUSED,
4685 virNetClient *client G_GNUC_UNUSED,
4686 void *evdata, void *opaque)
4687 {
4688 virConnectPtr conn = opaque;
4689 remote_domain_event_graphics_msg *msg = evdata;
4690 remoteDomainBuildEventGraphicsHelper(conn, msg, -1);
4691 }
4692 static void
remoteDomainBuildEventCallbackGraphics(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4693 remoteDomainBuildEventCallbackGraphics(virNetClientProgram *prog G_GNUC_UNUSED,
4694 virNetClient *client G_GNUC_UNUSED,
4695 void *evdata, void *opaque)
4696 {
4697 virConnectPtr conn = opaque;
4698 remote_domain_event_callback_graphics_msg *msg = evdata;
4699 remoteDomainBuildEventGraphicsHelper(conn, &msg->msg, msg->callbackID);
4700 }
4701
4702 static void
remoteDomainBuildEventControlErrorHelper(virConnectPtr conn,remote_domain_event_control_error_msg * msg,int callbackID)4703 remoteDomainBuildEventControlErrorHelper(virConnectPtr conn,
4704 remote_domain_event_control_error_msg *msg,
4705 int callbackID)
4706 {
4707 struct private_data *priv = conn->privateData;
4708 virDomainPtr dom;
4709 virObjectEvent *event = NULL;
4710
4711 dom = get_nonnull_domain(conn, msg->dom);
4712 if (!dom)
4713 return;
4714
4715 event = virDomainEventControlErrorNewFromDom(dom);
4716
4717 virObjectUnref(dom);
4718
4719 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4720 }
4721 static void
remoteDomainBuildEventControlError(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4722 remoteDomainBuildEventControlError(virNetClientProgram *prog G_GNUC_UNUSED,
4723 virNetClient *client G_GNUC_UNUSED,
4724 void *evdata, void *opaque)
4725 {
4726 virConnectPtr conn = opaque;
4727 remote_domain_event_control_error_msg *msg = evdata;
4728 remoteDomainBuildEventControlErrorHelper(conn, msg, -1);
4729 }
4730 static void
remoteDomainBuildEventCallbackControlError(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4731 remoteDomainBuildEventCallbackControlError(virNetClientProgram *prog G_GNUC_UNUSED,
4732 virNetClient *client G_GNUC_UNUSED,
4733 void *evdata, void *opaque)
4734 {
4735 virConnectPtr conn = opaque;
4736 remote_domain_event_callback_control_error_msg *msg = evdata;
4737 remoteDomainBuildEventControlErrorHelper(conn, &msg->msg, msg->callbackID);
4738 }
4739
4740
4741 static void
remoteDomainBuildEventDiskChangeHelper(virConnectPtr conn,remote_domain_event_disk_change_msg * msg,int callbackID)4742 remoteDomainBuildEventDiskChangeHelper(virConnectPtr conn,
4743 remote_domain_event_disk_change_msg *msg,
4744 int callbackID)
4745 {
4746 struct private_data *priv = conn->privateData;
4747 virDomainPtr dom;
4748 virObjectEvent *event = NULL;
4749
4750 dom = get_nonnull_domain(conn, msg->dom);
4751 if (!dom)
4752 return;
4753
4754 event = virDomainEventDiskChangeNewFromDom(dom,
4755 msg->oldSrcPath ? *msg->oldSrcPath : NULL,
4756 msg->newSrcPath ? *msg->newSrcPath : NULL,
4757 msg->devAlias,
4758 msg->reason);
4759
4760 virObjectUnref(dom);
4761
4762 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4763 }
4764 static void
remoteDomainBuildEventDiskChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4765 remoteDomainBuildEventDiskChange(virNetClientProgram *prog G_GNUC_UNUSED,
4766 virNetClient *client G_GNUC_UNUSED,
4767 void *evdata, void *opaque)
4768 {
4769 virConnectPtr conn = opaque;
4770 remote_domain_event_disk_change_msg *msg = evdata;
4771 remoteDomainBuildEventDiskChangeHelper(conn, msg, -1);
4772 }
4773 static void
remoteDomainBuildEventCallbackDiskChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4774 remoteDomainBuildEventCallbackDiskChange(virNetClientProgram *prog G_GNUC_UNUSED,
4775 virNetClient *client G_GNUC_UNUSED,
4776 void *evdata, void *opaque)
4777 {
4778 virConnectPtr conn = opaque;
4779 remote_domain_event_callback_disk_change_msg *msg = evdata;
4780 remoteDomainBuildEventDiskChangeHelper(conn, &msg->msg, msg->callbackID);
4781 }
4782
4783
4784 static void
remoteDomainBuildEventTrayChangeHelper(virConnectPtr conn,remote_domain_event_tray_change_msg * msg,int callbackID)4785 remoteDomainBuildEventTrayChangeHelper(virConnectPtr conn,
4786 remote_domain_event_tray_change_msg *msg,
4787 int callbackID)
4788 {
4789 struct private_data *priv = conn->privateData;
4790 virDomainPtr dom;
4791 virObjectEvent *event = NULL;
4792
4793 dom = get_nonnull_domain(conn, msg->dom);
4794 if (!dom)
4795 return;
4796
4797 event = virDomainEventTrayChangeNewFromDom(dom,
4798 msg->devAlias,
4799 msg->reason);
4800
4801 virObjectUnref(dom);
4802
4803 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4804 }
4805 static void
remoteDomainBuildEventTrayChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4806 remoteDomainBuildEventTrayChange(virNetClientProgram *prog G_GNUC_UNUSED,
4807 virNetClient *client G_GNUC_UNUSED,
4808 void *evdata, void *opaque)
4809 {
4810 virConnectPtr conn = opaque;
4811 remote_domain_event_tray_change_msg *msg = evdata;
4812 remoteDomainBuildEventTrayChangeHelper(conn, msg, -1);
4813 }
4814 static void
remoteDomainBuildEventCallbackTrayChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4815 remoteDomainBuildEventCallbackTrayChange(virNetClientProgram *prog G_GNUC_UNUSED,
4816 virNetClient *client G_GNUC_UNUSED,
4817 void *evdata, void *opaque)
4818 {
4819 virConnectPtr conn = opaque;
4820 remote_domain_event_callback_tray_change_msg *msg = evdata;
4821 remoteDomainBuildEventTrayChangeHelper(conn, &msg->msg, msg->callbackID);
4822 }
4823
4824 static void
remoteDomainBuildEventPMWakeupHelper(virConnectPtr conn,remote_domain_event_pmwakeup_msg * msg,int callbackID,int reason)4825 remoteDomainBuildEventPMWakeupHelper(virConnectPtr conn,
4826 remote_domain_event_pmwakeup_msg *msg,
4827 int callbackID,
4828 int reason)
4829 {
4830 struct private_data *priv = conn->privateData;
4831 virDomainPtr dom;
4832 virObjectEvent *event = NULL;
4833
4834 dom = get_nonnull_domain(conn, msg->dom);
4835 if (!dom)
4836 return;
4837
4838 event = virDomainEventPMWakeupNewFromDom(dom, reason);
4839
4840 virObjectUnref(dom);
4841
4842 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4843 }
4844 static void
remoteDomainBuildEventPMWakeup(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4845 remoteDomainBuildEventPMWakeup(virNetClientProgram *prog G_GNUC_UNUSED,
4846 virNetClient *client G_GNUC_UNUSED,
4847 void *evdata, void *opaque)
4848 {
4849 virConnectPtr conn = opaque;
4850 remote_domain_event_pmwakeup_msg *msg = evdata;
4851 remoteDomainBuildEventPMWakeupHelper(conn, msg, -1, 0);
4852 }
4853 static void
remoteDomainBuildEventCallbackPMWakeup(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4854 remoteDomainBuildEventCallbackPMWakeup(virNetClientProgram *prog G_GNUC_UNUSED,
4855 virNetClient *client G_GNUC_UNUSED,
4856 void *evdata, void *opaque)
4857 {
4858 virConnectPtr conn = opaque;
4859 remote_domain_event_callback_pmwakeup_msg *msg = evdata;
4860 remoteDomainBuildEventPMWakeupHelper(conn, &msg->msg, msg->callbackID,
4861 msg->reason);
4862 }
4863
4864 static void
remoteDomainBuildEventPMSuspendHelper(virConnectPtr conn,remote_domain_event_pmsuspend_msg * msg,int callbackID,int reason)4865 remoteDomainBuildEventPMSuspendHelper(virConnectPtr conn,
4866 remote_domain_event_pmsuspend_msg *msg,
4867 int callbackID,
4868 int reason)
4869 {
4870 struct private_data *priv = conn->privateData;
4871 virDomainPtr dom;
4872 virObjectEvent *event = NULL;
4873
4874 dom = get_nonnull_domain(conn, msg->dom);
4875 if (!dom)
4876 return;
4877
4878 event = virDomainEventPMSuspendNewFromDom(dom, reason);
4879
4880 virObjectUnref(dom);
4881
4882 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4883 }
4884 static void
remoteDomainBuildEventPMSuspend(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4885 remoteDomainBuildEventPMSuspend(virNetClientProgram *prog G_GNUC_UNUSED,
4886 virNetClient *client G_GNUC_UNUSED,
4887 void *evdata, void *opaque)
4888 {
4889 virConnectPtr conn = opaque;
4890 remote_domain_event_pmsuspend_msg *msg = evdata;
4891 remoteDomainBuildEventPMSuspendHelper(conn, msg, -1, 0);
4892 }
4893 static void
remoteDomainBuildEventCallbackPMSuspend(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4894 remoteDomainBuildEventCallbackPMSuspend(virNetClientProgram *prog G_GNUC_UNUSED,
4895 virNetClient *client G_GNUC_UNUSED,
4896 void *evdata, void *opaque)
4897 {
4898 virConnectPtr conn = opaque;
4899 remote_domain_event_callback_pmsuspend_msg *msg = evdata;
4900 remoteDomainBuildEventPMSuspendHelper(conn, &msg->msg, msg->callbackID,
4901 msg->reason);
4902 }
4903
4904
4905 static void
remoteDomainBuildEventBalloonChangeHelper(virConnectPtr conn,remote_domain_event_balloon_change_msg * msg,int callbackID)4906 remoteDomainBuildEventBalloonChangeHelper(virConnectPtr conn,
4907 remote_domain_event_balloon_change_msg *msg,
4908 int callbackID)
4909 {
4910 struct private_data *priv = conn->privateData;
4911 virDomainPtr dom;
4912 virObjectEvent *event = NULL;
4913
4914 dom = get_nonnull_domain(conn, msg->dom);
4915 if (!dom)
4916 return;
4917
4918 event = virDomainEventBalloonChangeNewFromDom(dom, msg->actual);
4919 virObjectUnref(dom);
4920
4921 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4922 }
4923 static void
remoteDomainBuildEventBalloonChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4924 remoteDomainBuildEventBalloonChange(virNetClientProgram *prog G_GNUC_UNUSED,
4925 virNetClient *client G_GNUC_UNUSED,
4926 void *evdata, void *opaque)
4927 {
4928 virConnectPtr conn = opaque;
4929 remote_domain_event_balloon_change_msg *msg = evdata;
4930 remoteDomainBuildEventBalloonChangeHelper(conn, msg, -1);
4931 }
4932 static void
remoteDomainBuildEventCallbackBalloonChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4933 remoteDomainBuildEventCallbackBalloonChange(virNetClientProgram *prog G_GNUC_UNUSED,
4934 virNetClient *client G_GNUC_UNUSED,
4935 void *evdata, void *opaque)
4936 {
4937 virConnectPtr conn = opaque;
4938 remote_domain_event_callback_balloon_change_msg *msg = evdata;
4939 remoteDomainBuildEventBalloonChangeHelper(conn, &msg->msg, msg->callbackID);
4940 }
4941
4942
4943 static void
remoteDomainBuildEventPMSuspendDiskHelper(virConnectPtr conn,remote_domain_event_pmsuspend_disk_msg * msg,int callbackID,int reason)4944 remoteDomainBuildEventPMSuspendDiskHelper(virConnectPtr conn,
4945 remote_domain_event_pmsuspend_disk_msg *msg,
4946 int callbackID,
4947 int reason)
4948 {
4949 struct private_data *priv = conn->privateData;
4950 virDomainPtr dom;
4951 virObjectEvent *event = NULL;
4952
4953 dom = get_nonnull_domain(conn, msg->dom);
4954 if (!dom)
4955 return;
4956
4957 event = virDomainEventPMSuspendDiskNewFromDom(dom, reason);
4958
4959 virObjectUnref(dom);
4960
4961 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
4962 }
4963 static void
remoteDomainBuildEventPMSuspendDisk(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4964 remoteDomainBuildEventPMSuspendDisk(virNetClientProgram *prog G_GNUC_UNUSED,
4965 virNetClient *client G_GNUC_UNUSED,
4966 void *evdata, void *opaque)
4967 {
4968 virConnectPtr conn = opaque;
4969 remote_domain_event_pmsuspend_disk_msg *msg = evdata;
4970 remoteDomainBuildEventPMSuspendDiskHelper(conn, msg, -1, 0);
4971 }
4972 static void
remoteDomainBuildEventCallbackPMSuspendDisk(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)4973 remoteDomainBuildEventCallbackPMSuspendDisk(virNetClientProgram *prog G_GNUC_UNUSED,
4974 virNetClient *client G_GNUC_UNUSED,
4975 void *evdata, void *opaque)
4976 {
4977 virConnectPtr conn = opaque;
4978 remote_domain_event_callback_pmsuspend_disk_msg *msg = evdata;
4979 remoteDomainBuildEventPMSuspendDiskHelper(conn, &msg->msg, msg->callbackID,
4980 msg->reason);
4981 }
4982
4983
4984 static void
remoteDomainBuildEventDeviceRemovedHelper(virConnectPtr conn,remote_domain_event_device_removed_msg * msg,int callbackID)4985 remoteDomainBuildEventDeviceRemovedHelper(virConnectPtr conn,
4986 remote_domain_event_device_removed_msg *msg,
4987 int callbackID)
4988 {
4989 struct private_data *priv = conn->privateData;
4990 virDomainPtr dom;
4991 virObjectEvent *event = NULL;
4992
4993 dom = get_nonnull_domain(conn, msg->dom);
4994 if (!dom)
4995 return;
4996
4997 event = virDomainEventDeviceRemovedNewFromDom(dom, msg->devAlias);
4998
4999 virObjectUnref(dom);
5000
5001 virObjectEventStateQueueRemote(priv->eventState, event, callbackID);
5002 }
5003 static void
remoteDomainBuildEventDeviceRemoved(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5004 remoteDomainBuildEventDeviceRemoved(virNetClientProgram *prog G_GNUC_UNUSED,
5005 virNetClient *client G_GNUC_UNUSED,
5006 void *evdata, void *opaque)
5007 {
5008 virConnectPtr conn = opaque;
5009 remote_domain_event_device_removed_msg *msg = evdata;
5010 remoteDomainBuildEventDeviceRemovedHelper(conn, msg, -1);
5011 }
5012 static void
remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5013 remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgram *prog G_GNUC_UNUSED,
5014 virNetClient *client G_GNUC_UNUSED,
5015 void *evdata, void *opaque)
5016 {
5017 virConnectPtr conn = opaque;
5018 remote_domain_event_callback_device_removed_msg *msg = evdata;
5019 remoteDomainBuildEventDeviceRemovedHelper(conn, &msg->msg, msg->callbackID);
5020 }
5021
5022 static void
remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5023 remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgram *prog G_GNUC_UNUSED,
5024 virNetClient *client G_GNUC_UNUSED,
5025 void *evdata, void *opaque)
5026 {
5027 virConnectPtr conn = opaque;
5028 remote_domain_event_callback_device_added_msg *msg = evdata;
5029 struct private_data *priv = conn->privateData;
5030 virDomainPtr dom;
5031 virObjectEvent *event = NULL;
5032
5033 dom = get_nonnull_domain(conn, msg->dom);
5034 if (!dom)
5035 return;
5036
5037 event = virDomainEventDeviceAddedNewFromDom(dom, msg->devAlias);
5038
5039 virObjectUnref(dom);
5040
5041 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5042 }
5043
5044
5045 static void
remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5046 remoteDomainBuildEventCallbackDeviceRemovalFailed(virNetClientProgram *prog G_GNUC_UNUSED,
5047 virNetClient *client G_GNUC_UNUSED,
5048 void *evdata, void *opaque)
5049 {
5050 virConnectPtr conn = opaque;
5051 remote_domain_event_callback_device_removal_failed_msg *msg = evdata;
5052 struct private_data *priv = conn->privateData;
5053 virDomainPtr dom;
5054 virObjectEvent *event = NULL;
5055
5056 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5057 return;
5058
5059 event = virDomainEventDeviceRemovalFailedNewFromDom(dom, msg->devAlias);
5060
5061 virObjectUnref(dom);
5062
5063 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5064 }
5065
5066 static void
remoteDomainBuildEventCallbackTunable(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5067 remoteDomainBuildEventCallbackTunable(virNetClientProgram *prog G_GNUC_UNUSED,
5068 virNetClient *client G_GNUC_UNUSED,
5069 void *evdata, void *opaque)
5070 {
5071 virConnectPtr conn = opaque;
5072 remote_domain_event_callback_tunable_msg *msg = evdata;
5073 struct private_data *priv = conn->privateData;
5074 virDomainPtr dom;
5075 virTypedParameterPtr params = NULL;
5076 int nparams = 0;
5077 virObjectEvent *event = NULL;
5078
5079 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) msg->params.params_val,
5080 msg->params.params_len,
5081 REMOTE_DOMAIN_EVENT_TUNABLE_MAX,
5082 ¶ms, &nparams) < 0)
5083 return;
5084
5085 dom = get_nonnull_domain(conn, msg->dom);
5086 if (!dom) {
5087 virTypedParamsFree(params, nparams);
5088 return;
5089 }
5090
5091 event = virDomainEventTunableNewFromDom(dom, params, nparams);
5092
5093 virObjectUnref(dom);
5094
5095 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5096 }
5097
5098
5099 static void
remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5100 remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
5101 virNetClient *client G_GNUC_UNUSED,
5102 void *evdata, void *opaque)
5103 {
5104 virConnectPtr conn = opaque;
5105 remote_domain_event_callback_agent_lifecycle_msg *msg = evdata;
5106 struct private_data *priv = conn->privateData;
5107 virDomainPtr dom;
5108 virObjectEvent *event = NULL;
5109
5110 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5111 return;
5112
5113 event = virDomainEventAgentLifecycleNewFromDom(dom, msg->state,
5114 msg->reason);
5115
5116 virObjectUnref(dom);
5117
5118 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5119 }
5120
5121
5122 static void
remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5123 remoteDomainBuildEventCallbackMigrationIteration(virNetClientProgram *prog G_GNUC_UNUSED,
5124 virNetClient *client G_GNUC_UNUSED,
5125 void *evdata,
5126 void *opaque)
5127 {
5128 virConnectPtr conn = opaque;
5129 remote_domain_event_callback_migration_iteration_msg *msg = evdata;
5130 struct private_data *priv = conn->privateData;
5131 virDomainPtr dom;
5132 virObjectEvent *event = NULL;
5133
5134 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5135 return;
5136
5137 event = virDomainEventMigrationIterationNewFromDom(dom, msg->iteration);
5138
5139 virObjectUnref(dom);
5140
5141 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5142 }
5143
5144
5145 static void
remoteDomainBuildEventCallbackJobCompleted(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5146 remoteDomainBuildEventCallbackJobCompleted(virNetClientProgram *prog G_GNUC_UNUSED,
5147 virNetClient *client G_GNUC_UNUSED,
5148 void *evdata,
5149 void *opaque)
5150 {
5151 virConnectPtr conn = opaque;
5152 remote_domain_event_callback_job_completed_msg *msg = evdata;
5153 struct private_data *priv = conn->privateData;
5154 virDomainPtr dom;
5155 virObjectEvent *event = NULL;
5156 virTypedParameterPtr params = NULL;
5157 int nparams = 0;
5158
5159 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) msg->params.params_val,
5160 msg->params.params_len,
5161 REMOTE_DOMAIN_JOB_STATS_MAX,
5162 ¶ms, &nparams) < 0)
5163 return;
5164
5165 if (!(dom = get_nonnull_domain(conn, msg->dom))) {
5166 virTypedParamsFree(params, nparams);
5167 return;
5168 }
5169
5170 event = virDomainEventJobCompletedNewFromDom(dom, params, nparams);
5171
5172 virObjectUnref(dom);
5173
5174 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5175 }
5176
5177
5178 static void
remoteDomainBuildEventCallbackMetadataChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5179 remoteDomainBuildEventCallbackMetadataChange(virNetClientProgram *prog G_GNUC_UNUSED,
5180 virNetClient *client G_GNUC_UNUSED,
5181 void *evdata, void *opaque)
5182 {
5183 virConnectPtr conn = opaque;
5184 remote_domain_event_callback_metadata_change_msg *msg = evdata;
5185 struct private_data *priv = conn->privateData;
5186 virDomainPtr dom;
5187 virObjectEvent *event = NULL;
5188
5189 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5190 return;
5191
5192 event = virDomainEventMetadataChangeNewFromDom(dom, msg->type, msg->nsuri ? *msg->nsuri : NULL);
5193
5194 virObjectUnref(dom);
5195
5196 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5197 }
5198
5199
5200 static void
remoteNetworkBuildEventLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5201 remoteNetworkBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
5202 virNetClient *client G_GNUC_UNUSED,
5203 void *evdata, void *opaque)
5204 {
5205 virConnectPtr conn = opaque;
5206 struct private_data *priv = conn->privateData;
5207 remote_network_event_lifecycle_msg *msg = evdata;
5208 virNetworkPtr net;
5209 virObjectEvent *event = NULL;
5210
5211 net = get_nonnull_network(conn, msg->net);
5212 if (!net)
5213 return;
5214
5215 event = virNetworkEventLifecycleNew(net->name, net->uuid, msg->event,
5216 msg->detail);
5217 virObjectUnref(net);
5218
5219 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5220 }
5221
5222 static void
remoteStoragePoolBuildEventLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5223 remoteStoragePoolBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
5224 virNetClient *client G_GNUC_UNUSED,
5225 void *evdata, void *opaque)
5226 {
5227 virConnectPtr conn = opaque;
5228 struct private_data *priv = conn->privateData;
5229 remote_storage_pool_event_lifecycle_msg *msg = evdata;
5230 virStoragePoolPtr pool;
5231 virObjectEvent *event = NULL;
5232
5233 pool = get_nonnull_storage_pool(conn, msg->pool);
5234 if (!pool)
5235 return;
5236
5237 event = virStoragePoolEventLifecycleNew(pool->name, pool->uuid, msg->event,
5238 msg->detail);
5239 virObjectUnref(pool);
5240
5241 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5242 }
5243
5244 static void
remoteStoragePoolBuildEventRefresh(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5245 remoteStoragePoolBuildEventRefresh(virNetClientProgram *prog G_GNUC_UNUSED,
5246 virNetClient *client G_GNUC_UNUSED,
5247 void *evdata, void *opaque)
5248 {
5249 virConnectPtr conn = opaque;
5250 struct private_data *priv = conn->privateData;
5251 remote_storage_pool_event_refresh_msg *msg = evdata;
5252 virStoragePoolPtr pool;
5253 virObjectEvent *event = NULL;
5254
5255 pool = get_nonnull_storage_pool(conn, msg->pool);
5256 if (!pool)
5257 return;
5258
5259 event = virStoragePoolEventRefreshNew(pool->name, pool->uuid);
5260 virObjectUnref(pool);
5261
5262 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5263 }
5264
5265 static void
remoteNodeDeviceBuildEventLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5266 remoteNodeDeviceBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
5267 virNetClient *client G_GNUC_UNUSED,
5268 void *evdata, void *opaque)
5269 {
5270 virConnectPtr conn = opaque;
5271 struct private_data *priv = conn->privateData;
5272 remote_node_device_event_lifecycle_msg *msg = evdata;
5273 virNodeDevicePtr dev;
5274 virObjectEvent *event = NULL;
5275
5276 dev = get_nonnull_node_device(conn, msg->dev);
5277 if (!dev)
5278 return;
5279
5280 event = virNodeDeviceEventLifecycleNew(dev->name, msg->event,
5281 msg->detail);
5282 virObjectUnref(dev);
5283
5284 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5285 }
5286
5287 static void
remoteNodeDeviceBuildEventUpdate(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5288 remoteNodeDeviceBuildEventUpdate(virNetClientProgram *prog G_GNUC_UNUSED,
5289 virNetClient *client G_GNUC_UNUSED,
5290 void *evdata, void *opaque)
5291 {
5292 virConnectPtr conn = opaque;
5293 struct private_data *priv = conn->privateData;
5294 remote_node_device_event_update_msg *msg = evdata;
5295 virNodeDevicePtr dev;
5296 virObjectEvent *event = NULL;
5297
5298 dev = get_nonnull_node_device(conn, msg->dev);
5299 if (!dev)
5300 return;
5301
5302 event = virNodeDeviceEventUpdateNew(dev->name);
5303 virObjectUnref(dev);
5304
5305 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5306 }
5307
5308 static void
remoteSecretBuildEventLifecycle(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5309 remoteSecretBuildEventLifecycle(virNetClientProgram *prog G_GNUC_UNUSED,
5310 virNetClient *client G_GNUC_UNUSED,
5311 void *evdata, void *opaque)
5312 {
5313 virConnectPtr conn = opaque;
5314 struct private_data *priv = conn->privateData;
5315 remote_secret_event_lifecycle_msg *msg = evdata;
5316 virSecretPtr secret;
5317 virObjectEvent *event = NULL;
5318
5319 secret = get_nonnull_secret(conn, msg->secret);
5320 if (!secret)
5321 return;
5322
5323 event = virSecretEventLifecycleNew(secret->uuid, secret->usageType, secret->usageID,
5324 msg->event, msg->detail);
5325 virObjectUnref(secret);
5326
5327 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5328 }
5329
5330 static void
remoteSecretBuildEventValueChanged(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5331 remoteSecretBuildEventValueChanged(virNetClientProgram *prog G_GNUC_UNUSED,
5332 virNetClient *client G_GNUC_UNUSED,
5333 void *evdata, void *opaque)
5334 {
5335 virConnectPtr conn = opaque;
5336 struct private_data *priv = conn->privateData;
5337 remote_secret_event_value_changed_msg *msg = evdata;
5338 virSecretPtr secret;
5339 virObjectEvent *event = NULL;
5340
5341 secret = get_nonnull_secret(conn, msg->secret);
5342 if (!secret)
5343 return;
5344
5345 event = virSecretEventValueChangedNew(secret->uuid, secret->usageType, secret->usageID);
5346 virObjectUnref(secret);
5347
5348 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5349 }
5350
5351 static void
remoteDomainBuildQemuMonitorEvent(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5352 remoteDomainBuildQemuMonitorEvent(virNetClientProgram *prog G_GNUC_UNUSED,
5353 virNetClient *client G_GNUC_UNUSED,
5354 void *evdata, void *opaque)
5355 {
5356 virConnectPtr conn = opaque;
5357 struct private_data *priv = conn->privateData;
5358 qemu_domain_monitor_event_msg *msg = evdata;
5359 virDomainPtr dom;
5360 virObjectEvent *event = NULL;
5361
5362 dom = get_nonnull_domain(conn, msg->dom);
5363 if (!dom)
5364 return;
5365
5366 event = virDomainQemuMonitorEventNew(dom->id, dom->name, dom->uuid,
5367 msg->event, msg->seconds,
5368 msg->micros,
5369 msg->details ? *msg->details : NULL);
5370 virObjectUnref(dom);
5371
5372 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5373 }
5374
5375
5376 static unsigned char *
remoteSecretGetValue(virSecretPtr secret,size_t * value_size,unsigned int flags)5377 remoteSecretGetValue(virSecretPtr secret, size_t *value_size,
5378 unsigned int flags)
5379 {
5380 unsigned char *rv = NULL;
5381 remote_secret_get_value_args args;
5382 remote_secret_get_value_ret ret;
5383 struct private_data *priv = secret->conn->privateData;
5384
5385 remoteDriverLock(priv);
5386
5387 make_nonnull_secret(&args.secret, secret);
5388 args.flags = flags;
5389
5390 memset(&ret, 0, sizeof(ret));
5391 if (call(secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_VALUE,
5392 (xdrproc_t) xdr_remote_secret_get_value_args, (char *) &args,
5393 (xdrproc_t) xdr_remote_secret_get_value_ret, (char *) &ret) == -1)
5394 goto done;
5395
5396 *value_size = ret.value.value_len;
5397 rv = (unsigned char *) ret.value.value_val; /* Caller frees. */
5398
5399 done:
5400 remoteDriverUnlock(priv);
5401 return rv;
5402 }
5403
5404
5405 static void
remoteDomainBuildEventBlockThreshold(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5406 remoteDomainBuildEventBlockThreshold(virNetClientProgram *prog G_GNUC_UNUSED,
5407 virNetClient *client G_GNUC_UNUSED,
5408 void *evdata, void *opaque)
5409 {
5410 virConnectPtr conn = opaque;
5411 remote_domain_event_block_threshold_msg *msg = evdata;
5412 struct private_data *priv = conn->privateData;
5413 virDomainPtr dom;
5414 virObjectEvent *event = NULL;
5415
5416 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5417 return;
5418
5419 event = virDomainEventBlockThresholdNewFromDom(dom, msg->dev,
5420 msg->path ? *msg->path : NULL,
5421 msg->threshold, msg->excess);
5422
5423 virObjectUnref(dom);
5424
5425 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5426 }
5427
5428
5429 static void
remoteDomainBuildEventMemoryFailure(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5430 remoteDomainBuildEventMemoryFailure(virNetClientProgram *prog G_GNUC_UNUSED,
5431 virNetClient *client G_GNUC_UNUSED,
5432 void *evdata, void *opaque)
5433 {
5434 virConnectPtr conn = opaque;
5435 remote_domain_event_memory_failure_msg *msg = evdata;
5436 struct private_data *priv = conn->privateData;
5437 virDomainPtr dom;
5438 virObjectEvent *event = NULL;
5439
5440 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5441 return;
5442
5443 event = virDomainEventMemoryFailureNewFromDom(dom, msg->recipient,
5444 msg->action, msg->flags);
5445
5446 virObjectUnref(dom);
5447
5448 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5449 }
5450
5451
5452 static void
remoteDomainBuildEventMemoryDeviceSizeChange(virNetClientProgram * prog G_GNUC_UNUSED,virNetClient * client G_GNUC_UNUSED,void * evdata,void * opaque)5453 remoteDomainBuildEventMemoryDeviceSizeChange(virNetClientProgram *prog G_GNUC_UNUSED,
5454 virNetClient *client G_GNUC_UNUSED,
5455 void *evdata, void *opaque)
5456 {
5457 virConnectPtr conn = opaque;
5458 remote_domain_event_memory_device_size_change_msg *msg = evdata;
5459 struct private_data *priv = conn->privateData;
5460 virDomainPtr dom;
5461 virObjectEvent *event = NULL;
5462
5463 if (!(dom = get_nonnull_domain(conn, msg->dom)))
5464 return;
5465
5466 event = virDomainEventMemoryDeviceSizeChangeNewFromDom(dom,
5467 msg->alias,
5468 msg->size);
5469
5470 virObjectUnref(dom);
5471
5472 virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackID);
5473 }
5474
5475
5476 static int
remoteStreamSend(virStreamPtr st,const char * data,size_t nbytes)5477 remoteStreamSend(virStreamPtr st,
5478 const char *data,
5479 size_t nbytes)
5480 {
5481 struct private_data *priv = st->conn->privateData;
5482 virNetClientStream *privst = st->privateData;
5483 int rv;
5484
5485 VIR_DEBUG("st=%p data=%p nbytes=%zu", st, data, nbytes);
5486
5487 remoteDriverLock(priv);
5488 priv->localUses++;
5489 remoteDriverUnlock(priv);
5490
5491 rv = virNetClientStreamSendPacket(privst,
5492 priv->client,
5493 VIR_NET_CONTINUE,
5494 data,
5495 nbytes);
5496
5497 remoteDriverLock(priv);
5498 priv->localUses--;
5499 remoteDriverUnlock(priv);
5500 return rv;
5501 }
5502
5503
5504 static int
remoteStreamRecvFlags(virStreamPtr st,char * data,size_t nbytes,unsigned int flags)5505 remoteStreamRecvFlags(virStreamPtr st,
5506 char *data,
5507 size_t nbytes,
5508 unsigned int flags)
5509 {
5510 struct private_data *priv = st->conn->privateData;
5511 virNetClientStream *privst = st->privateData;
5512 int rv;
5513
5514 VIR_DEBUG("st=%p data=%p nbytes=%zu flags=0x%x",
5515 st, data, nbytes, flags);
5516
5517 virCheckFlags(VIR_STREAM_RECV_STOP_AT_HOLE, -1);
5518
5519 remoteDriverLock(priv);
5520 priv->localUses++;
5521 remoteDriverUnlock(priv);
5522
5523 rv = virNetClientStreamRecvPacket(privst,
5524 priv->client,
5525 data,
5526 nbytes,
5527 (st->flags & VIR_STREAM_NONBLOCK),
5528 flags);
5529
5530 VIR_DEBUG("Done %d", rv);
5531
5532 remoteDriverLock(priv);
5533 priv->localUses--;
5534 remoteDriverUnlock(priv);
5535 return rv;
5536 }
5537
5538 static int
remoteStreamRecv(virStreamPtr st,char * data,size_t nbytes)5539 remoteStreamRecv(virStreamPtr st,
5540 char *data,
5541 size_t nbytes)
5542 {
5543 return remoteStreamRecvFlags(st, data, nbytes, 0);
5544 }
5545
5546
5547 static int
remoteStreamSendHole(virStreamPtr st,long long length,unsigned int flags)5548 remoteStreamSendHole(virStreamPtr st,
5549 long long length,
5550 unsigned int flags)
5551 {
5552 struct private_data *priv = st->conn->privateData;
5553 virNetClientStream *privst = st->privateData;
5554 int rv;
5555
5556 VIR_DEBUG("st=%p length=%lld flags=0x%x",
5557 st, length, flags);
5558
5559 remoteDriverLock(priv);
5560 priv->localUses++;
5561 remoteDriverUnlock(priv);
5562
5563 rv = virNetClientStreamSendHole(privst,
5564 priv->client,
5565 length,
5566 flags);
5567
5568 remoteDriverLock(priv);
5569 priv->localUses--;
5570 remoteDriverUnlock(priv);
5571 return rv;
5572 }
5573
5574
5575 static int
remoteStreamRecvHole(virStreamPtr st,long long * length,unsigned int flags)5576 remoteStreamRecvHole(virStreamPtr st,
5577 long long *length,
5578 unsigned int flags)
5579 {
5580 struct private_data *priv = st->conn->privateData;
5581 virNetClientStream *privst = st->privateData;
5582 int rv;
5583
5584 VIR_DEBUG("st=%p length=%p flags=0x%x",
5585 st, length, flags);
5586
5587 virCheckFlags(0, -1);
5588
5589 remoteDriverLock(priv);
5590 priv->localUses++;
5591 remoteDriverUnlock(priv);
5592
5593 rv = virNetClientStreamRecvHole(priv->client, privst, length);
5594
5595 remoteDriverLock(priv);
5596 priv->localUses--;
5597 remoteDriverUnlock(priv);
5598 return rv;
5599 }
5600
5601
5602 struct remoteStreamCallbackData {
5603 virStreamPtr st;
5604 virStreamEventCallback cb;
5605 void *opaque;
5606 virFreeCallback ff;
5607 };
5608
remoteStreamEventCallback(virNetClientStream * stream G_GNUC_UNUSED,int events,void * opaque)5609 static void remoteStreamEventCallback(virNetClientStream *stream G_GNUC_UNUSED,
5610 int events,
5611 void *opaque)
5612 {
5613 struct remoteStreamCallbackData *cbdata = opaque;
5614
5615 (cbdata->cb)(cbdata->st, events, cbdata->opaque);
5616 }
5617
5618
remoteStreamCallbackFree(void * opaque)5619 static void remoteStreamCallbackFree(void *opaque)
5620 {
5621 struct remoteStreamCallbackData *cbdata = opaque;
5622
5623 if (!cbdata->cb && cbdata->ff)
5624 (cbdata->ff)(cbdata->opaque);
5625
5626 virObjectUnref(cbdata->st);
5627 g_free(opaque);
5628 }
5629
5630
5631 static int
remoteStreamEventAddCallback(virStreamPtr st,int events,virStreamEventCallback cb,void * opaque,virFreeCallback ff)5632 remoteStreamEventAddCallback(virStreamPtr st,
5633 int events,
5634 virStreamEventCallback cb,
5635 void *opaque,
5636 virFreeCallback ff)
5637 {
5638 struct private_data *priv = st->conn->privateData;
5639 virNetClientStream *privst = st->privateData;
5640 int ret = -1;
5641 struct remoteStreamCallbackData *cbdata;
5642
5643 cbdata = g_new0(struct remoteStreamCallbackData, 1);
5644 cbdata->cb = cb;
5645 cbdata->opaque = opaque;
5646 cbdata->ff = ff;
5647 cbdata->st = st;
5648 virStreamRef(st);
5649
5650 remoteDriverLock(priv);
5651
5652 if ((ret = virNetClientStreamEventAddCallback(privst,
5653 events,
5654 remoteStreamEventCallback,
5655 cbdata,
5656 remoteStreamCallbackFree)) < 0) {
5657 VIR_FREE(cbdata);
5658 goto cleanup;
5659 }
5660
5661 cleanup:
5662 remoteDriverUnlock(priv);
5663 return ret;
5664 }
5665
5666
5667 static int
remoteStreamEventUpdateCallback(virStreamPtr st,int events)5668 remoteStreamEventUpdateCallback(virStreamPtr st,
5669 int events)
5670 {
5671 struct private_data *priv = st->conn->privateData;
5672 virNetClientStream *privst = st->privateData;
5673 int ret = -1;
5674
5675 remoteDriverLock(priv);
5676
5677 ret = virNetClientStreamEventUpdateCallback(privst, events);
5678
5679 remoteDriverUnlock(priv);
5680 return ret;
5681 }
5682
5683
5684 static int
remoteStreamEventRemoveCallback(virStreamPtr st)5685 remoteStreamEventRemoveCallback(virStreamPtr st)
5686 {
5687 struct private_data *priv = st->conn->privateData;
5688 virNetClientStream *privst = st->privateData;
5689 int ret = -1;
5690
5691 remoteDriverLock(priv);
5692
5693 ret = virNetClientStreamEventRemoveCallback(privst);
5694
5695 remoteDriverUnlock(priv);
5696 return ret;
5697 }
5698
5699
5700 static int
remoteStreamCloseInt(virStreamPtr st,bool streamAbort)5701 remoteStreamCloseInt(virStreamPtr st, bool streamAbort)
5702 {
5703 struct private_data *priv = st->conn->privateData;
5704 virNetClientStream *privst = st->privateData;
5705 int ret = -1;
5706
5707 remoteDriverLock(priv);
5708
5709 priv->localUses++;
5710 remoteDriverUnlock(priv);
5711
5712 ret = virNetClientStreamSendPacket(privst,
5713 priv->client,
5714 streamAbort ? VIR_NET_ERROR : VIR_NET_OK,
5715 NULL,
5716 0);
5717
5718 remoteDriverLock(priv);
5719 priv->localUses--;
5720
5721 virNetClientRemoveStream(priv->client, privst);
5722
5723 remoteDriverUnlock(priv);
5724 return ret;
5725 }
5726
5727
5728 static int
remoteStreamFinish(virStreamPtr st)5729 remoteStreamFinish(virStreamPtr st)
5730 {
5731 return remoteStreamCloseInt(st, false);
5732 }
5733
5734
5735 static int
remoteStreamAbort(virStreamPtr st)5736 remoteStreamAbort(virStreamPtr st)
5737 {
5738 return remoteStreamCloseInt(st, true);
5739 }
5740
5741
5742 static virStreamDriver remoteStreamDrv = {
5743 .streamRecv = remoteStreamRecv,
5744 .streamRecvFlags = remoteStreamRecvFlags,
5745 .streamSend = remoteStreamSend,
5746 .streamSendHole = remoteStreamSendHole,
5747 .streamRecvHole = remoteStreamRecvHole,
5748 .streamFinish = remoteStreamFinish,
5749 .streamAbort = remoteStreamAbort,
5750 .streamEventAddCallback = remoteStreamEventAddCallback,
5751 .streamEventUpdateCallback = remoteStreamEventUpdateCallback,
5752 .streamEventRemoveCallback = remoteStreamEventRemoveCallback,
5753 };
5754
5755
5756 static int
remoteConnectDomainEventRegisterAny(virConnectPtr conn,virDomainPtr dom,int eventID,virConnectDomainEventGenericCallback callback,void * opaque,virFreeCallback freecb)5757 remoteConnectDomainEventRegisterAny(virConnectPtr conn,
5758 virDomainPtr dom,
5759 int eventID,
5760 virConnectDomainEventGenericCallback callback,
5761 void *opaque,
5762 virFreeCallback freecb)
5763 {
5764 int rv = -1;
5765 struct private_data *priv = conn->privateData;
5766 int callbackID;
5767 int count;
5768 remote_nonnull_domain domain;
5769
5770 remoteDriverLock(priv);
5771
5772 if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
5773 dom, eventID, callback,
5774 opaque, freecb, false,
5775 &callbackID,
5776 priv->serverEventFilter)) < 0)
5777 goto done;
5778
5779 /* If this is the first callback for this eventID, we need to enable
5780 * events on the server */
5781 if (count == 1) {
5782 if (priv->serverEventFilter) {
5783 remote_connect_domain_event_callback_register_any_args args;
5784 remote_connect_domain_event_callback_register_any_ret ret;
5785
5786 args.eventID = eventID;
5787 if (dom) {
5788 make_nonnull_domain(&domain, dom);
5789 args.dom = &domain;
5790 } else {
5791 args.dom = NULL;
5792 }
5793
5794 memset(&ret, 0, sizeof(ret));
5795 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_REGISTER_ANY,
5796 (xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_args, (char *) &args,
5797 (xdrproc_t) xdr_remote_connect_domain_event_callback_register_any_ret, (char *) &ret) == -1) {
5798 virObjectEventStateDeregisterID(conn, priv->eventState,
5799 callbackID, false);
5800 goto done;
5801 }
5802 virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
5803 ret.callbackID);
5804 } else {
5805 remote_connect_domain_event_register_any_args args;
5806
5807 args.eventID = eventID;
5808
5809 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY,
5810 (xdrproc_t) xdr_remote_connect_domain_event_register_any_args, (char *) &args,
5811 (xdrproc_t) xdr_void, (char *)NULL) == -1) {
5812 virObjectEventStateDeregisterID(conn, priv->eventState,
5813 callbackID, false);
5814 goto done;
5815 }
5816 }
5817 }
5818
5819 rv = callbackID;
5820
5821 done:
5822 remoteDriverUnlock(priv);
5823 return rv;
5824 }
5825
5826
5827 static int
remoteConnectDomainEventDeregisterAny(virConnectPtr conn,int callbackID)5828 remoteConnectDomainEventDeregisterAny(virConnectPtr conn,
5829 int callbackID)
5830 {
5831 struct private_data *priv = conn->privateData;
5832 int rv = -1;
5833 int eventID;
5834 int remoteID;
5835 int count;
5836
5837 remoteDriverLock(priv);
5838
5839 if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
5840 callbackID, &remoteID)) < 0)
5841 goto done;
5842
5843 if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
5844 callbackID, true)) < 0)
5845 goto done;
5846
5847 /* If that was the last callback for this eventID, we need to disable
5848 * events on the server */
5849 if (count == 0) {
5850 if (priv->serverEventFilter) {
5851 remote_connect_domain_event_callback_deregister_any_args args;
5852
5853 args.callbackID = remoteID;
5854
5855 if (call(conn, priv, 0,
5856 REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_DEREGISTER_ANY,
5857 (xdrproc_t) xdr_remote_connect_domain_event_callback_deregister_any_args, (char *) &args,
5858 (xdrproc_t) xdr_void, (char *) NULL) == -1)
5859 goto done;
5860 } else {
5861 remote_connect_domain_event_deregister_any_args args;
5862
5863 args.eventID = eventID;
5864
5865 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_DEREGISTER_ANY,
5866 (xdrproc_t) xdr_remote_connect_domain_event_deregister_any_args, (char *) &args,
5867 (xdrproc_t) xdr_void, (char *) NULL) == -1)
5868 goto done;
5869 }
5870 }
5871
5872 rv = 0;
5873
5874 done:
5875 remoteDriverUnlock(priv);
5876 return rv;
5877 }
5878
5879
5880 /*----------------------------------------------------------------------*/
5881
5882 static int
remoteDomainQemuMonitorCommand(virDomainPtr domain,const char * cmd,char ** result,unsigned int flags)5883 remoteDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
5884 char **result, unsigned int flags)
5885 {
5886 int rv = -1;
5887 qemu_domain_monitor_command_args args;
5888 qemu_domain_monitor_command_ret ret;
5889 struct private_data *priv = domain->conn->privateData;
5890
5891 remoteDriverLock(priv);
5892
5893 make_nonnull_domain(&args.dom, domain);
5894 args.cmd = (char *)cmd;
5895 args.flags = flags;
5896
5897 memset(&ret, 0, sizeof(ret));
5898 if (call(domain->conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_DOMAIN_MONITOR_COMMAND,
5899 (xdrproc_t) xdr_qemu_domain_monitor_command_args, (char *) &args,
5900 (xdrproc_t) xdr_qemu_domain_monitor_command_ret, (char *) &ret) == -1)
5901 goto done;
5902
5903 *result = g_strdup(ret.result);
5904
5905 rv = 0;
5906
5907 xdr_free((xdrproc_t) xdr_qemu_domain_monitor_command_ret, (char *) &ret);
5908
5909 done:
5910 remoteDriverUnlock(priv);
5911 return rv;
5912 }
5913
5914
5915 static char *
remoteDomainMigrateBegin3(virDomainPtr domain,const char * xmlin,char ** cookieout,int * cookieoutlen,unsigned long flags,const char * dname,unsigned long resource)5916 remoteDomainMigrateBegin3(virDomainPtr domain,
5917 const char *xmlin,
5918 char **cookieout,
5919 int *cookieoutlen,
5920 unsigned long flags,
5921 const char *dname,
5922 unsigned long resource)
5923 {
5924 char *rv = NULL;
5925 remote_domain_migrate_begin3_args args;
5926 remote_domain_migrate_begin3_ret ret;
5927 struct private_data *priv = domain->conn->privateData;
5928
5929 remoteDriverLock(priv);
5930
5931 memset(&args, 0, sizeof(args));
5932 memset(&ret, 0, sizeof(ret));
5933
5934 make_nonnull_domain(&args.dom, domain);
5935 args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
5936 args.flags = flags;
5937 args.dname = dname == NULL ? NULL : (char **) &dname;
5938 args.resource = resource;
5939
5940 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3,
5941 (xdrproc_t) xdr_remote_domain_migrate_begin3_args, (char *) &args,
5942 (xdrproc_t) xdr_remote_domain_migrate_begin3_ret, (char *) &ret) == -1)
5943 goto done;
5944
5945 if (ret.cookie_out.cookie_out_len > 0) {
5946 if (!cookieout || !cookieoutlen) {
5947 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
5948 _("caller ignores cookieout or cookieoutlen"));
5949 goto error;
5950 }
5951 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
5952 *cookieoutlen = ret.cookie_out.cookie_out_len;
5953 }
5954
5955 rv = ret.xml; /* caller frees */
5956
5957 done:
5958 remoteDriverUnlock(priv);
5959 return rv;
5960
5961 error:
5962 VIR_FREE(ret.cookie_out.cookie_out_val);
5963 goto done;
5964 }
5965
5966
5967 static int
remoteDomainMigratePrepare3(virConnectPtr dconn,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,const char * uri_in,char ** uri_out,unsigned long flags,const char * dname,unsigned long resource,const char * dom_xml)5968 remoteDomainMigratePrepare3(virConnectPtr dconn,
5969 const char *cookiein,
5970 int cookieinlen,
5971 char **cookieout,
5972 int *cookieoutlen,
5973 const char *uri_in,
5974 char **uri_out,
5975 unsigned long flags,
5976 const char *dname,
5977 unsigned long resource,
5978 const char *dom_xml)
5979 {
5980 int rv = -1;
5981 remote_domain_migrate_prepare3_args args;
5982 remote_domain_migrate_prepare3_ret ret;
5983 struct private_data *priv = dconn->privateData;
5984
5985 remoteDriverLock(priv);
5986
5987 memset(&args, 0, sizeof(args));
5988 memset(&ret, 0, sizeof(ret));
5989
5990 args.cookie_in.cookie_in_val = (char *)cookiein;
5991 args.cookie_in.cookie_in_len = cookieinlen;
5992 args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
5993 args.flags = flags;
5994 args.dname = dname == NULL ? NULL : (char **) &dname;
5995 args.resource = resource;
5996 args.dom_xml = (char *) dom_xml;
5997
5998 memset(&ret, 0, sizeof(ret));
5999 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3,
6000 (xdrproc_t) xdr_remote_domain_migrate_prepare3_args, (char *) &args,
6001 (xdrproc_t) xdr_remote_domain_migrate_prepare3_ret, (char *) &ret) == -1)
6002 goto done;
6003
6004 if (ret.cookie_out.cookie_out_len > 0) {
6005 if (!cookieout || !cookieoutlen) {
6006 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6007 _("caller ignores cookieout or cookieoutlen"));
6008 goto error;
6009 }
6010 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
6011 *cookieoutlen = ret.cookie_out.cookie_out_len;
6012 }
6013 if (ret.uri_out) {
6014 if (!uri_out) {
6015 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6016 _("caller ignores uri_out"));
6017 goto error;
6018 }
6019 *uri_out = *ret.uri_out; /* Caller frees. */
6020 }
6021
6022 rv = 0;
6023
6024 done:
6025 VIR_FREE(ret.uri_out);
6026 remoteDriverUnlock(priv);
6027 return rv;
6028 error:
6029 VIR_FREE(ret.cookie_out.cookie_out_val);
6030 if (ret.uri_out)
6031 VIR_FREE(*ret.uri_out);
6032 goto done;
6033 }
6034
6035
6036 static int
remoteDomainMigratePrepareTunnel3(virConnectPtr dconn,virStreamPtr st,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,unsigned long flags,const char * dname,unsigned long resource,const char * dom_xml)6037 remoteDomainMigratePrepareTunnel3(virConnectPtr dconn,
6038 virStreamPtr st,
6039 const char *cookiein,
6040 int cookieinlen,
6041 char **cookieout,
6042 int *cookieoutlen,
6043 unsigned long flags,
6044 const char *dname,
6045 unsigned long resource,
6046 const char *dom_xml)
6047 {
6048 struct private_data *priv = dconn->privateData;
6049 int rv = -1;
6050 remote_domain_migrate_prepare_tunnel3_args args;
6051 remote_domain_migrate_prepare_tunnel3_ret ret;
6052 virNetClientStream *netst;
6053
6054 remoteDriverLock(priv);
6055
6056 memset(&args, 0, sizeof(args));
6057 memset(&ret, 0, sizeof(ret));
6058
6059 if (!(netst = virNetClientStreamNew(priv->remoteProgram,
6060 REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
6061 priv->counter,
6062 false)))
6063 goto done;
6064
6065 if (virNetClientAddStream(priv->client, netst) < 0) {
6066 virObjectUnref(netst);
6067 goto done;
6068 }
6069
6070 st->driver = &remoteStreamDrv;
6071 st->privateData = netst;
6072 st->ff = virObjectFreeCallback;
6073
6074 args.cookie_in.cookie_in_val = (char *)cookiein;
6075 args.cookie_in.cookie_in_len = cookieinlen;
6076 args.flags = flags;
6077 args.dname = dname == NULL ? NULL : (char **) &dname;
6078 args.resource = resource;
6079 args.dom_xml = (char *) dom_xml;
6080
6081 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
6082 (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_args, (char *) &args,
6083 (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_ret, (char *) &ret) == -1) {
6084 virNetClientRemoveStream(priv->client, netst);
6085 virObjectUnref(netst);
6086 goto done;
6087 }
6088
6089 if (ret.cookie_out.cookie_out_len > 0) {
6090 if (!cookieout || !cookieoutlen) {
6091 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6092 _("caller ignores cookieout or cookieoutlen"));
6093 goto error;
6094 }
6095 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
6096 *cookieoutlen = ret.cookie_out.cookie_out_len;
6097 }
6098
6099 rv = 0;
6100
6101 done:
6102 remoteDriverUnlock(priv);
6103 return rv;
6104
6105 error:
6106 VIR_FREE(ret.cookie_out.cookie_out_val);
6107 goto done;
6108 }
6109
6110
6111 static int
remoteDomainMigratePerform3(virDomainPtr dom,const char * xmlin,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,const char * dconnuri,const char * uri,unsigned long flags,const char * dname,unsigned long resource)6112 remoteDomainMigratePerform3(virDomainPtr dom,
6113 const char *xmlin,
6114 const char *cookiein,
6115 int cookieinlen,
6116 char **cookieout,
6117 int *cookieoutlen,
6118 const char *dconnuri,
6119 const char *uri,
6120 unsigned long flags,
6121 const char *dname,
6122 unsigned long resource)
6123 {
6124 int rv = -1;
6125 remote_domain_migrate_perform3_args args;
6126 remote_domain_migrate_perform3_ret ret;
6127 struct private_data *priv = dom->conn->privateData;
6128
6129 remoteDriverLock(priv);
6130
6131 memset(&args, 0, sizeof(args));
6132 memset(&ret, 0, sizeof(ret));
6133
6134 make_nonnull_domain(&args.dom, dom);
6135
6136 args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
6137 args.cookie_in.cookie_in_val = (char *)cookiein;
6138 args.cookie_in.cookie_in_len = cookieinlen;
6139 args.flags = flags;
6140 args.dname = dname == NULL ? NULL : (char **) &dname;
6141 args.uri = uri == NULL ? NULL : (char **) &uri;
6142 args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
6143 args.resource = resource;
6144
6145 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3,
6146 (xdrproc_t) xdr_remote_domain_migrate_perform3_args, (char *) &args,
6147 (xdrproc_t) xdr_remote_domain_migrate_perform3_ret, (char *) &ret) == -1)
6148 goto done;
6149
6150 if (ret.cookie_out.cookie_out_len > 0) {
6151 if (!cookieout || !cookieoutlen) {
6152 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6153 _("caller ignores cookieout or cookieoutlen"));
6154 goto error;
6155 }
6156 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
6157 *cookieoutlen = ret.cookie_out.cookie_out_len;
6158 }
6159
6160 rv = 0;
6161
6162 done:
6163 remoteDriverUnlock(priv);
6164 return rv;
6165
6166 error:
6167 VIR_FREE(ret.cookie_out.cookie_out_val);
6168 goto done;
6169 }
6170
6171
6172 static virDomainPtr
remoteDomainMigrateFinish3(virConnectPtr dconn,const char * dname,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,const char * dconnuri,const char * uri,unsigned long flags,int cancelled)6173 remoteDomainMigrateFinish3(virConnectPtr dconn,
6174 const char *dname,
6175 const char *cookiein,
6176 int cookieinlen,
6177 char **cookieout,
6178 int *cookieoutlen,
6179 const char *dconnuri,
6180 const char *uri,
6181 unsigned long flags,
6182 int cancelled)
6183 {
6184 remote_domain_migrate_finish3_args args;
6185 remote_domain_migrate_finish3_ret ret;
6186 struct private_data *priv = dconn->privateData;
6187 virDomainPtr rv = NULL;
6188
6189 remoteDriverLock(priv);
6190
6191 memset(&args, 0, sizeof(args));
6192 memset(&ret, 0, sizeof(ret));
6193
6194 args.cookie_in.cookie_in_val = (char *)cookiein;
6195 args.cookie_in.cookie_in_len = cookieinlen;
6196 args.dname = (char *) dname;
6197 args.uri = uri == NULL ? NULL : (char **) &uri;
6198 args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
6199 args.flags = flags;
6200 args.cancelled = cancelled;
6201
6202 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH3,
6203 (xdrproc_t) xdr_remote_domain_migrate_finish3_args, (char *) &args,
6204 (xdrproc_t) xdr_remote_domain_migrate_finish3_ret, (char *) &ret) == -1)
6205 goto done;
6206
6207 rv = get_nonnull_domain(dconn, ret.dom);
6208
6209 if (ret.cookie_out.cookie_out_len > 0) {
6210 if (!cookieout || !cookieoutlen) {
6211 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6212 _("caller ignores cookieout or cookieoutlen"));
6213 goto error;
6214 }
6215 *cookieout = g_steal_pointer(&ret.cookie_out.cookie_out_val); /* Caller frees. */
6216 *cookieoutlen = ret.cookie_out.cookie_out_len;
6217 ret.cookie_out.cookie_out_len = 0;
6218 }
6219
6220 xdr_free((xdrproc_t) &xdr_remote_domain_migrate_finish3_ret, (char *) &ret);
6221
6222 done:
6223 remoteDriverUnlock(priv);
6224 return rv;
6225
6226 error:
6227 VIR_FREE(ret.cookie_out.cookie_out_val);
6228 goto done;
6229 }
6230
6231
6232 static int
remoteDomainMigrateConfirm3(virDomainPtr domain,const char * cookiein,int cookieinlen,unsigned long flags,int cancelled)6233 remoteDomainMigrateConfirm3(virDomainPtr domain,
6234 const char *cookiein,
6235 int cookieinlen,
6236 unsigned long flags,
6237 int cancelled)
6238 {
6239 int rv = -1;
6240 remote_domain_migrate_confirm3_args args;
6241 struct private_data *priv = domain->conn->privateData;
6242
6243 remoteDriverLock(priv);
6244
6245 memset(&args, 0, sizeof(args));
6246
6247 make_nonnull_domain(&args.dom, domain);
6248 args.cookie_in.cookie_in_len = cookieinlen;
6249 args.cookie_in.cookie_in_val = (char *) cookiein;
6250 args.flags = flags;
6251 args.cancelled = cancelled;
6252
6253 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3,
6254 (xdrproc_t) xdr_remote_domain_migrate_confirm3_args, (char *) &args,
6255 (xdrproc_t) xdr_void, (char *) NULL) == -1)
6256 goto done;
6257
6258 rv = 0;
6259
6260 done:
6261 remoteDriverUnlock(priv);
6262 return rv;
6263 }
6264
6265
6266 static int
remoteConnectGetCPUModelNames(virConnectPtr conn,const char * arch,char *** models,unsigned int flags)6267 remoteConnectGetCPUModelNames(virConnectPtr conn,
6268 const char *arch,
6269 char ***models,
6270 unsigned int flags)
6271 {
6272 int rv = -1;
6273 size_t i;
6274 g_auto(GStrv) retmodels = NULL;
6275 remote_connect_get_cpu_model_names_args args;
6276 remote_connect_get_cpu_model_names_ret ret;
6277
6278 struct private_data *priv = conn->privateData;
6279
6280 remoteDriverLock(priv);
6281
6282 args.arch = (char *) arch;
6283 args.need_results = !!models;
6284 args.flags = flags;
6285
6286 memset(&ret, 0, sizeof(ret));
6287 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_CPU_MODEL_NAMES,
6288 (xdrproc_t) xdr_remote_connect_get_cpu_model_names_args,
6289 (char *) &args,
6290 (xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret,
6291 (char *) &ret) < 0)
6292 goto done;
6293
6294 /* Check the length of the returned list carefully. */
6295 if (ret.models.models_len > REMOTE_CONNECT_CPU_MODELS_MAX) {
6296 virReportError(VIR_ERR_RPC,
6297 _("Too many model names '%d' for limit '%d'"),
6298 ret.models.models_len,
6299 REMOTE_CONNECT_CPU_MODELS_MAX);
6300 goto cleanup;
6301 }
6302
6303 if (models) {
6304 retmodels = g_new0(char *, ret.models.models_len + 1);
6305
6306 for (i = 0; i < ret.models.models_len; i++) {
6307 retmodels[i] = g_steal_pointer(&ret.models.models_val[i]);
6308 }
6309 *models = g_steal_pointer(&retmodels);
6310 }
6311
6312 rv = ret.ret;
6313
6314 cleanup:
6315 xdr_free((xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret, (char *) &ret);
6316
6317 done:
6318 remoteDriverUnlock(priv);
6319 return rv;
6320 }
6321
6322
6323 static int
remoteDomainOpenGraphics(virDomainPtr dom,unsigned int idx,int fd,unsigned int flags)6324 remoteDomainOpenGraphics(virDomainPtr dom,
6325 unsigned int idx,
6326 int fd,
6327 unsigned int flags)
6328 {
6329 int rv = -1;
6330 remote_domain_open_graphics_args args;
6331 struct private_data *priv = dom->conn->privateData;
6332 int fdin[] = { fd };
6333 size_t fdinlen = G_N_ELEMENTS(fdin);
6334
6335 remoteDriverLock(priv);
6336
6337 make_nonnull_domain(&args.dom, dom);
6338 args.idx = idx;
6339 args.flags = flags;
6340
6341 if (callFull(dom->conn, priv, 0,
6342 fdin, fdinlen,
6343 NULL, NULL,
6344 REMOTE_PROC_DOMAIN_OPEN_GRAPHICS,
6345 (xdrproc_t) xdr_remote_domain_open_graphics_args, (char *) &args,
6346 (xdrproc_t) xdr_void, NULL) == -1)
6347 goto done;
6348
6349 rv = 0;
6350
6351 done:
6352 remoteDriverUnlock(priv);
6353
6354 return rv;
6355 }
6356
6357
6358 static int
remoteDomainOpenGraphicsFD(virDomainPtr dom,unsigned int idx,unsigned int flags)6359 remoteDomainOpenGraphicsFD(virDomainPtr dom,
6360 unsigned int idx,
6361 unsigned int flags)
6362 {
6363 int rv = -1;
6364 remote_domain_open_graphics_fd_args args;
6365 struct private_data *priv = dom->conn->privateData;
6366 int *fdout = NULL;
6367 size_t fdoutlen = 0;
6368
6369 remoteDriverLock(priv);
6370
6371 make_nonnull_domain(&args.dom, dom);
6372 args.idx = idx;
6373 args.flags = flags;
6374
6375 if (callFull(dom->conn, priv, 0,
6376 NULL, 0,
6377 &fdout, &fdoutlen,
6378 REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD,
6379 (xdrproc_t) xdr_remote_domain_open_graphics_fd_args, (char *) &args,
6380 (xdrproc_t) xdr_void, NULL) == -1)
6381 goto done;
6382
6383 if (fdoutlen != 1) {
6384 if (fdoutlen) {
6385 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6386 _("too many file descriptors received"));
6387 while (fdoutlen)
6388 VIR_FORCE_CLOSE(fdout[--fdoutlen]);
6389 } else {
6390 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6391 _("no file descriptor received"));
6392 }
6393 goto done;
6394 }
6395 rv = fdout[0];
6396
6397 done:
6398 VIR_FREE(fdout);
6399 remoteDriverUnlock(priv);
6400
6401 return rv;
6402 }
6403
6404
6405 static int
remoteConnectSetKeepAlive(virConnectPtr conn,int interval,unsigned int count)6406 remoteConnectSetKeepAlive(virConnectPtr conn, int interval, unsigned int count)
6407 {
6408 struct private_data *priv = conn->privateData;
6409 int ret = -1;
6410
6411 remoteDriverLock(priv);
6412 if (!virNetClientKeepAliveIsSupported(priv->client)) {
6413 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6414 _("the caller doesn't support keepalive protocol;"
6415 " perhaps it's missing event loop implementation"));
6416 goto cleanup;
6417 }
6418
6419 if (!priv->serverKeepAlive) {
6420 ret = 1;
6421 goto cleanup;
6422 }
6423
6424 if (interval > 0) {
6425 ret = virNetClientKeepAliveStart(priv->client, interval, count);
6426 } else {
6427 virNetClientKeepAliveStop(priv->client);
6428 ret = 0;
6429 }
6430
6431 cleanup:
6432 remoteDriverUnlock(priv);
6433 return ret;
6434 }
6435
6436
6437 static int
remoteConnectIsAlive(virConnectPtr conn)6438 remoteConnectIsAlive(virConnectPtr conn)
6439 {
6440 struct private_data *priv = conn->privateData;
6441 bool ret;
6442
6443 remoteDriverLock(priv);
6444 ret = virNetClientIsOpen(priv->client);
6445 remoteDriverUnlock(priv);
6446
6447 if (ret)
6448 return 1;
6449 else
6450 return 0;
6451 }
6452
6453
6454 static int
remoteDomainGetDiskErrors(virDomainPtr dom,virDomainDiskErrorPtr errors,unsigned int maxerrors,unsigned int flags)6455 remoteDomainGetDiskErrors(virDomainPtr dom,
6456 virDomainDiskErrorPtr errors,
6457 unsigned int maxerrors,
6458 unsigned int flags)
6459 {
6460 int rv = -1;
6461 struct private_data *priv = dom->conn->privateData;
6462 remote_domain_get_disk_errors_args args;
6463 remote_domain_get_disk_errors_ret ret;
6464
6465 remoteDriverLock(priv);
6466
6467 make_nonnull_domain(&args.dom, dom);
6468 args.maxerrors = maxerrors;
6469 args.flags = flags;
6470
6471 memset(&ret, 0, sizeof(ret));
6472
6473 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_DISK_ERRORS,
6474 (xdrproc_t) xdr_remote_domain_get_disk_errors_args,
6475 (char *) &args,
6476 (xdrproc_t) xdr_remote_domain_get_disk_errors_ret,
6477 (char *) &ret) == -1)
6478 goto done;
6479
6480 if (remoteDeserializeDomainDiskErrors(ret.errors.errors_val,
6481 ret.errors.errors_len,
6482 REMOTE_DOMAIN_DISK_ERRORS_MAX,
6483 errors,
6484 maxerrors) < 0)
6485 goto cleanup;
6486
6487 rv = ret.nerrors;
6488
6489 cleanup:
6490 xdr_free((xdrproc_t) xdr_remote_domain_get_disk_errors_ret, (char *) &ret);
6491
6492 done:
6493 remoteDriverUnlock(priv);
6494 return rv;
6495 }
6496
6497 #include "remote_client_bodies.h"
6498 #include "lxc_client_bodies.h"
6499 #include "qemu_client_bodies.h"
6500
6501 /*
6502 * Serial a set of arguments into a method call message,
6503 * send that to the server and wait for reply
6504 */
6505 static int
callFull(virConnectPtr conn G_GNUC_UNUSED,struct private_data * priv,unsigned int flags,int * fdin,size_t fdinlen,int ** fdout,size_t * fdoutlen,int proc_nr,xdrproc_t args_filter,char * args,xdrproc_t ret_filter,char * ret)6506 callFull(virConnectPtr conn G_GNUC_UNUSED,
6507 struct private_data *priv,
6508 unsigned int flags,
6509 int *fdin,
6510 size_t fdinlen,
6511 int **fdout,
6512 size_t *fdoutlen,
6513 int proc_nr,
6514 xdrproc_t args_filter, char *args,
6515 xdrproc_t ret_filter, char *ret)
6516 {
6517 int rv;
6518 virNetClientProgram *prog;
6519 int counter = priv->counter++;
6520 virNetClient *client = priv->client;
6521 priv->localUses++;
6522
6523 if (flags & REMOTE_CALL_QEMU)
6524 prog = priv->qemuProgram;
6525 else if (flags & REMOTE_CALL_LXC)
6526 prog = priv->lxcProgram;
6527 else
6528 prog = priv->remoteProgram;
6529
6530 /* Unlock, so that if we get any async events/stream data
6531 * while processing the RPC, we don't deadlock when our
6532 * callbacks for those are invoked
6533 */
6534 remoteDriverUnlock(priv);
6535 rv = virNetClientProgramCall(prog,
6536 client,
6537 counter,
6538 proc_nr,
6539 fdinlen, fdin,
6540 fdoutlen, fdout,
6541 args_filter, args,
6542 ret_filter, ret);
6543 remoteDriverLock(priv);
6544 priv->localUses--;
6545
6546 return rv;
6547 }
6548
6549 static int
call(virConnectPtr conn,struct private_data * priv,unsigned int flags,int proc_nr,xdrproc_t args_filter,char * args,xdrproc_t ret_filter,char * ret)6550 call(virConnectPtr conn,
6551 struct private_data *priv,
6552 unsigned int flags,
6553 int proc_nr,
6554 xdrproc_t args_filter, char *args,
6555 xdrproc_t ret_filter, char *ret)
6556 {
6557 return callFull(conn, priv, flags,
6558 NULL, 0,
6559 NULL, NULL,
6560 proc_nr,
6561 args_filter, args,
6562 ret_filter, ret);
6563 }
6564
6565
6566 static int
remoteDomainGetInterfaceParameters(virDomainPtr domain,const char * device,virTypedParameterPtr params,int * nparams,unsigned int flags)6567 remoteDomainGetInterfaceParameters(virDomainPtr domain,
6568 const char *device,
6569 virTypedParameterPtr params, int *nparams,
6570 unsigned int flags)
6571 {
6572 int rv = -1;
6573 remote_domain_get_interface_parameters_args args;
6574 remote_domain_get_interface_parameters_ret ret;
6575 struct private_data *priv = domain->conn->privateData;
6576
6577 remoteDriverLock(priv);
6578
6579 make_nonnull_domain(&args.dom, domain);
6580 args.device = (char *)device;
6581 args.nparams = *nparams;
6582 args.flags = flags;
6583
6584 memset(&ret, 0, sizeof(ret));
6585 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS,
6586 (xdrproc_t) xdr_remote_domain_get_interface_parameters_args, (char *) &args,
6587 (xdrproc_t) xdr_remote_domain_get_interface_parameters_ret, (char *) &ret) == -1)
6588 goto done;
6589
6590 /* Handle the case when the caller does not know the number of parameters
6591 * and is asking for the number of parameters supported
6592 */
6593 if (*nparams == 0) {
6594 *nparams = ret.nparams;
6595 rv = 0;
6596 goto cleanup;
6597 }
6598
6599 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
6600 ret.params.params_len,
6601 REMOTE_DOMAIN_INTERFACE_PARAMETERS_MAX,
6602 ¶ms,
6603 nparams) < 0)
6604 goto cleanup;
6605
6606 rv = 0;
6607
6608 cleanup:
6609 xdr_free((xdrproc_t) xdr_remote_domain_get_interface_parameters_ret,
6610 (char *) &ret);
6611 done:
6612 remoteDriverUnlock(priv);
6613 return rv;
6614 }
6615
6616
6617 static int
remoteNodeGetMemoryParameters(virConnectPtr conn,virTypedParameterPtr params,int * nparams,unsigned int flags)6618 remoteNodeGetMemoryParameters(virConnectPtr conn,
6619 virTypedParameterPtr params,
6620 int *nparams,
6621 unsigned int flags)
6622 {
6623 int rv = -1;
6624 remote_node_get_memory_parameters_args args;
6625 remote_node_get_memory_parameters_ret ret;
6626 struct private_data *priv = conn->privateData;
6627
6628 remoteDriverLock(priv);
6629
6630 args.nparams = *nparams;
6631 args.flags = flags;
6632
6633 memset(&ret, 0, sizeof(ret));
6634 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_MEMORY_PARAMETERS,
6635 (xdrproc_t) xdr_remote_node_get_memory_parameters_args, (char *) &args,
6636 (xdrproc_t) xdr_remote_node_get_memory_parameters_ret, (char *) &ret) == -1)
6637 goto done;
6638
6639 /* Handle the case when the caller does not know the number of parameters
6640 * and is asking for the number of parameters supported
6641 */
6642 if (*nparams == 0) {
6643 *nparams = ret.nparams;
6644 rv = 0;
6645 goto cleanup;
6646 }
6647
6648 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
6649 ret.params.params_len,
6650 REMOTE_NODE_MEMORY_PARAMETERS_MAX,
6651 ¶ms,
6652 nparams) < 0)
6653 goto cleanup;
6654
6655 rv = 0;
6656
6657 cleanup:
6658 xdr_free((xdrproc_t) xdr_remote_node_get_memory_parameters_ret,
6659 (char *) &ret);
6660 done:
6661 remoteDriverUnlock(priv);
6662 return rv;
6663 }
6664
6665
6666 static int
remoteNodeGetSEVInfo(virConnectPtr conn,virTypedParameterPtr * params,int * nparams,unsigned int flags)6667 remoteNodeGetSEVInfo(virConnectPtr conn,
6668 virTypedParameterPtr *params,
6669 int *nparams,
6670 unsigned int flags)
6671 {
6672 int rv = -1;
6673 remote_node_get_sev_info_args args;
6674 remote_node_get_sev_info_ret ret;
6675 struct private_data *priv = conn->privateData;
6676
6677 remoteDriverLock(priv);
6678
6679 args.flags = flags;
6680
6681 memset(&ret, 0, sizeof(ret));
6682 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_SEV_INFO,
6683 (xdrproc_t) xdr_remote_node_get_sev_info_args, (char *) &args,
6684 (xdrproc_t) xdr_remote_node_get_sev_info_ret, (char *) &ret) == -1)
6685 goto done;
6686
6687 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
6688 ret.params.params_len,
6689 REMOTE_NODE_SEV_INFO_MAX,
6690 params,
6691 nparams) < 0)
6692 goto cleanup;
6693
6694 rv = 0;
6695
6696 cleanup:
6697 xdr_free((xdrproc_t) xdr_remote_node_get_sev_info_ret, (char *) &ret);
6698 done:
6699 remoteDriverUnlock(priv);
6700 return rv;
6701 }
6702
6703
6704 static int
remoteNodeGetCPUMap(virConnectPtr conn,unsigned char ** cpumap,unsigned int * online,unsigned int flags)6705 remoteNodeGetCPUMap(virConnectPtr conn,
6706 unsigned char **cpumap,
6707 unsigned int *online,
6708 unsigned int flags)
6709 {
6710 int rv = -1;
6711 remote_node_get_cpu_map_args args;
6712 remote_node_get_cpu_map_ret ret;
6713 struct private_data *priv = conn->privateData;
6714
6715 remoteDriverLock(priv);
6716
6717 args.need_map = !!cpumap;
6718 args.need_online = !!online;
6719 args.flags = flags;
6720
6721 memset(&ret, 0, sizeof(ret));
6722 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_CPU_MAP,
6723 (xdrproc_t) xdr_remote_node_get_cpu_map_args,
6724 (char *) &args,
6725 (xdrproc_t) xdr_remote_node_get_cpu_map_ret,
6726 (char *) &ret) == -1)
6727 goto done;
6728
6729 if (ret.ret < 0)
6730 goto cleanup;
6731
6732 if (cpumap) {
6733 *cpumap = g_new0(unsigned char, ret.cpumap.cpumap_len);
6734 memcpy(*cpumap, ret.cpumap.cpumap_val, ret.cpumap.cpumap_len);
6735 }
6736
6737 if (online)
6738 *online = ret.online;
6739
6740 rv = ret.ret;
6741
6742 cleanup:
6743 xdr_free((xdrproc_t) xdr_remote_node_get_cpu_map_ret, (char *) &ret);
6744 done:
6745 remoteDriverUnlock(priv);
6746 return rv;
6747 }
6748
6749
6750 static int
remoteDomainLxcOpenNamespace(virDomainPtr domain,int ** fdlist,unsigned int flags)6751 remoteDomainLxcOpenNamespace(virDomainPtr domain,
6752 int **fdlist,
6753 unsigned int flags)
6754 {
6755 int rv = -1;
6756 lxc_domain_open_namespace_args args;
6757 struct private_data *priv = domain->conn->privateData;
6758 size_t nfds = 0;
6759
6760 remoteDriverLock(priv);
6761
6762 make_nonnull_domain(&args.dom, domain);
6763 args.flags = flags;
6764
6765 *fdlist = NULL;
6766
6767 if (callFull(domain->conn, priv, REMOTE_CALL_LXC,
6768 NULL, 0,
6769 fdlist, &nfds,
6770 LXC_PROC_DOMAIN_OPEN_NAMESPACE,
6771 (xdrproc_t) xdr_lxc_domain_open_namespace_args, (char *) &args,
6772 (xdrproc_t) xdr_void, NULL) == -1)
6773 goto done;
6774
6775 rv = nfds;
6776
6777 done:
6778 remoteDriverUnlock(priv);
6779 return rv;
6780 }
6781
6782 static int
remoteDomainGetJobStats(virDomainPtr domain,int * type,virTypedParameterPtr * params,int * nparams,unsigned int flags)6783 remoteDomainGetJobStats(virDomainPtr domain,
6784 int *type,
6785 virTypedParameterPtr *params,
6786 int *nparams,
6787 unsigned int flags)
6788 {
6789 int rv = -1;
6790 remote_domain_get_job_stats_args args;
6791 remote_domain_get_job_stats_ret ret;
6792 struct private_data *priv = domain->conn->privateData;
6793
6794 remoteDriverLock(priv);
6795
6796 make_nonnull_domain(&args.dom, domain);
6797 args.flags = flags;
6798
6799 memset(&ret, 0, sizeof(ret));
6800 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_JOB_STATS,
6801 (xdrproc_t) xdr_remote_domain_get_job_stats_args, (char *) &args,
6802 (xdrproc_t) xdr_remote_domain_get_job_stats_ret, (char *) &ret) == -1)
6803 goto done;
6804
6805 *type = ret.type;
6806
6807 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
6808 ret.params.params_len,
6809 REMOTE_DOMAIN_JOB_STATS_MAX,
6810 params, nparams) < 0)
6811 goto cleanup;
6812
6813 rv = 0;
6814
6815 cleanup:
6816 xdr_free((xdrproc_t) xdr_remote_domain_get_job_stats_ret,
6817 (char *) &ret);
6818 done:
6819 remoteDriverUnlock(priv);
6820 return rv;
6821 }
6822
6823
6824 static char *
remoteDomainMigrateBegin3Params(virDomainPtr domain,virTypedParameterPtr params,int nparams,char ** cookieout,int * cookieoutlen,unsigned int flags)6825 remoteDomainMigrateBegin3Params(virDomainPtr domain,
6826 virTypedParameterPtr params,
6827 int nparams,
6828 char **cookieout,
6829 int *cookieoutlen,
6830 unsigned int flags)
6831 {
6832 char *rv = NULL;
6833 remote_domain_migrate_begin3_params_args args;
6834 remote_domain_migrate_begin3_params_ret ret;
6835 struct private_data *priv = domain->conn->privateData;
6836
6837 remoteDriverLock(priv);
6838
6839 memset(&args, 0, sizeof(args));
6840 memset(&ret, 0, sizeof(ret));
6841
6842 make_nonnull_domain(&args.dom, domain);
6843 args.flags = flags;
6844
6845 if (virTypedParamsSerialize(params, nparams,
6846 REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX,
6847 (struct _virTypedParameterRemote **) &args.params.params_val,
6848 &args.params.params_len,
6849 VIR_TYPED_PARAM_STRING_OKAY) < 0) {
6850 xdr_free((xdrproc_t) xdr_remote_domain_migrate_begin3_params_args,
6851 (char *) &args);
6852 goto cleanup;
6853 }
6854
6855 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3_PARAMS,
6856 (xdrproc_t) xdr_remote_domain_migrate_begin3_params_args,
6857 (char *) &args,
6858 (xdrproc_t) xdr_remote_domain_migrate_begin3_params_ret,
6859 (char *) &ret) == -1)
6860 goto cleanup;
6861
6862 if (ret.cookie_out.cookie_out_len > 0) {
6863 if (!cookieout || !cookieoutlen) {
6864 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6865 _("caller ignores cookieout or cookieoutlen"));
6866 goto error;
6867 }
6868 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
6869 *cookieoutlen = ret.cookie_out.cookie_out_len;
6870 }
6871
6872 rv = ret.xml; /* caller frees */
6873
6874 cleanup:
6875 virTypedParamsRemoteFree((struct _virTypedParameterRemote *) args.params.params_val,
6876 args.params.params_len);
6877 remoteDriverUnlock(priv);
6878 return rv;
6879
6880 error:
6881 VIR_FREE(ret.cookie_out.cookie_out_val);
6882 goto cleanup;
6883 }
6884
6885
6886 static int
remoteDomainMigratePrepare3Params(virConnectPtr dconn,virTypedParameterPtr params,int nparams,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,char ** uri_out,unsigned int flags)6887 remoteDomainMigratePrepare3Params(virConnectPtr dconn,
6888 virTypedParameterPtr params,
6889 int nparams,
6890 const char *cookiein,
6891 int cookieinlen,
6892 char **cookieout,
6893 int *cookieoutlen,
6894 char **uri_out,
6895 unsigned int flags)
6896 {
6897 int rv = -1;
6898 remote_domain_migrate_prepare3_params_args args;
6899 remote_domain_migrate_prepare3_params_ret ret;
6900 struct private_data *priv = dconn->privateData;
6901
6902 remoteDriverLock(priv);
6903
6904 memset(&args, 0, sizeof(args));
6905 memset(&ret, 0, sizeof(ret));
6906
6907 if (virTypedParamsSerialize(params, nparams,
6908 REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX,
6909 (struct _virTypedParameterRemote **) &args.params.params_val,
6910 &args.params.params_len,
6911 VIR_TYPED_PARAM_STRING_OKAY) < 0) {
6912 xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare3_params_args,
6913 (char *) &args);
6914 goto cleanup;
6915 }
6916
6917 args.cookie_in.cookie_in_val = (char *)cookiein;
6918 args.cookie_in.cookie_in_len = cookieinlen;
6919 args.flags = flags;
6920
6921 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3_PARAMS,
6922 (xdrproc_t) xdr_remote_domain_migrate_prepare3_params_args,
6923 (char *) &args,
6924 (xdrproc_t) xdr_remote_domain_migrate_prepare3_params_ret,
6925 (char *) &ret) == -1)
6926 goto cleanup;
6927
6928 if (ret.cookie_out.cookie_out_len > 0) {
6929 if (!cookieout || !cookieoutlen) {
6930 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6931 _("caller ignores cookieout or cookieoutlen"));
6932 goto error;
6933 }
6934 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
6935 *cookieoutlen = ret.cookie_out.cookie_out_len;
6936 }
6937 if (ret.uri_out) {
6938 if (!uri_out) {
6939 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6940 _("caller ignores uri_out"));
6941 goto error;
6942 }
6943 *uri_out = *ret.uri_out; /* Caller frees. */
6944 }
6945
6946 rv = 0;
6947
6948 cleanup:
6949 virTypedParamsRemoteFree((struct _virTypedParameterRemote *) args.params.params_val,
6950 args.params.params_len);
6951 VIR_FREE(ret.uri_out);
6952 remoteDriverUnlock(priv);
6953 return rv;
6954
6955 error:
6956 VIR_FREE(ret.cookie_out.cookie_out_val);
6957 if (ret.uri_out)
6958 VIR_FREE(*ret.uri_out);
6959 goto cleanup;
6960 }
6961
6962
6963 static int
remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,virStreamPtr st,virTypedParameterPtr params,int nparams,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,unsigned int flags)6964 remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
6965 virStreamPtr st,
6966 virTypedParameterPtr params,
6967 int nparams,
6968 const char *cookiein,
6969 int cookieinlen,
6970 char **cookieout,
6971 int *cookieoutlen,
6972 unsigned int flags)
6973 {
6974 struct private_data *priv = dconn->privateData;
6975 int rv = -1;
6976 remote_domain_migrate_prepare_tunnel3_params_args args;
6977 remote_domain_migrate_prepare_tunnel3_params_ret ret;
6978 virNetClientStream *netst;
6979
6980 remoteDriverLock(priv);
6981
6982 memset(&args, 0, sizeof(args));
6983 memset(&ret, 0, sizeof(ret));
6984
6985 args.cookie_in.cookie_in_val = (char *)cookiein;
6986 args.cookie_in.cookie_in_len = cookieinlen;
6987 args.flags = flags;
6988
6989 if (virTypedParamsSerialize(params, nparams,
6990 REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX,
6991 (struct _virTypedParameterRemote **) &args.params.params_val,
6992 &args.params.params_len,
6993 VIR_TYPED_PARAM_STRING_OKAY) < 0) {
6994 xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_args,
6995 (char *) &args);
6996 goto cleanup;
6997 }
6998
6999 if (!(netst = virNetClientStreamNew(priv->remoteProgram,
7000 REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3_PARAMS,
7001 priv->counter,
7002 false)))
7003 goto cleanup;
7004
7005 if (virNetClientAddStream(priv->client, netst) < 0) {
7006 virObjectUnref(netst);
7007 goto cleanup;
7008 }
7009
7010 st->driver = &remoteStreamDrv;
7011 st->privateData = netst;
7012 st->ff = virObjectFreeCallback;
7013
7014 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3_PARAMS,
7015 (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_args,
7016 (char *) &args,
7017 (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_ret,
7018 (char *) &ret) == -1) {
7019 virNetClientRemoveStream(priv->client, netst);
7020 virObjectUnref(netst);
7021 goto cleanup;
7022 }
7023
7024 if (ret.cookie_out.cookie_out_len > 0) {
7025 if (!cookieout || !cookieoutlen) {
7026 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
7027 _("caller ignores cookieout or cookieoutlen"));
7028 goto error;
7029 }
7030 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
7031 *cookieoutlen = ret.cookie_out.cookie_out_len;
7032 }
7033
7034 rv = 0;
7035
7036 cleanup:
7037 virTypedParamsRemoteFree((struct _virTypedParameterRemote *) args.params.params_val,
7038 args.params.params_len);
7039 remoteDriverUnlock(priv);
7040 return rv;
7041
7042 error:
7043 VIR_FREE(ret.cookie_out.cookie_out_val);
7044 goto cleanup;
7045 }
7046
7047
7048 static int
remoteDomainMigratePerform3Params(virDomainPtr dom,const char * dconnuri,virTypedParameterPtr params,int nparams,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,unsigned int flags)7049 remoteDomainMigratePerform3Params(virDomainPtr dom,
7050 const char *dconnuri,
7051 virTypedParameterPtr params,
7052 int nparams,
7053 const char *cookiein,
7054 int cookieinlen,
7055 char **cookieout,
7056 int *cookieoutlen,
7057 unsigned int flags)
7058 {
7059 int rv = -1;
7060 remote_domain_migrate_perform3_params_args args;
7061 remote_domain_migrate_perform3_params_ret ret;
7062 struct private_data *priv = dom->conn->privateData;
7063
7064 remoteDriverLock(priv);
7065
7066 memset(&args, 0, sizeof(args));
7067 memset(&ret, 0, sizeof(ret));
7068
7069 make_nonnull_domain(&args.dom, dom);
7070 args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
7071 args.cookie_in.cookie_in_val = (char *)cookiein;
7072 args.cookie_in.cookie_in_len = cookieinlen;
7073 args.flags = flags;
7074
7075 if (virTypedParamsSerialize(params, nparams,
7076 REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX,
7077 (struct _virTypedParameterRemote **) &args.params.params_val,
7078 &args.params.params_len,
7079 VIR_TYPED_PARAM_STRING_OKAY) < 0) {
7080 xdr_free((xdrproc_t) xdr_remote_domain_migrate_perform3_params_args,
7081 (char *) &args);
7082 goto cleanup;
7083 }
7084
7085 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3_PARAMS,
7086 (xdrproc_t) xdr_remote_domain_migrate_perform3_params_args,
7087 (char *) &args,
7088 (xdrproc_t) xdr_remote_domain_migrate_perform3_params_ret,
7089 (char *) &ret) == -1)
7090 goto cleanup;
7091
7092 if (ret.cookie_out.cookie_out_len > 0) {
7093 if (!cookieout || !cookieoutlen) {
7094 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
7095 _("caller ignores cookieout or cookieoutlen"));
7096 goto error;
7097 }
7098 *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
7099 *cookieoutlen = ret.cookie_out.cookie_out_len;
7100 }
7101
7102 rv = 0;
7103
7104 cleanup:
7105 virTypedParamsRemoteFree((struct _virTypedParameterRemote *) args.params.params_val,
7106 args.params.params_len);
7107 remoteDriverUnlock(priv);
7108 return rv;
7109
7110 error:
7111 VIR_FREE(ret.cookie_out.cookie_out_val);
7112 goto cleanup;
7113 }
7114
7115
7116 static virDomainPtr
remoteDomainMigrateFinish3Params(virConnectPtr dconn,virTypedParameterPtr params,int nparams,const char * cookiein,int cookieinlen,char ** cookieout,int * cookieoutlen,unsigned int flags,int cancelled)7117 remoteDomainMigrateFinish3Params(virConnectPtr dconn,
7118 virTypedParameterPtr params,
7119 int nparams,
7120 const char *cookiein,
7121 int cookieinlen,
7122 char **cookieout,
7123 int *cookieoutlen,
7124 unsigned int flags,
7125 int cancelled)
7126 {
7127 remote_domain_migrate_finish3_params_args args;
7128 remote_domain_migrate_finish3_params_ret ret;
7129 struct private_data *priv = dconn->privateData;
7130 virDomainPtr rv = NULL;
7131
7132 remoteDriverLock(priv);
7133
7134 memset(&args, 0, sizeof(args));
7135 memset(&ret, 0, sizeof(ret));
7136
7137 args.cookie_in.cookie_in_val = (char *)cookiein;
7138 args.cookie_in.cookie_in_len = cookieinlen;
7139 args.flags = flags;
7140 args.cancelled = cancelled;
7141
7142 if (virTypedParamsSerialize(params, nparams,
7143 REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX,
7144 (struct _virTypedParameterRemote **) &args.params.params_val,
7145 &args.params.params_len,
7146 VIR_TYPED_PARAM_STRING_OKAY) < 0) {
7147 xdr_free((xdrproc_t) xdr_remote_domain_migrate_finish3_params_args,
7148 (char *) &args);
7149 goto cleanup;
7150 }
7151
7152 if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH3_PARAMS,
7153 (xdrproc_t) xdr_remote_domain_migrate_finish3_params_args,
7154 (char *) &args,
7155 (xdrproc_t) xdr_remote_domain_migrate_finish3_params_ret,
7156 (char *) &ret) == -1)
7157 goto cleanup;
7158
7159 rv = get_nonnull_domain(dconn, ret.dom);
7160
7161 if (ret.cookie_out.cookie_out_len > 0) {
7162 if (!cookieout || !cookieoutlen) {
7163 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
7164 _("caller ignores cookieout or cookieoutlen"));
7165 goto error;
7166 }
7167 *cookieout = g_steal_pointer(&ret.cookie_out.cookie_out_val); /* Caller frees. */
7168 *cookieoutlen = ret.cookie_out.cookie_out_len;
7169 ret.cookie_out.cookie_out_len = 0;
7170 }
7171
7172 xdr_free((xdrproc_t) &xdr_remote_domain_migrate_finish3_params_ret,
7173 (char *) &ret);
7174
7175 cleanup:
7176 virTypedParamsRemoteFree((struct _virTypedParameterRemote *) args.params.params_val,
7177 args.params.params_len);
7178 remoteDriverUnlock(priv);
7179 return rv;
7180
7181 error:
7182 VIR_FREE(ret.cookie_out.cookie_out_val);
7183 goto cleanup;
7184 }
7185
7186
7187 static int
remoteDomainMigrateConfirm3Params(virDomainPtr domain,virTypedParameterPtr params,int nparams,const char * cookiein,int cookieinlen,unsigned int flags,int cancelled)7188 remoteDomainMigrateConfirm3Params(virDomainPtr domain,
7189 virTypedParameterPtr params,
7190 int nparams,
7191 const char *cookiein,
7192 int cookieinlen,
7193 unsigned int flags,
7194 int cancelled)
7195 {
7196 int rv = -1;
7197 remote_domain_migrate_confirm3_params_args args;
7198 struct private_data *priv = domain->conn->privateData;
7199
7200 remoteDriverLock(priv);
7201
7202 memset(&args, 0, sizeof(args));
7203
7204 make_nonnull_domain(&args.dom, domain);
7205 args.cookie_in.cookie_in_len = cookieinlen;
7206 args.cookie_in.cookie_in_val = (char *) cookiein;
7207 args.flags = flags;
7208 args.cancelled = cancelled;
7209
7210 if (virTypedParamsSerialize(params, nparams,
7211 REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX,
7212 (struct _virTypedParameterRemote **) &args.params.params_val,
7213 &args.params.params_len,
7214 VIR_TYPED_PARAM_STRING_OKAY) < 0) {
7215 xdr_free((xdrproc_t) xdr_remote_domain_migrate_confirm3_params_args,
7216 (char *) &args);
7217 goto cleanup;
7218 }
7219
7220 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3_PARAMS,
7221 (xdrproc_t) xdr_remote_domain_migrate_confirm3_params_args,
7222 (char *) &args, (xdrproc_t) xdr_void, (char *) NULL) == -1)
7223 goto cleanup;
7224
7225 rv = 0;
7226
7227 cleanup:
7228 virTypedParamsRemoteFree((struct _virTypedParameterRemote *) args.params.params_val,
7229 args.params.params_len);
7230 remoteDriverUnlock(priv);
7231 return rv;
7232 }
7233
7234
7235 static virDomainPtr
remoteDomainCreateXMLWithFiles(virConnectPtr conn,const char * xml_desc,unsigned int nfiles,int * files,unsigned int flags)7236 remoteDomainCreateXMLWithFiles(virConnectPtr conn, const char *xml_desc,
7237 unsigned int nfiles, int *files, unsigned int flags)
7238 {
7239 virDomainPtr rv = NULL;
7240 struct private_data *priv = conn->privateData;
7241 remote_domain_create_xml_with_files_args args;
7242 remote_domain_create_xml_with_files_ret ret;
7243
7244 remoteDriverLock(priv);
7245
7246 args.xml_desc = (char *)xml_desc;
7247 args.flags = flags;
7248
7249 memset(&ret, 0, sizeof(ret));
7250
7251 if (callFull(conn, priv, 0,
7252 files, nfiles,
7253 NULL, NULL,
7254 REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES,
7255 (xdrproc_t)xdr_remote_domain_create_xml_with_files_args, (char *)&args,
7256 (xdrproc_t)xdr_remote_domain_create_xml_with_files_ret, (char *)&ret) == -1) {
7257 goto done;
7258 }
7259
7260 rv = get_nonnull_domain(conn, ret.dom);
7261 xdr_free((xdrproc_t)xdr_remote_domain_create_xml_with_files_ret, (char *)&ret);
7262
7263 done:
7264 remoteDriverUnlock(priv);
7265 return rv;
7266 }
7267
7268
7269 static int
remoteDomainCreateWithFiles(virDomainPtr dom,unsigned int nfiles,int * files,unsigned int flags)7270 remoteDomainCreateWithFiles(virDomainPtr dom,
7271 unsigned int nfiles, int *files,
7272 unsigned int flags)
7273 {
7274 int rv = -1;
7275 struct private_data *priv = dom->conn->privateData;
7276 remote_domain_create_with_files_args args;
7277 remote_domain_create_with_files_ret ret;
7278
7279 remoteDriverLock(priv);
7280
7281 make_nonnull_domain(&args.dom, dom);
7282 args.flags = flags;
7283
7284 memset(&ret, 0, sizeof(ret));
7285
7286 if (callFull(dom->conn, priv, 0,
7287 files, nfiles,
7288 NULL, NULL,
7289 REMOTE_PROC_DOMAIN_CREATE_WITH_FILES,
7290 (xdrproc_t)xdr_remote_domain_create_with_files_args, (char *)&args,
7291 (xdrproc_t)xdr_remote_domain_create_with_files_ret, (char *)&ret) == -1) {
7292 goto done;
7293 }
7294
7295 dom->id = ret.dom.id;
7296 xdr_free((xdrproc_t) &xdr_remote_domain_create_with_files_ret, (char *) &ret);
7297 rv = 0;
7298
7299 done:
7300 remoteDriverUnlock(priv);
7301 return rv;
7302 }
7303
7304 static int
remoteDomainGetTime(virDomainPtr dom,long long * seconds,unsigned int * nseconds,unsigned int flags)7305 remoteDomainGetTime(virDomainPtr dom,
7306 long long *seconds,
7307 unsigned int *nseconds,
7308 unsigned int flags)
7309 {
7310 int rv = -1;
7311 struct private_data *priv = dom->conn->privateData;
7312 remote_domain_get_time_args args;
7313 remote_domain_get_time_ret ret;
7314
7315 remoteDriverLock(priv);
7316
7317 make_nonnull_domain(&args.dom, dom);
7318 args.flags = flags;
7319
7320 *seconds = *nseconds = 0;
7321
7322 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_TIME,
7323 (xdrproc_t) xdr_remote_domain_get_time_args, (char *) &args,
7324 (xdrproc_t) xdr_remote_domain_get_time_ret, (char *) &ret) == -1)
7325 goto cleanup;
7326
7327 *seconds = ret.seconds;
7328 *nseconds = ret.nseconds;
7329 xdr_free((xdrproc_t) &xdr_remote_domain_get_time_ret, (char *) &ret);
7330 rv = 0;
7331
7332 cleanup:
7333 remoteDriverUnlock(priv);
7334 return rv;
7335 }
7336
7337
7338 static int
remoteNodeGetFreePages(virConnectPtr conn,unsigned int npages,unsigned int * pages,int startCell,unsigned int cellCount,unsigned long long * counts,unsigned int flags)7339 remoteNodeGetFreePages(virConnectPtr conn,
7340 unsigned int npages,
7341 unsigned int *pages,
7342 int startCell,
7343 unsigned int cellCount,
7344 unsigned long long *counts,
7345 unsigned int flags)
7346 {
7347 int rv = -1;
7348 remote_node_get_free_pages_args args;
7349 remote_node_get_free_pages_ret ret;
7350 struct private_data *priv = conn->privateData;
7351
7352 remoteDriverLock(priv);
7353
7354 if (npages * cellCount > REMOTE_NODE_MAX_CELLS) {
7355 virReportError(VIR_ERR_RPC,
7356 _("too many NUMA cells: %d > %d"),
7357 npages * cellCount, REMOTE_NODE_MAX_CELLS);
7358 goto done;
7359 }
7360
7361 args.pages.pages_val = (u_int *) pages;
7362 args.pages.pages_len = npages;
7363 args.startCell = startCell;
7364 args.cellCount = cellCount;
7365 args.flags = flags;
7366
7367 memset(&ret, 0, sizeof(ret));
7368 if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_FREE_PAGES,
7369 (xdrproc_t) xdr_remote_node_get_free_pages_args, (char *)&args,
7370 (xdrproc_t) xdr_remote_node_get_free_pages_ret, (char *)&ret) == -1)
7371 goto done;
7372
7373 memcpy(counts, ret.counts.counts_val, ret.counts.counts_len * sizeof(*counts));
7374
7375 xdr_free((xdrproc_t) xdr_remote_node_get_free_pages_ret, (char *) &ret);
7376
7377 rv = ret.counts.counts_len;
7378
7379 done:
7380 remoteDriverUnlock(priv);
7381 return rv;
7382 }
7383
7384
7385 /* Copy contents of remote_network_dhcp_lease to virNetworkDHCPLeasePtr */
7386 static int
remoteSerializeDHCPLease(virNetworkDHCPLeasePtr lease_dst,remote_network_dhcp_lease * lease_src)7387 remoteSerializeDHCPLease(virNetworkDHCPLeasePtr lease_dst, remote_network_dhcp_lease *lease_src)
7388 {
7389 lease_dst->expirytime = lease_src->expirytime;
7390 lease_dst->type = lease_src->type;
7391 lease_dst->prefix = lease_src->prefix;
7392
7393 lease_dst->iface = g_strdup(lease_src->iface);
7394
7395 lease_dst->ipaddr = g_strdup(lease_src->ipaddr);
7396
7397 if (lease_src->mac) {
7398 lease_dst->mac = g_strdup(*lease_src->mac);
7399 } else {
7400 lease_src->mac = NULL;
7401 }
7402
7403 if (lease_src->iaid) {
7404 lease_dst->iaid = g_strdup(*lease_src->iaid);
7405 } else {
7406 lease_src->iaid = NULL;
7407 }
7408
7409 if (lease_src->hostname) {
7410 lease_dst->hostname = g_strdup(*lease_src->hostname);
7411 } else {
7412 lease_src->hostname = NULL;
7413 }
7414
7415 if (lease_src->clientid) {
7416 lease_dst->clientid = g_strdup(*lease_src->clientid);
7417 } else {
7418 lease_src->clientid = NULL;
7419 }
7420
7421 return 0;
7422 }
7423
7424
7425 static int
remoteNetworkGetDHCPLeases(virNetworkPtr net,const char * mac,virNetworkDHCPLeasePtr ** leases,unsigned int flags)7426 remoteNetworkGetDHCPLeases(virNetworkPtr net,
7427 const char *mac,
7428 virNetworkDHCPLeasePtr **leases,
7429 unsigned int flags)
7430 {
7431 int rv = -1;
7432 size_t i;
7433 struct private_data *priv = net->conn->privateData;
7434 remote_network_get_dhcp_leases_args args;
7435 remote_network_get_dhcp_leases_ret ret;
7436
7437 virNetworkDHCPLeasePtr *leases_ret = NULL;
7438 remoteDriverLock(priv);
7439
7440 make_nonnull_network(&args.net, net);
7441 args.mac = mac ? (char **) &mac : NULL;
7442 args.flags = flags;
7443 args.need_results = !!leases;
7444
7445 memset(&ret, 0, sizeof(ret));
7446
7447 if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_DHCP_LEASES,
7448 (xdrproc_t)xdr_remote_network_get_dhcp_leases_args, (char *)&args,
7449 (xdrproc_t)xdr_remote_network_get_dhcp_leases_ret, (char *)&ret) == -1)
7450 goto done;
7451
7452 if (ret.leases.leases_len > REMOTE_NETWORK_DHCP_LEASES_MAX) {
7453 virReportError(VIR_ERR_INTERNAL_ERROR,
7454 _("Number of leases is %d, which exceeds max limit: %d"),
7455 ret.leases.leases_len, REMOTE_NETWORK_DHCP_LEASES_MAX);
7456 goto cleanup;
7457 }
7458
7459 if (leases) {
7460 if (ret.leases.leases_len)
7461 leases_ret = g_new0(virNetworkDHCPLeasePtr, ret.leases.leases_len + 1);
7462
7463 for (i = 0; i < ret.leases.leases_len; i++) {
7464 leases_ret[i] = g_new0(virNetworkDHCPLease, 1);
7465
7466 if (remoteSerializeDHCPLease(leases_ret[i], &ret.leases.leases_val[i]) < 0)
7467 goto cleanup;
7468 }
7469
7470 *leases = g_steal_pointer(&leases_ret);
7471 }
7472
7473 rv = ret.ret;
7474
7475 cleanup:
7476 if (leases_ret) {
7477 for (i = 0; i < ret.leases.leases_len; i++)
7478 virNetworkDHCPLeaseFree(leases_ret[i]);
7479 VIR_FREE(leases_ret);
7480 }
7481 xdr_free((xdrproc_t)xdr_remote_network_get_dhcp_leases_ret,
7482 (char *) &ret);
7483
7484 done:
7485 remoteDriverUnlock(priv);
7486 return rv;
7487 }
7488
7489
7490 static int
remoteConnectGetAllDomainStats(virConnectPtr conn,virDomainPtr * doms,unsigned int ndoms,unsigned int stats,virDomainStatsRecordPtr ** retStats,unsigned int flags)7491 remoteConnectGetAllDomainStats(virConnectPtr conn,
7492 virDomainPtr *doms,
7493 unsigned int ndoms,
7494 unsigned int stats,
7495 virDomainStatsRecordPtr **retStats,
7496 unsigned int flags)
7497 {
7498 struct private_data *priv = conn->privateData;
7499 int rv = -1;
7500 size_t i;
7501 remote_connect_get_all_domain_stats_args args;
7502 remote_connect_get_all_domain_stats_ret ret;
7503 virDomainStatsRecordPtr elem = NULL;
7504 virDomainStatsRecordPtr *tmpret = NULL;
7505
7506 memset(&args, 0, sizeof(args));
7507
7508 if (ndoms) {
7509 args.doms.doms_val = g_new0(remote_nonnull_domain, ndoms);
7510
7511 for (i = 0; i < ndoms; i++)
7512 make_nonnull_domain(args.doms.doms_val + i, doms[i]);
7513 }
7514 args.doms.doms_len = ndoms;
7515
7516 args.stats = stats;
7517 args.flags = flags;
7518
7519 memset(&ret, 0, sizeof(ret));
7520
7521 remoteDriverLock(priv);
7522 if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS,
7523 (xdrproc_t)xdr_remote_connect_get_all_domain_stats_args, (char *)&args,
7524 (xdrproc_t)xdr_remote_connect_get_all_domain_stats_ret, (char *)&ret) == -1) {
7525 remoteDriverUnlock(priv);
7526 goto cleanup;
7527 }
7528 remoteDriverUnlock(priv);
7529
7530 if (ret.retStats.retStats_len > REMOTE_DOMAIN_LIST_MAX) {
7531 virReportError(VIR_ERR_INTERNAL_ERROR,
7532 _("Number of stats entries is %d, which exceeds max limit: %d"),
7533 ret.retStats.retStats_len, REMOTE_DOMAIN_LIST_MAX);
7534 goto cleanup;
7535 }
7536
7537 *retStats = NULL;
7538
7539 tmpret = g_new0(virDomainStatsRecordPtr, ret.retStats.retStats_len + 1);
7540
7541 for (i = 0; i < ret.retStats.retStats_len; i++) {
7542 remote_domain_stats_record *rec = ret.retStats.retStats_val + i;
7543
7544 elem = g_new0(virDomainStatsRecord, 1);
7545
7546 if (!(elem->dom = get_nonnull_domain(conn, rec->dom)))
7547 goto cleanup;
7548
7549 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) rec->params.params_val,
7550 rec->params.params_len,
7551 REMOTE_CONNECT_GET_ALL_DOMAIN_STATS_MAX,
7552 &elem->params,
7553 &elem->nparams))
7554 goto cleanup;
7555
7556 tmpret[i] = g_steal_pointer(&elem);
7557 }
7558
7559 *retStats = g_steal_pointer(&tmpret);
7560 rv = ret.retStats.retStats_len;
7561
7562 cleanup:
7563 if (elem) {
7564 virObjectUnref(elem->dom);
7565 VIR_FREE(elem);
7566 }
7567 virDomainStatsRecordListFree(tmpret);
7568 VIR_FREE(args.doms.doms_val);
7569 xdr_free((xdrproc_t)xdr_remote_connect_get_all_domain_stats_ret,
7570 (char *) &ret);
7571
7572 return rv;
7573 }
7574
7575
7576 static int
remoteNodeAllocPages(virConnectPtr conn,unsigned int npages,unsigned int * pageSizes,unsigned long long * pageCounts,int startCell,unsigned int cellCount,unsigned int flags)7577 remoteNodeAllocPages(virConnectPtr conn,
7578 unsigned int npages,
7579 unsigned int *pageSizes,
7580 unsigned long long *pageCounts,
7581 int startCell,
7582 unsigned int cellCount,
7583 unsigned int flags)
7584 {
7585 int rv = -1;
7586 remote_node_alloc_pages_args args;
7587 remote_node_alloc_pages_ret ret;
7588 struct private_data *priv = conn->privateData;
7589
7590 remoteDriverLock(priv);
7591
7592 if (npages > REMOTE_NODE_MAX_CELLS) {
7593 virReportError(VIR_ERR_RPC,
7594 _("too many NUMA cells: %d > %d"),
7595 npages, REMOTE_NODE_MAX_CELLS);
7596 goto done;
7597 }
7598
7599 args.pageSizes.pageSizes_val = (u_int *) pageSizes;
7600 args.pageSizes.pageSizes_len = npages;
7601 args.pageCounts.pageCounts_val = (uint64_t *) pageCounts;
7602 args.pageCounts.pageCounts_len = npages;
7603 args.startCell = startCell;
7604 args.cellCount = cellCount;
7605 args.flags = flags;
7606
7607 memset(&ret, 0, sizeof(ret));
7608 if (call(conn, priv, 0, REMOTE_PROC_NODE_ALLOC_PAGES,
7609 (xdrproc_t) xdr_remote_node_alloc_pages_args, (char *) &args,
7610 (xdrproc_t) xdr_remote_node_alloc_pages_ret, (char *) &ret) == -1)
7611 goto done;
7612
7613 rv = ret.ret;
7614
7615 done:
7616 remoteDriverUnlock(priv);
7617 return rv;
7618 }
7619
7620
7621 static int
remoteDomainGetFSInfo(virDomainPtr dom,virDomainFSInfoPtr ** info,unsigned int flags)7622 remoteDomainGetFSInfo(virDomainPtr dom,
7623 virDomainFSInfoPtr **info,
7624 unsigned int flags)
7625 {
7626 int rv = -1;
7627 size_t i, j, len;
7628 struct private_data *priv = dom->conn->privateData;
7629 remote_domain_get_fsinfo_args args;
7630 remote_domain_get_fsinfo_ret ret;
7631 remote_domain_fsinfo *src;
7632
7633 remoteDriverLock(priv);
7634
7635 make_nonnull_domain(&args.dom, dom);
7636
7637 args.flags = flags;
7638
7639 memset(&ret, 0, sizeof(ret));
7640
7641 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_FSINFO,
7642 (xdrproc_t)xdr_remote_domain_get_fsinfo_args, (char *)&args,
7643 (xdrproc_t)xdr_remote_domain_get_fsinfo_ret, (char *)&ret) == -1)
7644 goto done;
7645
7646 if (ret.info.info_len > REMOTE_DOMAIN_FSINFO_MAX) {
7647 virReportError(VIR_ERR_INTERNAL_ERROR,
7648 _("Too many mountpoints in fsinfo: %d for limit %d"),
7649 ret.info.info_len, REMOTE_DOMAIN_FSINFO_MAX);
7650 goto cleanup;
7651 }
7652
7653 if (info) {
7654 virDomainFSInfoPtr *info_ret = NULL;
7655
7656 if (!ret.info.info_len) {
7657 *info = NULL;
7658 rv = ret.ret;
7659 goto cleanup;
7660 }
7661
7662 info_ret = g_new0(virDomainFSInfoPtr, ret.info.info_len);
7663
7664 for (i = 0; i < ret.info.info_len; i++) {
7665 src = &ret.info.info_val[i];
7666
7667 info_ret[i] = g_new0(virDomainFSInfo, 1);
7668
7669 info_ret[i]->mountpoint = g_strdup(src->mountpoint);
7670
7671 info_ret[i]->name = g_strdup(src->name);
7672
7673 info_ret[i]->fstype = g_strdup(src->fstype);
7674
7675 len = src->dev_aliases.dev_aliases_len;
7676 info_ret[i]->ndevAlias = len;
7677 if (len)
7678 info_ret[i]->devAlias = g_new0(char *, len);
7679
7680 for (j = 0; j < len; j++)
7681 info_ret[i]->devAlias[j] = g_strdup(src->dev_aliases.dev_aliases_val[j]);
7682 }
7683
7684 *info = info_ret;
7685 }
7686
7687 rv = ret.ret;
7688
7689 cleanup:
7690 xdr_free((xdrproc_t)xdr_remote_domain_get_fsinfo_ret,
7691 (char *) &ret);
7692
7693 done:
7694 remoteDriverUnlock(priv);
7695 return rv;
7696 }
7697
7698
7699 static int
remoteDomainInterfaceAddresses(virDomainPtr dom,virDomainInterfacePtr ** ifaces,unsigned int source,unsigned int flags)7700 remoteDomainInterfaceAddresses(virDomainPtr dom,
7701 virDomainInterfacePtr **ifaces,
7702 unsigned int source,
7703 unsigned int flags)
7704 {
7705 int rv = -1;
7706 size_t i, j;
7707
7708 virDomainInterfacePtr *ifaces_ret = NULL;
7709 remote_domain_interface_addresses_args args;
7710 remote_domain_interface_addresses_ret ret;
7711
7712 struct private_data *priv = dom->conn->privateData;
7713
7714 args.source = source;
7715 args.flags = flags;
7716 make_nonnull_domain(&args.dom, dom);
7717
7718 remoteDriverLock(priv);
7719
7720 memset(&ret, 0, sizeof(ret));
7721
7722 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES,
7723 (xdrproc_t)xdr_remote_domain_interface_addresses_args,
7724 (char *)&args,
7725 (xdrproc_t)xdr_remote_domain_interface_addresses_ret,
7726 (char *)&ret) == -1) {
7727 goto done;
7728 }
7729
7730 if (ret.ifaces.ifaces_len > REMOTE_DOMAIN_INTERFACE_MAX) {
7731 virReportError(VIR_ERR_INTERNAL_ERROR,
7732 _("Number of interfaces, %d exceeds the max limit: %d"),
7733 ret.ifaces.ifaces_len, REMOTE_DOMAIN_INTERFACE_MAX);
7734 goto cleanup;
7735 }
7736
7737 if (ret.ifaces.ifaces_len)
7738 ifaces_ret = g_new0(virDomainInterfacePtr, ret.ifaces.ifaces_len);
7739
7740 for (i = 0; i < ret.ifaces.ifaces_len; i++) {
7741 virDomainInterfacePtr iface;
7742 remote_domain_interface *iface_ret = &(ret.ifaces.ifaces_val[i]);
7743
7744 ifaces_ret[i] = g_new0(virDomainInterface, 1);
7745
7746 iface = ifaces_ret[i];
7747
7748 iface->name = g_strdup(iface_ret->name);
7749
7750 if (iface_ret->hwaddr)
7751 iface->hwaddr = g_strdup(*iface_ret->hwaddr);
7752
7753 if (iface_ret->addrs.addrs_len > REMOTE_DOMAIN_IP_ADDR_MAX) {
7754 virReportError(VIR_ERR_INTERNAL_ERROR,
7755 _("Number of interfaces, %d exceeds the max limit: %d"),
7756 iface_ret->addrs.addrs_len, REMOTE_DOMAIN_IP_ADDR_MAX);
7757 goto cleanup;
7758 }
7759
7760 iface->naddrs = iface_ret->addrs.addrs_len;
7761
7762 if (iface->naddrs) {
7763 iface->addrs = g_new0(virDomainIPAddress, iface->naddrs);
7764
7765 for (j = 0; j < iface->naddrs; j++) {
7766 virDomainIPAddressPtr ip_addr = &(iface->addrs[j]);
7767 remote_domain_ip_addr *ip_addr_ret =
7768 &(iface_ret->addrs.addrs_val[j]);
7769
7770 ip_addr->addr = g_strdup(ip_addr_ret->addr);
7771
7772 ip_addr->prefix = ip_addr_ret->prefix;
7773 ip_addr->type = ip_addr_ret->type;
7774 }
7775 }
7776 }
7777 *ifaces = g_steal_pointer(&ifaces_ret);
7778
7779 rv = ret.ifaces.ifaces_len;
7780
7781 cleanup:
7782 if (ifaces_ret) {
7783 for (i = 0; i < ret.ifaces.ifaces_len; i++)
7784 virDomainInterfaceFree(ifaces_ret[i]);
7785 VIR_FREE(ifaces_ret);
7786 }
7787 xdr_free((xdrproc_t)xdr_remote_domain_interface_addresses_ret,
7788 (char *) &ret);
7789 done:
7790 remoteDriverUnlock(priv);
7791 return rv;
7792 }
7793
7794 static int
remoteConnectRegisterCloseCallback(virConnectPtr conn,virConnectCloseFunc cb,void * opaque,virFreeCallback freecb)7795 remoteConnectRegisterCloseCallback(virConnectPtr conn,
7796 virConnectCloseFunc cb,
7797 void *opaque,
7798 virFreeCallback freecb)
7799 {
7800 struct private_data *priv = conn->privateData;
7801 int ret = -1;
7802
7803 remoteDriverLock(priv);
7804
7805 if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != NULL) {
7806 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
7807 _("A close callback is already registered"));
7808 goto cleanup;
7809 }
7810
7811 if (priv->serverCloseCallback &&
7812 call(conn, priv, 0, REMOTE_PROC_CONNECT_REGISTER_CLOSE_CALLBACK,
7813 (xdrproc_t) xdr_void, (char *) NULL,
7814 (xdrproc_t) xdr_void, (char *) NULL) == -1)
7815 goto cleanup;
7816
7817 virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb,
7818 opaque, freecb);
7819 ret = 0;
7820
7821 cleanup:
7822 remoteDriverUnlock(priv);
7823
7824 return ret;
7825 }
7826
7827 static int
remoteConnectUnregisterCloseCallback(virConnectPtr conn,virConnectCloseFunc cb)7828 remoteConnectUnregisterCloseCallback(virConnectPtr conn,
7829 virConnectCloseFunc cb)
7830 {
7831 struct private_data *priv = conn->privateData;
7832 int ret = -1;
7833
7834 remoteDriverLock(priv);
7835
7836 if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != cb) {
7837 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
7838 _("A different callback was requested"));
7839 goto cleanup;
7840 }
7841
7842 if (priv->serverCloseCallback &&
7843 call(conn, priv, 0, REMOTE_PROC_CONNECT_UNREGISTER_CLOSE_CALLBACK,
7844 (xdrproc_t) xdr_void, (char *) NULL,
7845 (xdrproc_t) xdr_void, (char *) NULL) == -1)
7846 goto cleanup;
7847
7848 virConnectCloseCallbackDataUnregister(priv->closeCallback, cb);
7849 ret = 0;
7850
7851 cleanup:
7852 remoteDriverUnlock(priv);
7853
7854 return ret;
7855 }
7856
7857 static int
remoteDomainRename(virDomainPtr dom,const char * new_name,unsigned int flags)7858 remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags)
7859 {
7860 int rv = -1;
7861 struct private_data *priv = dom->conn->privateData;
7862 remote_domain_rename_args args;
7863 remote_domain_rename_ret ret;
7864 char *tmp = NULL;
7865
7866 tmp = g_strdup(new_name);
7867
7868 remoteDriverLock(priv);
7869
7870 make_nonnull_domain(&args.dom, dom);
7871 args.new_name = new_name ? (char **)&new_name : NULL;
7872 args.flags = flags;
7873
7874 memset(&ret, 0, sizeof(ret));
7875
7876 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_RENAME,
7877 (xdrproc_t)xdr_remote_domain_rename_args, (char *)&args,
7878 (xdrproc_t)xdr_remote_domain_rename_ret, (char *)&ret) == -1) {
7879 goto done;
7880 }
7881
7882 rv = ret.retcode;
7883
7884 if (rv == 0) {
7885 VIR_FREE(dom->name);
7886 dom->name = g_steal_pointer(&tmp);
7887 }
7888
7889 done:
7890 remoteDriverUnlock(priv);
7891 VIR_FREE(tmp);
7892 return rv;
7893 }
7894
7895
7896 static int
remoteStorageVolGetInfoFlags(virStorageVolPtr vol,virStorageVolInfoPtr result,unsigned int flags)7897 remoteStorageVolGetInfoFlags(virStorageVolPtr vol,
7898 virStorageVolInfoPtr result,
7899 unsigned int flags)
7900 {
7901 int rv = -1;
7902 struct private_data *priv = vol->conn->privateData;
7903 remote_storage_vol_get_info_flags_args args;
7904 remote_storage_vol_get_info_flags_ret ret;
7905
7906 remoteDriverLock(priv);
7907
7908 make_nonnull_storage_vol(&args.vol, vol);
7909 args.flags = flags;
7910
7911 memset(&ret, 0, sizeof(ret));
7912
7913 if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_INFO_FLAGS,
7914 (xdrproc_t)xdr_remote_storage_vol_get_info_flags_args,
7915 (char *)&args,
7916 (xdrproc_t)xdr_remote_storage_vol_get_info_flags_ret,
7917 (char *)&ret) == -1) {
7918 goto done;
7919 }
7920
7921 result->type = ret.type;
7922 result->capacity = ret.capacity;
7923 result->allocation = ret.allocation;
7924 rv = 0;
7925
7926 done:
7927 remoteDriverUnlock(priv);
7928 return rv;
7929 }
7930
7931
7932 static int
remoteNetworkPortGetParameters(virNetworkPortPtr port,virTypedParameterPtr * params,int * nparams,unsigned int flags)7933 remoteNetworkPortGetParameters(virNetworkPortPtr port,
7934 virTypedParameterPtr *params,
7935 int *nparams,
7936 unsigned int flags)
7937 {
7938 int rv = -1;
7939 struct private_data *priv = port->net->conn->privateData;
7940 remote_network_port_get_parameters_args args;
7941 remote_network_port_get_parameters_ret ret;
7942
7943 remoteDriverLock(priv);
7944
7945 make_nonnull_network_port(&args.port, port);
7946 args.flags = flags;
7947
7948 memset(&ret, 0, sizeof(ret));
7949 if (call(port->net->conn, priv, 0, REMOTE_PROC_NETWORK_PORT_GET_PARAMETERS,
7950 (xdrproc_t) xdr_remote_network_port_get_parameters_args, (char *) &args,
7951 (xdrproc_t) xdr_remote_network_port_get_parameters_ret, (char *) &ret) == -1)
7952 goto done;
7953
7954 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
7955 ret.params.params_len,
7956 REMOTE_NETWORK_PORT_PARAMETERS_MAX,
7957 params,
7958 nparams) < 0)
7959 goto cleanup;
7960
7961 rv = 0;
7962
7963 cleanup:
7964 xdr_free((xdrproc_t) xdr_remote_network_port_get_parameters_ret, (char *) &ret);
7965 done:
7966 remoteDriverUnlock(priv);
7967 return rv;
7968 }
7969
7970 static int
remoteDomainGetGuestInfo(virDomainPtr dom,unsigned int types,virTypedParameterPtr * params,int * nparams,unsigned int flags)7971 remoteDomainGetGuestInfo(virDomainPtr dom,
7972 unsigned int types,
7973 virTypedParameterPtr *params,
7974 int *nparams,
7975 unsigned int flags)
7976 {
7977 int rv = -1;
7978 struct private_data *priv = dom->conn->privateData;
7979 remote_domain_get_guest_info_args args;
7980 remote_domain_get_guest_info_ret ret;
7981
7982 remoteDriverLock(priv);
7983
7984 make_nonnull_domain(&args.dom, dom);
7985
7986 args.types = types;
7987 args.flags = flags;
7988
7989 memset(&ret, 0, sizeof(ret));
7990
7991 if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_GUEST_INFO,
7992 (xdrproc_t)xdr_remote_domain_get_guest_info_args, (char *)&args,
7993 (xdrproc_t)xdr_remote_domain_get_guest_info_ret, (char *)&ret) == -1)
7994 goto done;
7995
7996 if (virTypedParamsDeserialize((struct _virTypedParameterRemote *) ret.params.params_val,
7997 ret.params.params_len,
7998 REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX,
7999 params,
8000 nparams) < 0)
8001 goto cleanup;
8002
8003 rv = 0;
8004
8005 cleanup:
8006 xdr_free((xdrproc_t)xdr_remote_domain_get_guest_info_ret,
8007 (char *) &ret);
8008
8009 done:
8010 remoteDriverUnlock(priv);
8011 return rv;
8012 }
8013
8014 static int
remoteDomainAuthorizedSSHKeysGet(virDomainPtr domain,const char * user,char *** keys,unsigned int flags)8015 remoteDomainAuthorizedSSHKeysGet(virDomainPtr domain,
8016 const char *user,
8017 char ***keys,
8018 unsigned int flags)
8019 {
8020 int rv = -1;
8021 size_t i;
8022 struct private_data *priv = domain->conn->privateData;
8023 remote_domain_authorized_ssh_keys_get_args args;
8024 remote_domain_authorized_ssh_keys_get_ret ret;
8025
8026 remoteDriverLock(priv);
8027
8028 make_nonnull_domain(&args.dom, domain);
8029 args.user = (char *) user;
8030 args.flags = flags;
8031 memset(&ret, 0, sizeof(ret));
8032
8033 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_GET,
8034 (xdrproc_t) xdr_remote_domain_authorized_ssh_keys_get_args, (char *)&args,
8035 (xdrproc_t) xdr_remote_domain_authorized_ssh_keys_get_ret, (char *)&ret) == -1) {
8036 goto cleanup;
8037 }
8038
8039 if (ret.keys.keys_len > REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX) {
8040 virReportError(VIR_ERR_RPC, "%s",
8041 _("remoteDomainAuthorizedSSHKeysGet: "
8042 "returned number of keys exceeds limit"));
8043 goto cleanup;
8044 }
8045
8046 *keys = g_new0(char *, ret.keys.keys_len + 1);
8047 for (i = 0; i < ret.keys.keys_len; i++)
8048 (*keys)[i] = g_strdup(ret.keys.keys_val[i]);
8049
8050 rv = ret.keys.keys_len;
8051
8052 cleanup:
8053 remoteDriverUnlock(priv);
8054 xdr_free((xdrproc_t)xdr_remote_domain_authorized_ssh_keys_get_ret,
8055 (char *) &ret);
8056 return rv;
8057 }
8058
8059 static int
remoteDomainAuthorizedSSHKeysSet(virDomainPtr domain,const char * user,const char ** keys,unsigned int nkeys,unsigned int flags)8060 remoteDomainAuthorizedSSHKeysSet(virDomainPtr domain,
8061 const char *user,
8062 const char **keys,
8063 unsigned int nkeys,
8064 unsigned int flags)
8065 {
8066 int rv = -1;
8067 struct private_data *priv = domain->conn->privateData;
8068 remote_domain_authorized_ssh_keys_set_args args;
8069
8070 remoteDriverLock(priv);
8071
8072 if (nkeys > REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX) {
8073 virReportError(VIR_ERR_RPC, "%s",
8074 _("remoteDomainAuthorizedSSHKeysSet: "
8075 "returned number of keys exceeds limit"));
8076 goto cleanup;
8077 }
8078
8079 make_nonnull_domain(&args.dom, domain);
8080 args.user = (char *) user;
8081 args.keys.keys_len = nkeys;
8082 args.keys.keys_val = (char **) keys;
8083 args.flags = flags;
8084
8085 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET,
8086 (xdrproc_t) xdr_remote_domain_authorized_ssh_keys_set_args, (char *)&args,
8087 (xdrproc_t) xdr_void, (char *) NULL) == -1) {
8088 goto cleanup;
8089 }
8090
8091 rv = 0;
8092
8093 cleanup:
8094 remoteDriverUnlock(priv);
8095 return rv;
8096 }
8097
8098
8099 static int
remoteDomainGetMessages(virDomainPtr domain,char *** msgs,unsigned int flags)8100 remoteDomainGetMessages(virDomainPtr domain,
8101 char ***msgs,
8102 unsigned int flags)
8103 {
8104 int rv = -1;
8105 size_t i;
8106 struct private_data *priv = domain->conn->privateData;
8107 remote_domain_get_messages_args args;
8108 remote_domain_get_messages_ret ret;
8109
8110 remoteDriverLock(priv);
8111
8112 make_nonnull_domain(&args.dom, domain);
8113 args.flags = flags;
8114 memset(&ret, 0, sizeof(ret));
8115
8116 if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_MESSAGES,
8117 (xdrproc_t) xdr_remote_domain_get_messages_args, (char *)&args,
8118 (xdrproc_t) xdr_remote_domain_get_messages_ret, (char *)&ret) == -1) {
8119 goto cleanup;
8120 }
8121
8122 if (ret.msgs.msgs_len > REMOTE_DOMAIN_MESSAGES_MAX) {
8123 virReportError(VIR_ERR_RPC, "%s",
8124 _("remoteDomainGetMessages: "
8125 "returned number of msgs exceeds limit"));
8126 goto cleanup;
8127 }
8128
8129 *msgs = g_new0(char *, ret.msgs.msgs_len + 1);
8130 for (i = 0; i < ret.msgs.msgs_len; i++)
8131 (*msgs)[i] = g_strdup(ret.msgs.msgs_val[i]);
8132
8133 rv = ret.msgs.msgs_len;
8134
8135 cleanup:
8136 remoteDriverUnlock(priv);
8137 xdr_free((xdrproc_t)xdr_remote_domain_get_messages_ret,
8138 (char *) &ret);
8139 return rv;
8140 }
8141
8142 /* get_nonnull_domain and get_nonnull_network turn an on-wire
8143 * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
8144 * These can return NULL if underlying memory allocations fail,
8145 * but if they do then virterror_internal.has been set.
8146 */
8147 static virDomainPtr
get_nonnull_domain(virConnectPtr conn,remote_nonnull_domain domain)8148 get_nonnull_domain(virConnectPtr conn, remote_nonnull_domain domain)
8149 {
8150 return virGetDomain(conn, domain.name, BAD_CAST domain.uuid, domain.id);
8151 }
8152
8153 static virNetworkPtr
get_nonnull_network(virConnectPtr conn,remote_nonnull_network network)8154 get_nonnull_network(virConnectPtr conn, remote_nonnull_network network)
8155 {
8156 return virGetNetwork(conn, network.name, BAD_CAST network.uuid);
8157 }
8158
8159 static virNetworkPortPtr
get_nonnull_network_port(virConnectPtr conn,remote_nonnull_network_port port)8160 get_nonnull_network_port(virConnectPtr conn, remote_nonnull_network_port port)
8161 {
8162 virNetworkPortPtr ret;
8163 virNetworkPtr net;
8164 net = virGetNetwork(conn, port.net.name, BAD_CAST port.net.uuid);
8165 if (!net)
8166 return NULL;
8167 ret = virGetNetworkPort(net, BAD_CAST port.uuid);
8168 virObjectUnref(net);
8169 return ret;
8170 }
8171
8172 static virInterfacePtr
get_nonnull_interface(virConnectPtr conn,remote_nonnull_interface iface)8173 get_nonnull_interface(virConnectPtr conn, remote_nonnull_interface iface)
8174 {
8175 return virGetInterface(conn, iface.name, iface.mac);
8176 }
8177
8178 static virStoragePoolPtr
get_nonnull_storage_pool(virConnectPtr conn,remote_nonnull_storage_pool pool)8179 get_nonnull_storage_pool(virConnectPtr conn, remote_nonnull_storage_pool pool)
8180 {
8181 return virGetStoragePool(conn, pool.name, BAD_CAST pool.uuid,
8182 NULL, NULL);
8183 }
8184
8185 static virStorageVolPtr
get_nonnull_storage_vol(virConnectPtr conn,remote_nonnull_storage_vol vol)8186 get_nonnull_storage_vol(virConnectPtr conn, remote_nonnull_storage_vol vol)
8187 {
8188 return virGetStorageVol(conn, vol.pool, vol.name, vol.key,
8189 NULL, NULL);
8190 }
8191
8192 static virNodeDevicePtr
get_nonnull_node_device(virConnectPtr conn,remote_nonnull_node_device dev)8193 get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev)
8194 {
8195 return virGetNodeDevice(conn, dev.name);
8196 }
8197
8198 static virSecretPtr
get_nonnull_secret(virConnectPtr conn,remote_nonnull_secret secret)8199 get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret)
8200 {
8201 return virGetSecret(conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID);
8202 }
8203
8204 static virNWFilterPtr
get_nonnull_nwfilter(virConnectPtr conn,remote_nonnull_nwfilter nwfilter)8205 get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter)
8206 {
8207 return virGetNWFilter(conn, nwfilter.name, BAD_CAST nwfilter.uuid);
8208 }
8209
8210 static virNWFilterBindingPtr
get_nonnull_nwfilter_binding(virConnectPtr conn,remote_nonnull_nwfilter_binding binding)8211 get_nonnull_nwfilter_binding(virConnectPtr conn, remote_nonnull_nwfilter_binding binding)
8212 {
8213 return virGetNWFilterBinding(conn, binding.portdev, binding.filtername);
8214 }
8215
8216 static virDomainCheckpointPtr
get_nonnull_domain_checkpoint(virDomainPtr domain,remote_nonnull_domain_checkpoint checkpoint)8217 get_nonnull_domain_checkpoint(virDomainPtr domain, remote_nonnull_domain_checkpoint checkpoint)
8218 {
8219 return virGetDomainCheckpoint(domain, checkpoint.name);
8220 }
8221
8222 static virDomainSnapshotPtr
get_nonnull_domain_snapshot(virDomainPtr domain,remote_nonnull_domain_snapshot snapshot)8223 get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot)
8224 {
8225 return virGetDomainSnapshot(domain, snapshot.name);
8226 }
8227
8228
8229 /* Make remote_nonnull_domain and remote_nonnull_network. */
8230 static void
make_nonnull_domain(remote_nonnull_domain * dom_dst,virDomainPtr dom_src)8231 make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
8232 {
8233 dom_dst->id = dom_src->id;
8234 dom_dst->name = dom_src->name;
8235 memcpy(dom_dst->uuid, dom_src->uuid, VIR_UUID_BUFLEN);
8236 }
8237
8238 static void
make_nonnull_network(remote_nonnull_network * net_dst,virNetworkPtr net_src)8239 make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src)
8240 {
8241 net_dst->name = net_src->name;
8242 memcpy(net_dst->uuid, net_src->uuid, VIR_UUID_BUFLEN);
8243 }
8244
8245 static void
make_nonnull_network_port(remote_nonnull_network_port * port_dst,virNetworkPortPtr port_src)8246 make_nonnull_network_port(remote_nonnull_network_port *port_dst, virNetworkPortPtr port_src)
8247 {
8248 port_dst->net.name = port_src->net->name;
8249 memcpy(port_dst->net.uuid, port_src->net->uuid, VIR_UUID_BUFLEN);
8250 memcpy(port_dst->uuid, port_src->uuid, VIR_UUID_BUFLEN);
8251 }
8252
8253 static void
make_nonnull_interface(remote_nonnull_interface * interface_dst,virInterfacePtr interface_src)8254 make_nonnull_interface(remote_nonnull_interface *interface_dst,
8255 virInterfacePtr interface_src)
8256 {
8257 interface_dst->name = interface_src->name;
8258 interface_dst->mac = interface_src->mac;
8259 }
8260
8261 static void
make_nonnull_storage_pool(remote_nonnull_storage_pool * pool_dst,virStoragePoolPtr pool_src)8262 make_nonnull_storage_pool(remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src)
8263 {
8264 pool_dst->name = pool_src->name;
8265 memcpy(pool_dst->uuid, pool_src->uuid, VIR_UUID_BUFLEN);
8266 }
8267
8268 static void
make_nonnull_storage_vol(remote_nonnull_storage_vol * vol_dst,virStorageVolPtr vol_src)8269 make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src)
8270 {
8271 vol_dst->pool = vol_src->pool;
8272 vol_dst->name = vol_src->name;
8273 vol_dst->key = vol_src->key;
8274 }
8275
8276 static void
make_nonnull_secret(remote_nonnull_secret * secret_dst,virSecretPtr secret_src)8277 make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
8278 {
8279 memcpy(secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
8280 secret_dst->usageType = secret_src->usageType;
8281 secret_dst->usageID = secret_src->usageID;
8282 }
8283
8284 static void
make_nonnull_node_device(remote_nonnull_node_device * dev_dst,virNodeDevicePtr dev_src)8285 make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src)
8286 {
8287 dev_dst->name = dev_src->name;
8288 }
8289
8290 static void
make_nonnull_nwfilter(remote_nonnull_nwfilter * nwfilter_dst,virNWFilterPtr nwfilter_src)8291 make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src)
8292 {
8293 nwfilter_dst->name = nwfilter_src->name;
8294 memcpy(nwfilter_dst->uuid, nwfilter_src->uuid, VIR_UUID_BUFLEN);
8295 }
8296
8297 static void
make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding * binding_dst,virNWFilterBindingPtr binding_src)8298 make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding *binding_dst, virNWFilterBindingPtr binding_src)
8299 {
8300 binding_dst->portdev = binding_src->portdev;
8301 binding_dst->filtername = binding_src->filtername;
8302 }
8303
8304 static void
make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint * checkpoint_dst,virDomainCheckpointPtr checkpoint_src)8305 make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint *checkpoint_dst, virDomainCheckpointPtr checkpoint_src)
8306 {
8307 checkpoint_dst->name = checkpoint_src->name;
8308 make_nonnull_domain(&checkpoint_dst->dom, checkpoint_src->domain);
8309 }
8310
8311 static void
make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot * snapshot_dst,virDomainSnapshotPtr snapshot_src)8312 make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src)
8313 {
8314 snapshot_dst->name = snapshot_src->name;
8315 make_nonnull_domain(&snapshot_dst->dom, snapshot_src->domain);
8316 }
8317
8318 /*----------------------------------------------------------------------*/
8319
remoteVersion(void)8320 unsigned long remoteVersion(void)
8321 {
8322 return REMOTE_PROTOCOL_VERSION;
8323 }
8324
8325 static virHypervisorDriver hypervisor_driver = {
8326 .name = "remote",
8327 .connectOpen = remoteConnectOpen, /* 0.3.0 */
8328 .connectClose = remoteConnectClose, /* 0.3.0 */
8329 .connectSetIdentity = remoteConnectSetIdentity, /* 5.8.0 */
8330 .connectSupportsFeature = remoteConnectSupportsFeature, /* 0.3.0 */
8331 .connectGetType = remoteConnectGetType, /* 0.3.0 */
8332 .connectGetVersion = remoteConnectGetVersion, /* 0.3.0 */
8333 .connectGetLibVersion = remoteConnectGetLibVersion, /* 0.7.3 */
8334 .connectGetHostname = remoteConnectGetHostname, /* 0.3.0 */
8335 .connectGetSysinfo = remoteConnectGetSysinfo, /* 0.8.8 */
8336 .connectGetMaxVcpus = remoteConnectGetMaxVcpus, /* 0.3.0 */
8337 .nodeGetInfo = remoteNodeGetInfo, /* 0.3.0 */
8338 .connectGetCapabilities = remoteConnectGetCapabilities, /* 0.3.0 */
8339 .connectListDomains = remoteConnectListDomains, /* 0.3.0 */
8340 .connectNumOfDomains = remoteConnectNumOfDomains, /* 0.3.0 */
8341 .connectListAllDomains = remoteConnectListAllDomains, /* 0.9.13 */
8342 .domainCreateXML = remoteDomainCreateXML, /* 0.3.0 */
8343 .domainCreateXMLWithFiles = remoteDomainCreateXMLWithFiles, /* 1.1.1 */
8344 .domainLookupByID = remoteDomainLookupByID, /* 0.3.0 */
8345 .domainLookupByUUID = remoteDomainLookupByUUID, /* 0.3.0 */
8346 .domainLookupByName = remoteDomainLookupByName, /* 0.3.0 */
8347 .domainSuspend = remoteDomainSuspend, /* 0.3.0 */
8348 .domainResume = remoteDomainResume, /* 0.3.0 */
8349 .domainPMSuspendForDuration = remoteDomainPMSuspendForDuration, /* 0.9.10 */
8350 .domainPMWakeup = remoteDomainPMWakeup, /* 0.9.11 */
8351 .domainShutdown = remoteDomainShutdown, /* 0.3.0 */
8352 .domainShutdownFlags = remoteDomainShutdownFlags, /* 0.9.10 */
8353 .domainReboot = remoteDomainReboot, /* 0.3.0 */
8354 .domainReset = remoteDomainReset, /* 0.9.7 */
8355 .domainDestroy = remoteDomainDestroy, /* 0.3.0 */
8356 .domainDestroyFlags = remoteDomainDestroyFlags, /* 0.9.4 */
8357 .domainGetOSType = remoteDomainGetOSType, /* 0.3.0 */
8358 .domainGetMaxMemory = remoteDomainGetMaxMemory, /* 0.3.0 */
8359 .domainSetMaxMemory = remoteDomainSetMaxMemory, /* 0.3.0 */
8360 .domainSetMemory = remoteDomainSetMemory, /* 0.3.0 */
8361 .domainSetMemoryFlags = remoteDomainSetMemoryFlags, /* 0.9.0 */
8362 .domainSetMemoryStatsPeriod = remoteDomainSetMemoryStatsPeriod, /* 1.1.1 */
8363 .domainSetMemoryParameters = remoteDomainSetMemoryParameters, /* 0.8.5 */
8364 .domainGetMemoryParameters = remoteDomainGetMemoryParameters, /* 0.8.5 */
8365 .domainSetBlkioParameters = remoteDomainSetBlkioParameters, /* 0.9.0 */
8366 .domainGetBlkioParameters = remoteDomainGetBlkioParameters, /* 0.9.0 */
8367 .domainGetPerfEvents = remoteDomainGetPerfEvents, /* 1.3.3 */
8368 .domainSetPerfEvents = remoteDomainSetPerfEvents, /* 1.3.3 */
8369 .domainGetInfo = remoteDomainGetInfo, /* 0.3.0 */
8370 .domainGetState = remoteDomainGetState, /* 0.9.2 */
8371 .domainGetControlInfo = remoteDomainGetControlInfo, /* 0.9.3 */
8372 .domainSave = remoteDomainSave, /* 0.3.0 */
8373 .domainSaveFlags = remoteDomainSaveFlags, /* 0.9.4 */
8374 .domainRestore = remoteDomainRestore, /* 0.3.0 */
8375 .domainRestoreFlags = remoteDomainRestoreFlags, /* 0.9.4 */
8376 .domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */
8377 .domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */
8378 .domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */
8379 .domainCoreDumpWithFormat = remoteDomainCoreDumpWithFormat, /* 1.2.3 */
8380 .domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */
8381 .domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */
8382 .domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */
8383 .domainGetVcpusFlags = remoteDomainGetVcpusFlags, /* 0.8.5 */
8384 .domainPinVcpu = remoteDomainPinVcpu, /* 0.3.0 */
8385 .domainPinVcpuFlags = remoteDomainPinVcpuFlags, /* 0.9.3 */
8386 .domainGetVcpuPinInfo = remoteDomainGetVcpuPinInfo, /* 0.9.3 */
8387 .domainPinEmulator = remoteDomainPinEmulator, /* 0.10.0 */
8388 .domainGetEmulatorPinInfo = remoteDomainGetEmulatorPinInfo, /* 0.10.0 */
8389 .domainGetVcpus = remoteDomainGetVcpus, /* 0.3.0 */
8390 .domainGetMaxVcpus = remoteDomainGetMaxVcpus, /* 0.3.0 */
8391 .domainGetIOThreadInfo = remoteDomainGetIOThreadInfo, /* 1.2.14 */
8392 .domainPinIOThread = remoteDomainPinIOThread, /* 1.2.14 */
8393 .domainAddIOThread = remoteDomainAddIOThread, /* 1.2.15 */
8394 .domainDelIOThread = remoteDomainDelIOThread, /* 1.2.15 */
8395 .domainSetIOThreadParams = remoteDomainSetIOThreadParams, /* 4.10.0 */
8396 .domainGetSecurityLabel = remoteDomainGetSecurityLabel, /* 0.6.1 */
8397 .domainGetSecurityLabelList = remoteDomainGetSecurityLabelList, /* 0.10.0 */
8398 .nodeGetSecurityModel = remoteNodeGetSecurityModel, /* 0.6.1 */
8399 .domainGetXMLDesc = remoteDomainGetXMLDesc, /* 0.3.0 */
8400 .connectDomainXMLFromNative = remoteConnectDomainXMLFromNative, /* 0.6.4 */
8401 .connectDomainXMLToNative = remoteConnectDomainXMLToNative, /* 0.6.4 */
8402 .connectListDefinedDomains = remoteConnectListDefinedDomains, /* 0.3.0 */
8403 .connectNumOfDefinedDomains = remoteConnectNumOfDefinedDomains, /* 0.3.0 */
8404 .domainCreate = remoteDomainCreate, /* 0.3.0 */
8405 .domainCreateWithFlags = remoteDomainCreateWithFlags, /* 0.8.2 */
8406 .domainCreateWithFiles = remoteDomainCreateWithFiles, /* 1.1.1 */
8407 .domainDefineXML = remoteDomainDefineXML, /* 0.3.0 */
8408 .domainDefineXMLFlags = remoteDomainDefineXMLFlags, /* 1.2.12 */
8409 .domainUndefine = remoteDomainUndefine, /* 0.3.0 */
8410 .domainUndefineFlags = remoteDomainUndefineFlags, /* 0.9.4 */
8411 .domainAttachDevice = remoteDomainAttachDevice, /* 0.3.0 */
8412 .domainAttachDeviceFlags = remoteDomainAttachDeviceFlags, /* 0.7.7 */
8413 .domainDetachDevice = remoteDomainDetachDevice, /* 0.3.0 */
8414 .domainDetachDeviceFlags = remoteDomainDetachDeviceFlags, /* 0.7.7 */
8415 .domainUpdateDeviceFlags = remoteDomainUpdateDeviceFlags, /* 0.8.0 */
8416 .domainDetachDeviceAlias = remoteDomainDetachDeviceAlias, /* 4.4.0 */
8417 .domainGetAutostart = remoteDomainGetAutostart, /* 0.3.0 */
8418 .domainSetAutostart = remoteDomainSetAutostart, /* 0.3.0 */
8419 .domainGetSchedulerType = remoteDomainGetSchedulerType, /* 0.3.0 */
8420 .domainGetSchedulerParameters = remoteDomainGetSchedulerParameters, /* 0.3.0 */
8421 .domainGetSchedulerParametersFlags = remoteDomainGetSchedulerParametersFlags, /* 0.9.2 */
8422 .domainSetSchedulerParameters = remoteDomainSetSchedulerParameters, /* 0.3.0 */
8423 .domainSetSchedulerParametersFlags = remoteDomainSetSchedulerParametersFlags, /* 0.9.2 */
8424 .domainMigratePrepare = remoteDomainMigratePrepare, /* 0.3.2 */
8425 .domainMigratePerform = remoteDomainMigratePerform, /* 0.3.2 */
8426 .domainMigrateFinish = remoteDomainMigrateFinish, /* 0.3.2 */
8427 .domainBlockResize = remoteDomainBlockResize, /* 0.9.8 */
8428 .domainBlockStats = remoteDomainBlockStats, /* 0.3.2 */
8429 .domainBlockStatsFlags = remoteDomainBlockStatsFlags, /* 0.9.5 */
8430 .domainInterfaceStats = remoteDomainInterfaceStats, /* 0.3.2 */
8431 .domainSetInterfaceParameters = remoteDomainSetInterfaceParameters, /* 0.9.9 */
8432 .domainGetInterfaceParameters = remoteDomainGetInterfaceParameters, /* 0.9.9 */
8433 .domainMemoryStats = remoteDomainMemoryStats, /* 0.7.5 */
8434 .domainBlockPeek = remoteDomainBlockPeek, /* 0.4.2 */
8435 .domainMemoryPeek = remoteDomainMemoryPeek, /* 0.4.2 */
8436 .domainGetBlockInfo = remoteDomainGetBlockInfo, /* 0.8.1 */
8437 .nodeGetCPUStats = remoteNodeGetCPUStats, /* 0.9.3 */
8438 .nodeGetMemoryStats = remoteNodeGetMemoryStats, /* 0.9.3 */
8439 .nodeGetCellsFreeMemory = remoteNodeGetCellsFreeMemory, /* 0.3.3 */
8440 .nodeGetFreeMemory = remoteNodeGetFreeMemory, /* 0.3.3 */
8441 .connectDomainEventRegister = remoteConnectDomainEventRegister, /* 0.5.0 */
8442 .connectDomainEventDeregister = remoteConnectDomainEventDeregister, /* 0.5.0 */
8443 .domainMigratePrepare2 = remoteDomainMigratePrepare2, /* 0.5.0 */
8444 .domainMigrateFinish2 = remoteDomainMigrateFinish2, /* 0.5.0 */
8445 .nodeDeviceDettach = remoteNodeDeviceDettach, /* 0.6.1 */
8446 .nodeDeviceDetachFlags = remoteNodeDeviceDetachFlags, /* 1.0.5 */
8447 .nodeDeviceReAttach = remoteNodeDeviceReAttach, /* 0.6.1 */
8448 .nodeDeviceReset = remoteNodeDeviceReset, /* 0.6.1 */
8449 .domainMigratePrepareTunnel = remoteDomainMigratePrepareTunnel, /* 0.7.2 */
8450 .connectIsEncrypted = remoteConnectIsEncrypted, /* 0.7.3 */
8451 .connectIsSecure = remoteConnectIsSecure, /* 0.7.3 */
8452 .domainIsActive = remoteDomainIsActive, /* 0.7.3 */
8453 .domainIsPersistent = remoteDomainIsPersistent, /* 0.7.3 */
8454 .domainIsUpdated = remoteDomainIsUpdated, /* 0.8.6 */
8455 .connectCompareCPU = remoteConnectCompareCPU, /* 0.7.5 */
8456 .connectBaselineCPU = remoteConnectBaselineCPU, /* 0.7.7 */
8457 .domainGetJobInfo = remoteDomainGetJobInfo, /* 0.7.7 */
8458 .domainGetJobStats = remoteDomainGetJobStats, /* 1.0.3 */
8459 .domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */
8460 .domainMigrateGetMaxDowntime = remoteDomainMigrateGetMaxDowntime, /* 3.7.0 */
8461 .domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */
8462 .domainMigrateGetCompressionCache = remoteDomainMigrateGetCompressionCache, /* 1.0.3 */
8463 .domainMigrateSetCompressionCache = remoteDomainMigrateSetCompressionCache, /* 1.0.3 */
8464 .domainMigrateSetMaxSpeed = remoteDomainMigrateSetMaxSpeed, /* 0.9.0 */
8465 .domainMigrateGetMaxSpeed = remoteDomainMigrateGetMaxSpeed, /* 0.9.5 */
8466 .connectDomainEventRegisterAny = remoteConnectDomainEventRegisterAny, /* 0.8.0 */
8467 .connectDomainEventDeregisterAny = remoteConnectDomainEventDeregisterAny, /* 0.8.0 */
8468 .domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */
8469 .domainHasManagedSaveImage = remoteDomainHasManagedSaveImage, /* 0.8.0 */
8470 .domainManagedSaveRemove = remoteDomainManagedSaveRemove, /* 0.8.0 */
8471 .domainManagedSaveGetXMLDesc = remoteDomainManagedSaveGetXMLDesc, /* 3.7.0 */
8472 .domainManagedSaveDefineXML = remoteDomainManagedSaveDefineXML, /* 3.7.0 */
8473 .domainSnapshotCreateXML = remoteDomainSnapshotCreateXML, /* 0.8.0 */
8474 .domainSnapshotGetXMLDesc = remoteDomainSnapshotGetXMLDesc, /* 0.8.0 */
8475 .domainSnapshotNum = remoteDomainSnapshotNum, /* 0.8.0 */
8476 .domainSnapshotListNames = remoteDomainSnapshotListNames, /* 0.8.0 */
8477 .domainListAllSnapshots = remoteDomainListAllSnapshots, /* 0.9.13 */
8478 .domainSnapshotNumChildren = remoteDomainSnapshotNumChildren, /* 0.9.7 */
8479 .domainSnapshotListAllChildren = remoteDomainSnapshotListAllChildren, /* 0.9.13 */
8480 .domainSnapshotListChildrenNames = remoteDomainSnapshotListChildrenNames, /* 0.9.7 */
8481 .domainSnapshotLookupByName = remoteDomainSnapshotLookupByName, /* 0.8.0 */
8482 .domainHasCurrentSnapshot = remoteDomainHasCurrentSnapshot, /* 0.8.0 */
8483 .domainSnapshotGetParent = remoteDomainSnapshotGetParent, /* 0.9.7 */
8484 .domainSnapshotCurrent = remoteDomainSnapshotCurrent, /* 0.8.0 */
8485 .domainRevertToSnapshot = remoteDomainRevertToSnapshot, /* 0.8.0 */
8486 .domainSnapshotIsCurrent = remoteDomainSnapshotIsCurrent, /* 0.9.13 */
8487 .domainSnapshotHasMetadata = remoteDomainSnapshotHasMetadata, /* 0.9.13 */
8488 .domainSnapshotDelete = remoteDomainSnapshotDelete, /* 0.8.0 */
8489 .domainQemuMonitorCommand = remoteDomainQemuMonitorCommand, /* 0.8.3 */
8490 .domainQemuAttach = remoteDomainQemuAttach, /* 0.9.4 */
8491 .domainQemuAgentCommand = remoteDomainQemuAgentCommand, /* 0.10.0 */
8492 .connectDomainQemuMonitorEventRegister = remoteConnectDomainQemuMonitorEventRegister, /* 1.2.3 */
8493 .connectDomainQemuMonitorEventDeregister = remoteConnectDomainQemuMonitorEventDeregister, /* 1.2.3 */
8494 .domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */
8495 .domainOpenChannel = remoteDomainOpenChannel, /* 1.0.2 */
8496 .domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */
8497 .domainOpenGraphicsFD = remoteDomainOpenGraphicsFD, /* 1.2.8 */
8498 .domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */
8499 .domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */
8500 .domainMigratePrepare3 = remoteDomainMigratePrepare3, /* 0.9.2 */
8501 .domainMigratePrepareTunnel3 = remoteDomainMigratePrepareTunnel3, /* 0.9.2 */
8502 .domainMigratePerform3 = remoteDomainMigratePerform3, /* 0.9.2 */
8503 .domainMigrateFinish3 = remoteDomainMigrateFinish3, /* 0.9.2 */
8504 .domainMigrateConfirm3 = remoteDomainMigrateConfirm3, /* 0.9.2 */
8505 .domainSendKey = remoteDomainSendKey, /* 0.9.3 */
8506 .domainSendProcessSignal = remoteDomainSendProcessSignal, /* 1.0.1 */
8507 .domainBlockJobAbort = remoteDomainBlockJobAbort, /* 0.9.4 */
8508 .domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */
8509 .domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
8510 .domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
8511 .domainBlockRebase = remoteDomainBlockRebase, /* 0.9.10 */
8512 .domainBlockCopy = remoteDomainBlockCopy, /* 1.2.9 */
8513 .domainBlockCommit = remoteDomainBlockCommit, /* 0.10.2 */
8514 .connectSetKeepAlive = remoteConnectSetKeepAlive, /* 0.9.8 */
8515 .connectIsAlive = remoteConnectIsAlive, /* 0.9.8 */
8516 .nodeSuspendForDuration = remoteNodeSuspendForDuration, /* 0.9.8 */
8517 .domainSetBlockIoTune = remoteDomainSetBlockIoTune, /* 0.9.8 */
8518 .domainGetBlockIoTune = remoteDomainGetBlockIoTune, /* 0.9.8 */
8519 .domainSetNumaParameters = remoteDomainSetNumaParameters, /* 0.9.9 */
8520 .domainGetNumaParameters = remoteDomainGetNumaParameters, /* 0.9.9 */
8521 .domainGetCPUStats = remoteDomainGetCPUStats, /* 0.9.10 */
8522 .domainGetDiskErrors = remoteDomainGetDiskErrors, /* 0.9.10 */
8523 .domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */
8524 .domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */
8525 .domainGetHostname = remoteDomainGetHostname, /* 0.10.0 */
8526 .nodeSetMemoryParameters = remoteNodeSetMemoryParameters, /* 0.10.2 */
8527 .nodeGetMemoryParameters = remoteNodeGetMemoryParameters, /* 0.10.2 */
8528 .nodeGetCPUMap = remoteNodeGetCPUMap, /* 1.0.0 */
8529 .domainFSTrim = remoteDomainFSTrim, /* 1.0.1 */
8530 .domainLxcOpenNamespace = remoteDomainLxcOpenNamespace, /* 1.0.2 */
8531 .domainMigrateBegin3Params = remoteDomainMigrateBegin3Params, /* 1.1.0 */
8532 .domainMigratePrepare3Params = remoteDomainMigratePrepare3Params, /* 1.1.0 */
8533 .domainMigratePrepareTunnel3Params = remoteDomainMigratePrepareTunnel3Params, /* 1.1.0 */
8534 .domainMigratePerform3Params = remoteDomainMigratePerform3Params, /* 1.1.0 */
8535 .domainMigrateFinish3Params = remoteDomainMigrateFinish3Params, /* 1.1.0 */
8536 .domainMigrateConfirm3Params = remoteDomainMigrateConfirm3Params, /* 1.1.0 */
8537 .connectGetCPUModelNames = remoteConnectGetCPUModelNames, /* 1.1.3 */
8538 .domainFSFreeze = remoteDomainFSFreeze, /* 1.2.5 */
8539 .domainFSThaw = remoteDomainFSThaw, /* 1.2.5 */
8540 .domainGetTime = remoteDomainGetTime, /* 1.2.5 */
8541 .domainSetTime = remoteDomainSetTime, /* 1.2.5 */
8542 .nodeGetFreePages = remoteNodeGetFreePages, /* 1.2.6 */
8543 .connectGetDomainCapabilities = remoteConnectGetDomainCapabilities, /* 1.2.7 */
8544 .connectGetAllDomainStats = remoteConnectGetAllDomainStats, /* 1.2.8 */
8545 .nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */
8546 .domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */
8547 .domainInterfaceAddresses = remoteDomainInterfaceAddresses, /* 1.2.14 */
8548 .domainSetUserPassword = remoteDomainSetUserPassword, /* 1.2.16 */
8549 .domainRename = remoteDomainRename, /* 1.2.19 */
8550 .connectRegisterCloseCallback = remoteConnectRegisterCloseCallback, /* 1.3.2 */
8551 .connectUnregisterCloseCallback = remoteConnectUnregisterCloseCallback, /* 1.3.2 */
8552 .domainMigrateStartPostCopy = remoteDomainMigrateStartPostCopy, /* 1.3.3 */
8553 .domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */
8554 .domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */
8555 .domainSetVcpu = remoteDomainSetVcpu, /* 3.1.0 */
8556 .domainSetBlockThreshold = remoteDomainSetBlockThreshold, /* 3.2.0 */
8557 .domainSetLifecycleAction = remoteDomainSetLifecycleAction, /* 3.9.0 */
8558 .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */
8559 .connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */
8560 .nodeGetSEVInfo = remoteNodeGetSEVInfo, /* 4.5.0 */
8561 .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo, /* 4.5.0 */
8562 .domainCheckpointCreateXML = remoteDomainCheckpointCreateXML, /* 5.6.0 */
8563 .domainCheckpointGetXMLDesc = remoteDomainCheckpointGetXMLDesc, /* 5.6.0 */
8564 .domainListAllCheckpoints = remoteDomainListAllCheckpoints, /* 5.6.0 */
8565 .domainCheckpointListAllChildren = remoteDomainCheckpointListAllChildren, /* 5.6.0 */
8566 .domainCheckpointLookupByName = remoteDomainCheckpointLookupByName, /* 5.6.0 */
8567 .domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.6.0 */
8568 .domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.6.0 */
8569 .domainGetGuestInfo = remoteDomainGetGuestInfo, /* 5.7.0 */
8570 .domainAgentSetResponseTimeout = remoteDomainAgentSetResponseTimeout, /* 5.10.0 */
8571 .domainBackupBegin = remoteDomainBackupBegin, /* 6.0.0 */
8572 .domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */
8573 .domainAuthorizedSSHKeysGet = remoteDomainAuthorizedSSHKeysGet, /* 6.10.0 */
8574 .domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */
8575 .domainGetMessages = remoteDomainGetMessages, /* 7.1.0 */
8576 .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 7.2.0 */
8577 };
8578
8579 static virNetworkDriver network_driver = {
8580 .connectNumOfNetworks = remoteConnectNumOfNetworks, /* 0.3.0 */
8581 .connectListNetworks = remoteConnectListNetworks, /* 0.3.0 */
8582 .connectNumOfDefinedNetworks = remoteConnectNumOfDefinedNetworks, /* 0.3.0 */
8583 .connectListDefinedNetworks = remoteConnectListDefinedNetworks, /* 0.3.0 */
8584 .connectListAllNetworks = remoteConnectListAllNetworks, /* 0.10.2 */
8585 .connectNetworkEventDeregisterAny = remoteConnectNetworkEventDeregisterAny, /* 1.2.1 */
8586 .connectNetworkEventRegisterAny = remoteConnectNetworkEventRegisterAny, /* 1.2.1 */
8587 .networkLookupByUUID = remoteNetworkLookupByUUID, /* 0.3.0 */
8588 .networkLookupByName = remoteNetworkLookupByName, /* 0.3.0 */
8589 .networkCreateXML = remoteNetworkCreateXML, /* 0.3.0 */
8590 .networkCreateXMLFlags = remoteNetworkCreateXMLFlags, /* 7.8.0 */
8591 .networkDefineXML = remoteNetworkDefineXML, /* 0.3.0 */
8592 .networkDefineXMLFlags = remoteNetworkDefineXMLFlags, /* 7.7.0 */
8593 .networkUndefine = remoteNetworkUndefine, /* 0.3.0 */
8594 .networkUpdate = remoteNetworkUpdate, /* 0.10.2 */
8595 .networkCreate = remoteNetworkCreate, /* 0.3.0 */
8596 .networkDestroy = remoteNetworkDestroy, /* 0.3.0 */
8597 .networkGetXMLDesc = remoteNetworkGetXMLDesc, /* 0.3.0 */
8598 .networkGetBridgeName = remoteNetworkGetBridgeName, /* 0.3.0 */
8599 .networkGetAutostart = remoteNetworkGetAutostart, /* 0.3.0 */
8600 .networkSetAutostart = remoteNetworkSetAutostart, /* 0.3.0 */
8601 .networkIsActive = remoteNetworkIsActive, /* 0.7.3 */
8602 .networkIsPersistent = remoteNetworkIsPersistent, /* 0.7.3 */
8603 .networkGetDHCPLeases = remoteNetworkGetDHCPLeases, /* 1.2.6 */
8604 .networkListAllPorts = remoteNetworkListAllPorts, /* 5.5.0 */
8605 .networkPortLookupByUUID = remoteNetworkPortLookupByUUID, /* 5.5.0 */
8606 .networkPortCreateXML = remoteNetworkPortCreateXML, /* 5.5.0 */
8607 .networkPortGetXMLDesc = remoteNetworkPortGetXMLDesc, /* 5.5.0 */
8608 .networkPortSetParameters = remoteNetworkPortSetParameters, /* 5.5.0 */
8609 .networkPortGetParameters = remoteNetworkPortGetParameters, /* 5.5.0 */
8610 .networkPortDelete = remoteNetworkPortDelete, /* 5.5.0 */
8611 };
8612
8613 static virInterfaceDriver interface_driver = {
8614 .connectNumOfInterfaces = remoteConnectNumOfInterfaces, /* 0.7.2 */
8615 .connectListInterfaces = remoteConnectListInterfaces, /* 0.7.2 */
8616 .connectNumOfDefinedInterfaces = remoteConnectNumOfDefinedInterfaces, /* 0.7.2 */
8617 .connectListDefinedInterfaces = remoteConnectListDefinedInterfaces, /* 0.7.2 */
8618 .connectListAllInterfaces = remoteConnectListAllInterfaces, /* 0.10.2 */
8619 .interfaceLookupByName = remoteInterfaceLookupByName, /* 0.7.2 */
8620 .interfaceLookupByMACString = remoteInterfaceLookupByMACString, /* 0.7.2 */
8621 .interfaceGetXMLDesc = remoteInterfaceGetXMLDesc, /* 0.7.2 */
8622 .interfaceDefineXML = remoteInterfaceDefineXML, /* 0.7.2 */
8623 .interfaceUndefine = remoteInterfaceUndefine, /* 0.7.2 */
8624 .interfaceCreate = remoteInterfaceCreate, /* 0.7.2 */
8625 .interfaceDestroy = remoteInterfaceDestroy, /* 0.7.2 */
8626 .interfaceIsActive = remoteInterfaceIsActive, /* 0.7.3 */
8627 .interfaceChangeBegin = remoteInterfaceChangeBegin, /* 0.9.2 */
8628 .interfaceChangeCommit = remoteInterfaceChangeCommit, /* 0.9.2 */
8629 .interfaceChangeRollback = remoteInterfaceChangeRollback, /* 0.9.2 */
8630 };
8631
8632 static virStorageDriver storage_driver = {
8633 .connectNumOfStoragePools = remoteConnectNumOfStoragePools, /* 0.4.1 */
8634 .connectListStoragePools = remoteConnectListStoragePools, /* 0.4.1 */
8635 .connectNumOfDefinedStoragePools = remoteConnectNumOfDefinedStoragePools, /* 0.4.1 */
8636 .connectListDefinedStoragePools = remoteConnectListDefinedStoragePools, /* 0.4.1 */
8637 .connectListAllStoragePools = remoteConnectListAllStoragePools, /* 0.10.2 */
8638 .connectFindStoragePoolSources = remoteConnectFindStoragePoolSources, /* 0.4.5 */
8639 .connectStoragePoolEventDeregisterAny = remoteConnectStoragePoolEventDeregisterAny, /* 2.0.0 */
8640 .connectStoragePoolEventRegisterAny = remoteConnectStoragePoolEventRegisterAny, /* 2.0.0 */
8641 .connectGetStoragePoolCapabilities = remoteConnectGetStoragePoolCapabilities, /* 5.2.0 */
8642 .storagePoolLookupByName = remoteStoragePoolLookupByName, /* 0.4.1 */
8643 .storagePoolLookupByUUID = remoteStoragePoolLookupByUUID, /* 0.4.1 */
8644 .storagePoolLookupByVolume = remoteStoragePoolLookupByVolume, /* 0.4.1 */
8645 .storagePoolLookupByTargetPath = remoteStoragePoolLookupByTargetPath, /* 4.1.0 */
8646 .storagePoolCreateXML = remoteStoragePoolCreateXML, /* 0.4.1 */
8647 .storagePoolDefineXML = remoteStoragePoolDefineXML, /* 0.4.1 */
8648 .storagePoolBuild = remoteStoragePoolBuild, /* 0.4.1 */
8649 .storagePoolUndefine = remoteStoragePoolUndefine, /* 0.4.1 */
8650 .storagePoolCreate = remoteStoragePoolCreate, /* 0.4.1 */
8651 .storagePoolDestroy = remoteStoragePoolDestroy, /* 0.4.1 */
8652 .storagePoolDelete = remoteStoragePoolDelete, /* 0.4.1 */
8653 .storagePoolRefresh = remoteStoragePoolRefresh, /* 0.4.1 */
8654 .storagePoolGetInfo = remoteStoragePoolGetInfo, /* 0.4.1 */
8655 .storagePoolGetXMLDesc = remoteStoragePoolGetXMLDesc, /* 0.4.1 */
8656 .storagePoolGetAutostart = remoteStoragePoolGetAutostart, /* 0.4.1 */
8657 .storagePoolSetAutostart = remoteStoragePoolSetAutostart, /* 0.4.1 */
8658 .storagePoolNumOfVolumes = remoteStoragePoolNumOfVolumes, /* 0.4.1 */
8659 .storagePoolListVolumes = remoteStoragePoolListVolumes, /* 0.4.1 */
8660 .storagePoolListAllVolumes = remoteStoragePoolListAllVolumes, /* 0.10.0 */
8661
8662 .storageVolLookupByName = remoteStorageVolLookupByName, /* 0.4.1 */
8663 .storageVolLookupByKey = remoteStorageVolLookupByKey, /* 0.4.1 */
8664 .storageVolLookupByPath = remoteStorageVolLookupByPath, /* 0.4.1 */
8665 .storageVolCreateXML = remoteStorageVolCreateXML, /* 0.4.1 */
8666 .storageVolCreateXMLFrom = remoteStorageVolCreateXMLFrom, /* 0.6.4 */
8667 .storageVolDownload = remoteStorageVolDownload, /* 0.9.0 */
8668 .storageVolUpload = remoteStorageVolUpload, /* 0.9.0 */
8669 .storageVolDelete = remoteStorageVolDelete, /* 0.4.1 */
8670 .storageVolWipe = remoteStorageVolWipe, /* 0.8.0 */
8671 .storageVolWipePattern = remoteStorageVolWipePattern, /* 0.9.10 */
8672 .storageVolGetInfo = remoteStorageVolGetInfo, /* 0.4.1 */
8673 .storageVolGetInfoFlags = remoteStorageVolGetInfoFlags, /* 3.0.0 */
8674 .storageVolGetXMLDesc = remoteStorageVolGetXMLDesc, /* 0.4.1 */
8675 .storageVolGetPath = remoteStorageVolGetPath, /* 0.4.1 */
8676 .storageVolResize = remoteStorageVolResize, /* 0.9.10 */
8677 .storagePoolIsActive = remoteStoragePoolIsActive, /* 0.7.3 */
8678 .storagePoolIsPersistent = remoteStoragePoolIsPersistent, /* 0.7.3 */
8679 };
8680
8681 static virSecretDriver secret_driver = {
8682 .connectNumOfSecrets = remoteConnectNumOfSecrets, /* 0.7.1 */
8683 .connectListSecrets = remoteConnectListSecrets, /* 0.7.1 */
8684 .connectListAllSecrets = remoteConnectListAllSecrets, /* 0.10.2 */
8685 .secretLookupByUUID = remoteSecretLookupByUUID, /* 0.7.1 */
8686 .secretLookupByUsage = remoteSecretLookupByUsage, /* 0.7.1 */
8687 .secretDefineXML = remoteSecretDefineXML, /* 0.7.1 */
8688 .secretGetXMLDesc = remoteSecretGetXMLDesc, /* 0.7.1 */
8689 .secretSetValue = remoteSecretSetValue, /* 0.7.1 */
8690 .secretGetValue = remoteSecretGetValue, /* 0.7.1 */
8691 .secretUndefine = remoteSecretUndefine, /* 0.7.1 */
8692 .connectSecretEventDeregisterAny = remoteConnectSecretEventDeregisterAny, /* 3.0.0 */
8693 .connectSecretEventRegisterAny = remoteConnectSecretEventRegisterAny, /* 3.0.0 */
8694 };
8695
8696 static virNodeDeviceDriver node_device_driver = {
8697 .connectNodeDeviceEventDeregisterAny = remoteConnectNodeDeviceEventDeregisterAny, /* 2.2.0 */
8698 .connectNodeDeviceEventRegisterAny = remoteConnectNodeDeviceEventRegisterAny, /* 2.2.0 */
8699 .nodeNumOfDevices = remoteNodeNumOfDevices, /* 0.5.0 */
8700 .nodeListDevices = remoteNodeListDevices, /* 0.5.0 */
8701 .connectListAllNodeDevices = remoteConnectListAllNodeDevices, /* 0.10.2 */
8702 .nodeDeviceLookupByName = remoteNodeDeviceLookupByName, /* 0.5.0 */
8703 .nodeDeviceLookupSCSIHostByWWN = remoteNodeDeviceLookupSCSIHostByWWN, /* 1.0.2 */
8704 .nodeDeviceGetXMLDesc = remoteNodeDeviceGetXMLDesc, /* 0.5.0 */
8705 .nodeDeviceGetParent = remoteNodeDeviceGetParent, /* 0.5.0 */
8706 .nodeDeviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
8707 .nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
8708 .nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
8709 .nodeDeviceCreate = remoteNodeDeviceCreate, /* 7.3.0 */
8710 .nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 7.3.0 */
8711 .nodeDeviceUndefine = remoteNodeDeviceUndefine, /* 7.3.0 */
8712 .nodeDeviceDestroy = remoteNodeDeviceDestroy, /* 0.6.3 */
8713 .nodeDeviceGetAutostart = remoteNodeDeviceGetAutostart, /* 7.8.0 */
8714 .nodeDeviceSetAutostart = remoteNodeDeviceSetAutostart, /* 7.8.0 */
8715 .nodeDeviceIsPersistent = remoteNodeDeviceIsPersistent, /* 7.8.0 */
8716 .nodeDeviceIsActive = remoteNodeDeviceIsActive, /* 7.8.0 */
8717 };
8718
8719 static virNWFilterDriver nwfilter_driver = {
8720 .nwfilterLookupByUUID = remoteNWFilterLookupByUUID, /* 0.8.0 */
8721 .nwfilterLookupByName = remoteNWFilterLookupByName, /* 0.8.0 */
8722 .nwfilterGetXMLDesc = remoteNWFilterGetXMLDesc, /* 0.8.0 */
8723 .nwfilterDefineXML = remoteNWFilterDefineXML, /* 0.8.0 */
8724 .nwfilterDefineXMLFlags = remoteNWFilterDefineXMLFlags, /* 7.7.0 */
8725 .nwfilterUndefine = remoteNWFilterUndefine, /* 0.8.0 */
8726 .connectNumOfNWFilters = remoteConnectNumOfNWFilters, /* 0.8.0 */
8727 .connectListNWFilters = remoteConnectListNWFilters, /* 0.8.0 */
8728 .connectListAllNWFilters = remoteConnectListAllNWFilters, /* 0.10.2 */
8729 .connectListAllNWFilterBindings = remoteConnectListAllNWFilterBindings, /* 4.5.0 */
8730 .nwfilterBindingLookupByPortDev = remoteNWFilterBindingLookupByPortDev, /* 4.5.0 */
8731 .nwfilterBindingCreateXML = remoteNWFilterBindingCreateXML, /* 4.5.0 */
8732 .nwfilterBindingDelete = remoteNWFilterBindingDelete, /* 4.5.0 */
8733 .nwfilterBindingGetXMLDesc = remoteNWFilterBindingGetXMLDesc, /* 4.5.0 */
8734 };
8735
8736 static virConnectDriver connect_driver = {
8737 .hypervisorDriver = &hypervisor_driver,
8738 .interfaceDriver = &interface_driver,
8739 .networkDriver = &network_driver,
8740 .nodeDeviceDriver = &node_device_driver,
8741 .nwfilterDriver = &nwfilter_driver,
8742 .secretDriver = &secret_driver,
8743 .storageDriver = &storage_driver,
8744 };
8745
8746 static virStateDriver state_driver = {
8747 .name = "Remote",
8748 .stateInitialize = remoteStateInitialize,
8749 };
8750
8751
8752 /** remoteRegister:
8753 *
8754 * Register driver with libvirt driver system.
8755 *
8756 * Returns -1 on error.
8757 */
8758 int
remoteRegister(void)8759 remoteRegister(void)
8760 {
8761 if (virRegisterConnectDriver(&connect_driver,
8762 false) < 0)
8763 return -1;
8764 if (virRegisterStateDriver(&state_driver) < 0)
8765 return -1;
8766
8767 return 0;
8768 }
8769