remote.c 173.5 KB
Newer Older
1
/*
2
 * remote.c: handlers for RPC method calls
3
 *
4
 * Copyright (C) 2007, 2008, 2009 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * Author: Richard W.M. Jones <rjones@redhat.com>
 */

#include <config.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/poll.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <pwd.h>
#include <stdio.h>
#include <stdarg.h>
#include <syslog.h>
#include <string.h>
#include <errno.h>
43
#include <fnmatch.h>
44
#include "virterror_internal.h"
45

46
#if HAVE_POLKIT0
47 48 49 50
#include <polkit/polkit.h>
#include <polkit-dbus/polkit-dbus.h>
#endif

51 52 53
#include "remote.h"
#include "dispatch.h"

54 55
#include "libvirt_internal.h"
#include "datatypes.h"
56
#include "memory.h"
57
#include "util.h"
C
Chris Lalancette 已提交
58
#include "stream.h"
59

60
#define VIR_FROM_THIS VIR_FROM_REMOTE
61
#define REMOTE_DEBUG(fmt, ...) DEBUG(fmt, __VA_ARGS__)
62

63 64
static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain);
static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network network);
65
static virInterfacePtr get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface iface);
66 67
static virStoragePoolPtr get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool);
static virStorageVolPtr get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol);
68
static virSecretPtr get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret);
69 70
static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src);
D
Daniel Veillard 已提交
71
static void make_nonnull_interface (remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
72 73
static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src);
static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
74
static void make_nonnull_node_device (remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src);
75
static void make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
76

77

78
#include "remote_dispatch_prototypes.h"
79 80 81 82

static const dispatch_data const dispatch_table[] = {
#include "remote_dispatch_table.h"
};
83

84 85 86 87 88 89 90 91 92 93
const dispatch_data const *remoteGetDispatchData(int proc)
{
    if (proc >= ARRAY_CARDINALITY(dispatch_table) ||
        dispatch_table[proc].fn == NULL) {
        return NULL;
    }

    return &(dispatch_table[proc]);
}

94 95 96
/* Prototypes */
static void
remoteDispatchDomainEventSend (struct qemud_client *client,
97
                               remote_domain_event_msg *data);
98

99
int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED,
100 101 102 103
                            virDomainPtr dom,
                            int event,
                            int detail,
                            void *opaque)
104 105
{
    struct qemud_client *client = opaque;
106
    REMOTE_DEBUG("Relaying domain event %d %d", event, detail);
107

108
    if (client) {
109 110
        remote_domain_event_msg data;

111 112
        virMutexLock(&client->lock);

113 114 115 116 117
        /* build return data */
        memset(&data, 0, sizeof data);
        make_nonnull_domain (&data.dom, dom);
        data.event = event;
        data.detail = detail;
118

119
        remoteDispatchDomainEventSend (client, &data);
120 121

        virMutexUnlock(&client->lock);
122 123 124
    }
    return 0;
}
125 126


127 128 129
/*----- Functions. -----*/

static int
130
remoteDispatchOpen (struct qemud_server *server,
131
                    struct qemud_client *client,
132
                    virConnectPtr conn,
133
                    remote_message_header *hdr ATTRIBUTE_UNUSED,
134
                    remote_error *rerr,
135 136 137
                    struct remote_open_args *args, void *ret ATTRIBUTE_UNUSED)
{
    const char *name;
138
    int flags, rc;
139 140

    /* Already opened? */
141
    if (conn) {
142 143
        remoteDispatchFormatError (rerr, "%s", _("connection already open"));
        return -1;
144 145
    }

146 147 148
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
149

150 151 152 153 154 155 156 157 158 159 160 161 162
    name = args->name ? *args->name : NULL;

    /* If this connection arrived on a readonly socket, force
     * the connection to be readonly.
     */
    flags = args->flags;
    if (client->readonly) flags |= VIR_CONNECT_RO;

    client->conn =
        flags & VIR_CONNECT_RO
        ? virConnectOpenReadOnly (name)
        : virConnectOpen (name);

163
    if (client->conn == NULL)
164 165
        remoteDispatchConnError(rerr, NULL);

166
    rc = client->conn ? 0 : -1;
167
    virMutexUnlock(&client->lock);
168
    return rc;
169 170
}

171 172 173 174
#define CHECK_CONN(client)                                              \
    if (!client->conn) {                                                \
        remoteDispatchFormatError (rerr, "%s", _("connection not open")); \
        return -1;                                                      \
175 176 177
    }

static int
178
remoteDispatchClose (struct qemud_server *server ATTRIBUTE_UNUSED,
179 180
                     struct qemud_client *client ATTRIBUTE_UNUSED,
                     virConnectPtr conn ATTRIBUTE_UNUSED,
181
                     remote_message_header *hdr ATTRIBUTE_UNUSED,
182
                     remote_error *rerr ATTRIBUTE_UNUSED,
183 184
                     void *args ATTRIBUTE_UNUSED, void *ret ATTRIBUTE_UNUSED)
{
185 186 187
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
188

189
    client->closing = 1;
190

191
    virMutexUnlock(&client->lock);
192
    return 0;
193 194
}

195
static int
196
remoteDispatchSupportsFeature (struct qemud_server *server ATTRIBUTE_UNUSED,
197 198
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
199
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
200
                               remote_error *rerr,
201 202
                               remote_supports_feature_args *args, remote_supports_feature_ret *ret)
{
203
    ret->supported = virDrvSupportsFeature (conn, args->feature);
204 205

    if (ret->supported == -1) {
206
        remoteDispatchConnError(rerr, conn);
207 208
        return -1;
    }
209 210 211 212

    return 0;
}

213
static int
214
remoteDispatchGetType (struct qemud_server *server ATTRIBUTE_UNUSED,
215 216
                       struct qemud_client *client ATTRIBUTE_UNUSED,
                       virConnectPtr conn,
217
                       remote_message_header *hdr ATTRIBUTE_UNUSED,
218
                       remote_error *rerr,
219 220 221 222
                       void *args ATTRIBUTE_UNUSED, remote_get_type_ret *ret)
{
    const char *type;

223
    type = virConnectGetType (conn);
224
    if (type == NULL) {
225
        remoteDispatchConnError(rerr, conn);
226 227
        return -1;
    }
228 229 230 231 232 233

    /* We have to strdup because remoteDispatchClientRequest will
     * free this string after it's been serialised.
     */
    ret->type = strdup (type);
    if (!ret->type) {
234 235
        remoteDispatchFormatError (rerr, "%s", _("out of memory in strdup"));
        return -1;
236 237 238 239 240 241
    }

    return 0;
}

static int
242
remoteDispatchGetVersion (struct qemud_server *server ATTRIBUTE_UNUSED,
243 244
                          struct qemud_client *client ATTRIBUTE_UNUSED,
                          virConnectPtr conn,
245
                          remote_message_header *hdr ATTRIBUTE_UNUSED,
246
                          remote_error *rerr,
247 248 249 250 251
                          void *args ATTRIBUTE_UNUSED,
                          remote_get_version_ret *ret)
{
    unsigned long hvVer;

252 253
    if (virConnectGetVersion (conn, &hvVer) == -1) {
        remoteDispatchConnError(rerr, conn);
254
        return -1;
255
    }
256 257 258 259 260

    ret->hv_ver = hvVer;
    return 0;
}

261
static int
262
remoteDispatchGetHostname (struct qemud_server *server ATTRIBUTE_UNUSED,
263 264
                           struct qemud_client *client ATTRIBUTE_UNUSED,
                           virConnectPtr conn,
265
                           remote_message_header *hdr ATTRIBUTE_UNUSED,
266
                           remote_error *rerr,
267 268 269 270 271
                           void *args ATTRIBUTE_UNUSED,
                           remote_get_hostname_ret *ret)
{
    char *hostname;

272
    hostname = virConnectGetHostname (conn);
273
    if (hostname == NULL) {
274
        remoteDispatchConnError(rerr, conn);
275 276
        return -1;
    }
277 278 279 280 281

    ret->hostname = hostname;
    return 0;
}

282 283
static int
remoteDispatchGetUri (struct qemud_server *server ATTRIBUTE_UNUSED,
284 285
                      struct qemud_client *client ATTRIBUTE_UNUSED,
                      virConnectPtr conn,
286
                      remote_message_header *hdr ATTRIBUTE_UNUSED,
287
                      remote_error *rerr,
288 289 290 291 292 293
                      void *args ATTRIBUTE_UNUSED,
                      remote_get_uri_ret *ret)
{
    char *uri;
    CHECK_CONN(client);

294
    uri = virConnectGetURI (conn);
295
    if (uri == NULL) {
296
        remoteDispatchConnError(rerr, conn);
297 298
        return -1;
    }
299 300 301 302 303

    ret->uri = uri;
    return 0;
}

304
static int
305
remoteDispatchGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
306 307
                           struct qemud_client *client ATTRIBUTE_UNUSED,
                           virConnectPtr conn,
308
                           remote_message_header *hdr ATTRIBUTE_UNUSED,
309
                           remote_error *rerr,
310 311 312 313 314 315
                           remote_get_max_vcpus_args *args,
                           remote_get_max_vcpus_ret *ret)
{
    char *type;

    type = args->type ? *args->type : NULL;
316
    ret->max_vcpus = virConnectGetMaxVcpus (conn, type);
317
    if (ret->max_vcpus == -1) {
318
        remoteDispatchConnError(rerr, conn);
319 320
        return -1;
    }
321 322 323 324 325

    return 0;
}

static int
326
remoteDispatchNodeGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
327 328
                           struct qemud_client *client ATTRIBUTE_UNUSED,
                           virConnectPtr conn,
329
                           remote_message_header *hdr ATTRIBUTE_UNUSED,
330
                           remote_error *rerr,
331 332 333 334 335
                           void *args ATTRIBUTE_UNUSED,
                           remote_node_get_info_ret *ret)
{
    virNodeInfo info;

336 337
    if (virNodeGetInfo (conn, &info) == -1) {
        remoteDispatchConnError(rerr, conn);
338
        return -1;
339
    }
340 341 342 343 344 345 346 347 348 349 350 351 352 353

    memcpy (ret->model, info.model, sizeof ret->model);
    ret->memory = info.memory;
    ret->cpus = info.cpus;
    ret->mhz = info.mhz;
    ret->nodes = info.nodes;
    ret->sockets = info.sockets;
    ret->cores = info.cores;
    ret->threads = info.threads;

    return 0;
}

static int
354
remoteDispatchGetCapabilities (struct qemud_server *server ATTRIBUTE_UNUSED,
355 356
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
357
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
358
                               remote_error *rerr,
359 360 361 362 363
                               void *args ATTRIBUTE_UNUSED,
                               remote_get_capabilities_ret *ret)
{
    char *caps;

364
    caps = virConnectGetCapabilities (conn);
365
    if (caps == NULL) {
366
        remoteDispatchConnError(rerr, conn);
367 368
        return -1;
    }
369 370 371 372 373

    ret->capabilities = caps;
    return 0;
}

374 375
static int
remoteDispatchNodeGetCellsFreeMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
376 377
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
378
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
379
                                      remote_error *rerr,
380 381 382
                                      remote_node_get_cells_free_memory_args *args,
                                      remote_node_get_cells_free_memory_ret *ret)
{
D
Daniel P. Berrange 已提交
383
    int err;
384 385

    if (args->maxCells > REMOTE_NODE_MAX_CELLS) {
386 387 388
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxCells > REMOTE_NODE_MAX_CELLS"));
        return -1;
389 390 391
    }

    /* Allocate return buffer. */
392
    if (VIR_ALLOC_N(ret->freeMems.freeMems_val, args->maxCells) < 0) {
393 394
        remoteDispatchOOMError(rerr);
        return -1;
395
    }
396

D
Daniel P. Berrange 已提交
397 398 399 400 401
    err = virNodeGetCellsFreeMemory(conn,
                                    (unsigned long long *)ret->freeMems.freeMems_val,
                                    args->startCell,
                                    args->maxCells);
    if (err <= 0) {
402
        VIR_FREE(ret->freeMems.freeMems_val);
403
        remoteDispatchConnError(rerr, conn);
404
        return -1;
405
    }
D
Daniel P. Berrange 已提交
406
    ret->freeMems.freeMems_len = err;
407 408 409 410 411 412 413

    return 0;
}


static int
remoteDispatchNodeGetFreeMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
414 415
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
416
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
417
                                 remote_error *rerr,
418 419 420 421 422
                                 void *args ATTRIBUTE_UNUSED,
                                 remote_node_get_free_memory_ret *ret)
{
    unsigned long long freeMem;

423
    freeMem = virNodeGetFreeMemory(conn);
424
    if (freeMem == 0) {
425
        remoteDispatchConnError(rerr, conn);
426 427
        return -1;
    }
428 429 430 431 432
    ret->freeMem = freeMem;
    return 0;
}


433
static int
434
remoteDispatchDomainGetSchedulerType (struct qemud_server *server ATTRIBUTE_UNUSED,
435 436
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
437
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
438
                                      remote_error *rerr,
439 440 441 442 443 444 445
                                      remote_domain_get_scheduler_type_args *args,
                                      remote_domain_get_scheduler_type_ret *ret)
{
    virDomainPtr dom;
    char *type;
    int nparams;

446
    dom = get_nonnull_domain (conn, args->dom);
447
    if (dom == NULL) {
448
        remoteDispatchConnError(rerr, conn);
449
        return -1;
450 451 452
    }

    type = virDomainGetSchedulerType (dom, &nparams);
453 454
    if (type == NULL) {
        virDomainFree(dom);
455
        remoteDispatchConnError(rerr, conn);
456 457
        return -1;
    }
458 459 460

    ret->type = type;
    ret->nparams = nparams;
461
    virDomainFree(dom);
462 463 464 465
    return 0;
}

static int
466
remoteDispatchDomainGetSchedulerParameters (struct qemud_server *server ATTRIBUTE_UNUSED,
467 468
                                            struct qemud_client *client ATTRIBUTE_UNUSED,
                                            virConnectPtr conn,
469
                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
470
                                            remote_error *rerr,
471 472 473 474 475 476 477 478 479 480
                                            remote_domain_get_scheduler_parameters_args *args,
                                            remote_domain_get_scheduler_parameters_ret *ret)
{
    virDomainPtr dom;
    virSchedParameterPtr params;
    int i, r, nparams;

    nparams = args->nparams;

    if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
481 482
        remoteDispatchFormatError (rerr, "%s", _("nparams too large"));
        return -1;
483
    }
484
    if (VIR_ALLOC_N(params, nparams) < 0) {
485 486
        remoteDispatchOOMError(rerr);
        return -1;
487 488
    }

489
    dom = get_nonnull_domain (conn, args->dom);
490
    if (dom == NULL) {
491
        VIR_FREE(params);
492
        remoteDispatchConnError(rerr, conn);
493
        return -1;
494 495 496 497
    }

    r = virDomainGetSchedulerParameters (dom, params, &nparams);
    if (r == -1) {
498
        virDomainFree(dom);
499
        VIR_FREE(params);
500
        remoteDispatchConnError(rerr, conn);
501 502 503 504 505
        return -1;
    }

    /* Serialise the scheduler parameters. */
    ret->params.params_len = nparams;
506 507
    if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0)
        goto oom;
508 509 510 511

    for (i = 0; i < nparams; ++i) {
        // remoteDispatchClientRequest will free this:
        ret->params.params_val[i].field = strdup (params[i].field);
512 513 514
        if (ret->params.params_val[i].field == NULL)
            goto oom;

515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
        ret->params.params_val[i].value.type = params[i].type;
        switch (params[i].type) {
        case VIR_DOMAIN_SCHED_FIELD_INT:
            ret->params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break;
        case VIR_DOMAIN_SCHED_FIELD_UINT:
            ret->params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break;
        case VIR_DOMAIN_SCHED_FIELD_LLONG:
            ret->params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break;
        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
            ret->params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break;
        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
            ret->params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break;
        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
            ret->params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break;
        default:
530
            remoteDispatchFormatError (rerr, "%s", _("unknown type"));
531
            goto cleanup;
532 533
        }
    }
534
    virDomainFree(dom);
535
    VIR_FREE(params);
536 537

    return 0;
538 539

oom:
540
    remoteDispatchOOMError(rerr);
541 542 543 544 545
cleanup:
    virDomainFree(dom);
    for (i = 0 ; i < nparams ; i++)
        VIR_FREE(ret->params.params_val[i].field);
    VIR_FREE(params);
546
    return -1;
547 548 549
}

static int
550
remoteDispatchDomainSetSchedulerParameters (struct qemud_server *server ATTRIBUTE_UNUSED,
551 552
                                            struct qemud_client *client ATTRIBUTE_UNUSED,
                                            virConnectPtr conn,
553
                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
554
                                            remote_error *rerr,
555 556 557 558 559 560 561 562 563 564
                                            remote_domain_set_scheduler_parameters_args *args,
                                            void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;
    int i, r, nparams;
    virSchedParameterPtr params;

    nparams = args->params.params_len;

    if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
565 566
        remoteDispatchFormatError (rerr, "%s", _("nparams too large"));
        return -1;
567
    }
568
    if (VIR_ALLOC_N(params, nparams) < 0) {
569 570
        remoteDispatchOOMError(rerr);
        return -1;
571 572 573 574
    }

    /* Deserialise parameters. */
    for (i = 0; i < nparams; ++i) {
C
Chris Lalancette 已提交
575 576 577 578 579
        if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) == NULL) {
            remoteDispatchFormatError(rerr, _("Field %s too big for destination"),
                                      args->params.params_val[i].field);
            return -1;
        }
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
        params[i].type = args->params.params_val[i].value.type;
        switch (params[i].type) {
        case VIR_DOMAIN_SCHED_FIELD_INT:
            params[i].value.i = args->params.params_val[i].value.remote_sched_param_value_u.i; break;
        case VIR_DOMAIN_SCHED_FIELD_UINT:
            params[i].value.ui = args->params.params_val[i].value.remote_sched_param_value_u.ui; break;
        case VIR_DOMAIN_SCHED_FIELD_LLONG:
            params[i].value.l = args->params.params_val[i].value.remote_sched_param_value_u.l; break;
        case VIR_DOMAIN_SCHED_FIELD_ULLONG:
            params[i].value.ul = args->params.params_val[i].value.remote_sched_param_value_u.ul; break;
        case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
            params[i].value.d = args->params.params_val[i].value.remote_sched_param_value_u.d; break;
        case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
            params[i].value.b = args->params.params_val[i].value.remote_sched_param_value_u.b; break;
        }
    }

597
    dom = get_nonnull_domain (conn, args->dom);
598
    if (dom == NULL) {
599
        VIR_FREE(params);
600
        remoteDispatchConnError(rerr, conn);
601
        return -1;
602 603 604
    }

    r = virDomainSetSchedulerParameters (dom, params, nparams);
605
    virDomainFree(dom);
606
    VIR_FREE(params);
607
    if (r == -1) {
608
        remoteDispatchConnError(rerr, conn);
609 610
        return -1;
    }
611 612 613 614

    return 0;
}

615
static int
616
remoteDispatchDomainBlockStats (struct qemud_server *server ATTRIBUTE_UNUSED,
617 618
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
619
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
620
                                remote_error *rerr,
621 622 623 624 625 626 627
                                remote_domain_block_stats_args *args,
                                remote_domain_block_stats_ret *ret)
{
    virDomainPtr dom;
    char *path;
    struct _virDomainBlockStats stats;

628
    dom = get_nonnull_domain (conn, args->dom);
629
    if (dom == NULL) {
630
        remoteDispatchConnError(rerr, conn);
631
        return -1;
632 633 634
    }
    path = args->path;

D
Daniel P. Berrange 已提交
635 636
    if (virDomainBlockStats (dom, path, &stats, sizeof stats) == -1) {
        virDomainFree (dom);
637
        remoteDispatchConnError(rerr, conn);
638
        return -1;
D
Daniel P. Berrange 已提交
639 640
    }
    virDomainFree (dom);
641 642 643 644 645 646 647 648 649 650 651

    ret->rd_req = stats.rd_req;
    ret->rd_bytes = stats.rd_bytes;
    ret->wr_req = stats.wr_req;
    ret->wr_bytes = stats.wr_bytes;
    ret->errs = stats.errs;

    return 0;
}

static int
652
remoteDispatchDomainInterfaceStats (struct qemud_server *server ATTRIBUTE_UNUSED,
653 654
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
655
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
656
                                    remote_error *rerr,
657 658 659 660 661 662 663
                                    remote_domain_interface_stats_args *args,
                                    remote_domain_interface_stats_ret *ret)
{
    virDomainPtr dom;
    char *path;
    struct _virDomainInterfaceStats stats;

664
    dom = get_nonnull_domain (conn, args->dom);
665
    if (dom == NULL) {
666
        remoteDispatchConnError(rerr, conn);
667
        return -1;
668 669 670
    }
    path = args->path;

D
Daniel P. Berrange 已提交
671 672
    if (virDomainInterfaceStats (dom, path, &stats, sizeof stats) == -1) {
        virDomainFree (dom);
673
        remoteDispatchConnError(rerr, conn);
674
        return -1;
D
Daniel P. Berrange 已提交
675 676
    }
    virDomainFree (dom);
677 678 679 680 681 682 683 684 685 686 687 688 689

    ret->rx_bytes = stats.rx_bytes;
    ret->rx_packets = stats.rx_packets;
    ret->rx_errs = stats.rx_errs;
    ret->rx_drop = stats.rx_drop;
    ret->tx_bytes = stats.tx_bytes;
    ret->tx_packets = stats.tx_packets;
    ret->tx_errs = stats.tx_errs;
    ret->tx_drop = stats.tx_drop;

    return 0;
}

690 691
static int
remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
692 693
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
694
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
695
                               remote_error *rerr,
696 697 698 699 700 701 702 703 704
                               remote_domain_block_peek_args *args,
                               remote_domain_block_peek_ret *ret)
{
    virDomainPtr dom;
    char *path;
    unsigned long long offset;
    size_t size;
    unsigned int flags;

705
    dom = get_nonnull_domain (conn, args->dom);
706
    if (dom == NULL) {
707
        remoteDispatchConnError(rerr, conn);
708
        return -1;
709 710 711 712 713 714 715
    }
    path = args->path;
    offset = args->offset;
    size = args->size;
    flags = args->flags;

    if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
716
        virDomainFree (dom);
717 718 719
        remoteDispatchFormatError (rerr,
                                   "%s", _("size > maximum buffer size"));
        return -1;
720 721 722
    }

    ret->buffer.buffer_len = size;
723
    if (VIR_ALLOC_N (ret->buffer.buffer_val, size) < 0) {
724
        virDomainFree (dom);
725
        remoteDispatchOOMError(rerr);
726
        return -1;
727 728 729 730 731 732
    }

    if (virDomainBlockPeek (dom, path, offset, size,
                            ret->buffer.buffer_val, flags) == -1) {
        /* free (ret->buffer.buffer_val); - caller frees */
        virDomainFree (dom);
733
        remoteDispatchConnError(rerr, conn);
734 735 736 737 738 739 740
        return -1;
    }
    virDomainFree (dom);

    return 0;
}

R
Richard W.M. Jones 已提交
741 742
static int
remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
743 744
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
745
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
746
                                remote_error *rerr,
R
Richard W.M. Jones 已提交
747 748 749 750 751 752 753 754
                                remote_domain_memory_peek_args *args,
                                remote_domain_memory_peek_ret *ret)
{
    virDomainPtr dom;
    unsigned long long offset;
    size_t size;
    unsigned int flags;

755
    dom = get_nonnull_domain (conn, args->dom);
R
Richard W.M. Jones 已提交
756
    if (dom == NULL) {
757
        remoteDispatchConnError(rerr, conn);
758
        return -1;
R
Richard W.M. Jones 已提交
759 760 761 762 763 764
    }
    offset = args->offset;
    size = args->size;
    flags = args->flags;

    if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) {
765
        virDomainFree (dom);
766 767 768
        remoteDispatchFormatError (rerr,
                                   "%s", _("size > maximum buffer size"));
        return -1;
R
Richard W.M. Jones 已提交
769 770 771 772 773
    }

    ret->buffer.buffer_len = size;
    if (VIR_ALLOC_N (ret->buffer.buffer_val, size) < 0) {
        virDomainFree (dom);
774
        remoteDispatchOOMError(rerr);
775
        return -1;
R
Richard W.M. Jones 已提交
776 777 778 779 780 781
    }

    if (virDomainMemoryPeek (dom, offset, size,
                             ret->buffer.buffer_val, flags) == -1) {
        /* free (ret->buffer.buffer_val); - caller frees */
        virDomainFree (dom);
782
        remoteDispatchConnError(rerr, conn);
R
Richard W.M. Jones 已提交
783 784 785 786 787 788 789
        return -1;
    }
    virDomainFree (dom);

    return 0;
}

790
static int
791
remoteDispatchDomainAttachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
792 793
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
794
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
795
                                  remote_error *rerr,
796 797 798 799 800
                                  remote_domain_attach_device_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

801
    dom = get_nonnull_domain (conn, args->dom);
802
    if (dom == NULL) {
803
        remoteDispatchConnError(rerr, conn);
804
        return -1;
805 806
    }

807 808
    if (virDomainAttachDevice (dom, args->xml) == -1) {
        virDomainFree(dom);
809
        remoteDispatchConnError(rerr, conn);
810
        return -1;
811 812
    }
    virDomainFree(dom);
813 814 815 816
    return 0;
}

static int
817
remoteDispatchDomainCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
818 819
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn,
820
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
821
                            remote_error *rerr,
822 823 824 825 826
                            remote_domain_create_args *args,
                            void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

827
    dom = get_nonnull_domain (conn, args->dom);
828
    if (dom == NULL) {
829
        remoteDispatchConnError(rerr, conn);
830
        return -1;
831 832
    }

833 834
    if (virDomainCreate (dom) == -1) {
        virDomainFree(dom);
835
        remoteDispatchConnError(rerr, conn);
836
        return -1;
837 838
    }
    virDomainFree(dom);
839 840 841 842
    return 0;
}

static int
843
remoteDispatchDomainCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
844 845
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
846
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
847 848 849
                               remote_error *rerr,
                               remote_domain_create_xml_args *args,
                               remote_domain_create_xml_ret *ret)
850 851 852
{
    virDomainPtr dom;

853
    dom = virDomainCreateXML (conn, args->xml_desc, args->flags);
854
    if (dom == NULL) {
855
        remoteDispatchConnError(rerr, conn);
856 857
        return -1;
    }
858 859

    make_nonnull_domain (&ret->dom, dom);
860
    virDomainFree(dom);
861 862 863 864 865

    return 0;
}

static int
866
remoteDispatchDomainDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
867 868
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
869
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
870
                               remote_error *rerr,
871 872 873 874 875
                               remote_domain_define_xml_args *args,
                               remote_domain_define_xml_ret *ret)
{
    virDomainPtr dom;

876
    dom = virDomainDefineXML (conn, args->xml);
877
    if (dom == NULL) {
878
        remoteDispatchConnError(rerr, conn);
879 880
        return -1;
    }
881 882

    make_nonnull_domain (&ret->dom, dom);
883
    virDomainFree(dom);
884 885 886 887 888

    return 0;
}

static int
889
remoteDispatchDomainDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
890 891
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
892
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
893
                             remote_error *rerr,
894 895 896 897 898
                             remote_domain_destroy_args *args,
                             void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

899
    dom = get_nonnull_domain (conn, args->dom);
900
    if (dom == NULL) {
901
        remoteDispatchConnError(rerr, conn);
902
        return -1;
903 904
    }

905 906
    if (virDomainDestroy (dom) == -1) {
        virDomainFree(dom);
907
        remoteDispatchConnError(rerr, conn);
908
        return -1;
909 910
    }
    virDomainFree(dom);
911 912 913 914
    return 0;
}

static int
915
remoteDispatchDomainDetachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
916 917
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
918
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
919
                                  remote_error *rerr,
920 921 922 923 924
                                  remote_domain_detach_device_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

925
    dom = get_nonnull_domain (conn, args->dom);
926
    if (dom == NULL) {
927
        remoteDispatchConnError(rerr, conn);
928
        return -1;
929 930
    }

931 932
    if (virDomainDetachDevice (dom, args->xml) == -1) {
        virDomainFree(dom);
933
        remoteDispatchConnError(rerr, conn);
934
        return -1;
935
    }
936

937
    virDomainFree(dom);
938 939 940 941
    return 0;
}

static int
942
remoteDispatchDomainDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
943 944
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
945
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
946
                             remote_error *rerr,
947 948 949 950 951
                             remote_domain_dump_xml_args *args,
                             remote_domain_dump_xml_ret *ret)
{
    virDomainPtr dom;

952
    dom = get_nonnull_domain (conn, args->dom);
953
    if (dom == NULL) {
954
        remoteDispatchConnError(rerr, conn);
955
        return -1;
956 957 958 959
    }

    /* remoteDispatchClientRequest will free this. */
    ret->xml = virDomainGetXMLDesc (dom, args->flags);
960
    if (!ret->xml) {
961
        virDomainFree(dom);
962
        remoteDispatchConnError(rerr, conn);
963
        return -1;
964 965
    }
    virDomainFree(dom);
966 967 968
    return 0;
}

969 970 971 972
static int
remoteDispatchDomainXmlFromNative (struct qemud_server *server ATTRIBUTE_UNUSED,
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
973
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
                                   remote_error *rerr,
                                   remote_domain_xml_from_native_args *args,
                                   remote_domain_xml_from_native_ret *ret)
{
    /* remoteDispatchClientRequest will free this. */
    ret->domainXml = virConnectDomainXMLFromNative (conn,
                                                    args->nativeFormat,
                                                    args->nativeConfig,
                                                    args->flags);
    if (!ret->domainXml) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }
    return 0;
}

static int
remoteDispatchDomainXmlToNative (struct qemud_server *server ATTRIBUTE_UNUSED,
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
994
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
                                 remote_error *rerr,
                                 remote_domain_xml_to_native_args *args,
                                 remote_domain_xml_to_native_ret *ret)
{
    /* remoteDispatchClientRequest will free this. */
    ret->nativeConfig = virConnectDomainXMLToNative (conn,
                                                     args->nativeFormat,
                                                     args->domainXml,
                                                     args->flags);
    if (!ret->nativeConfig) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }
    return 0;
}


1012
static int
1013
remoteDispatchDomainGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
1014 1015
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1016
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1017
                                  remote_error *rerr,
1018 1019 1020 1021 1022
                                  remote_domain_get_autostart_args *args,
                                  remote_domain_get_autostart_ret *ret)
{
    virDomainPtr dom;

1023
    dom = get_nonnull_domain (conn, args->dom);
1024
    if (dom == NULL) {
1025
        remoteDispatchConnError(rerr, conn);
1026
        return -1;
1027 1028
    }

1029 1030
    if (virDomainGetAutostart (dom, &ret->autostart) == -1) {
        virDomainFree(dom);
1031
        remoteDispatchConnError(rerr, conn);
1032
        return -1;
1033 1034
    }
    virDomainFree(dom);
1035 1036 1037 1038
    return 0;
}

static int
1039
remoteDispatchDomainGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
1040 1041
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
1042
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
1043
                             remote_error *rerr,
1044 1045 1046 1047 1048 1049
                             remote_domain_get_info_args *args,
                             remote_domain_get_info_ret *ret)
{
    virDomainPtr dom;
    virDomainInfo info;

1050
    dom = get_nonnull_domain (conn, args->dom);
1051
    if (dom == NULL) {
1052
        remoteDispatchConnError(rerr, conn);
1053
        return -1;
1054 1055
    }

1056 1057
    if (virDomainGetInfo (dom, &info) == -1) {
        virDomainFree(dom);
1058
        remoteDispatchConnError(rerr, conn);
1059
        return -1;
1060
    }
1061 1062 1063 1064 1065 1066 1067

    ret->state = info.state;
    ret->max_mem = info.maxMem;
    ret->memory = info.memory;
    ret->nr_virt_cpu = info.nrVirtCpu;
    ret->cpu_time = info.cpuTime;

1068 1069
    virDomainFree(dom);

1070 1071 1072 1073
    return 0;
}

static int
1074
remoteDispatchDomainGetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
1075 1076
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1077
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1078
                                  remote_error *rerr,
1079 1080 1081 1082 1083
                                  remote_domain_get_max_memory_args *args,
                                  remote_domain_get_max_memory_ret *ret)
{
    virDomainPtr dom;

1084
    dom = get_nonnull_domain (conn, args->dom);
1085
    if (dom == NULL) {
1086
        remoteDispatchConnError(rerr, conn);
1087
        return -1;
1088 1089 1090
    }

    ret->memory = virDomainGetMaxMemory (dom);
1091 1092
    if (ret->memory == 0) {
        virDomainFree(dom);
1093
        remoteDispatchConnError(rerr, conn);
1094 1095 1096
        return -1;
    }
    virDomainFree(dom);
1097 1098 1099 1100
    return 0;
}

static int
1101
remoteDispatchDomainGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
1102 1103
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
1104
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
1105
                                 remote_error *rerr,
1106 1107 1108 1109 1110
                                 remote_domain_get_max_vcpus_args *args,
                                 remote_domain_get_max_vcpus_ret *ret)
{
    virDomainPtr dom;

1111
    dom = get_nonnull_domain (conn, args->dom);
1112
    if (dom == NULL) {
1113
        remoteDispatchConnError(rerr, conn);
1114
        return -1;
1115 1116 1117
    }

    ret->num = virDomainGetMaxVcpus (dom);
1118 1119
    if (ret->num == -1) {
        virDomainFree(dom);
1120
        remoteDispatchConnError(rerr, conn);
1121 1122 1123
        return -1;
    }
    virDomainFree(dom);
1124 1125 1126
    return 0;
}

1127 1128 1129 1130
static int
remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSED,
                                     struct qemud_client *client ATTRIBUTE_UNUSED,
                                     virConnectPtr conn,
1131
                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
                                     remote_error *rerr,
                                     remote_domain_get_security_label_args *args,
                                     remote_domain_get_security_label_ret *ret)
{
    virDomainPtr dom;
    virSecurityLabel seclabel;

    dom = get_nonnull_domain(conn, args->dom);
    if (dom == NULL) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    memset(&seclabel, 0, sizeof seclabel);
    if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
        virDomainFree(dom);
1148
        remoteDispatchConnError(rerr, conn);
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
        return -1;
    }

    ret->label.label_len = strlen(seclabel.label) + 1;
    if (VIR_ALLOC_N(ret->label.label_val, ret->label.label_len) < 0) {
        virDomainFree(dom);
        remoteDispatchOOMError(rerr);
        return -1;
    }
    strcpy(ret->label.label_val, seclabel.label);
    ret->enforcing = seclabel.enforcing;
    virDomainFree(dom);

    return 0;
}

static int
remoteDispatchNodeGetSecurityModel(struct qemud_server *server ATTRIBUTE_UNUSED,
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
1169
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
1170 1171 1172 1173 1174 1175 1176 1177
                                   remote_error *rerr,
                                   void *args ATTRIBUTE_UNUSED,
                                   remote_node_get_security_model_ret *ret)
{
    virSecurityModel secmodel;

    memset(&secmodel, 0, sizeof secmodel);
    if (virNodeGetSecurityModel(conn, &secmodel) == -1) {
1178
        remoteDispatchConnError(rerr, conn);
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
        return -1;
    }

    ret->model.model_len = strlen(secmodel.model) + 1;
    if (VIR_ALLOC_N(ret->model.model_val, ret->model.model_len) < 0) {
        remoteDispatchOOMError(rerr);
        return -1;
    }
    strcpy(ret->model.model_val, secmodel.model);

    ret->doi.doi_len = strlen(secmodel.doi) + 1;
    if (VIR_ALLOC_N(ret->doi.doi_val, ret->doi.doi_len) < 0) {
        remoteDispatchOOMError(rerr);
        return -1;
    }
    strcpy(ret->doi.doi_val, secmodel.doi);

    return 0;
}

1199
static int
1200
remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED,
1201 1202
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
1203
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
1204
                               remote_error *rerr,
1205 1206 1207 1208 1209
                               remote_domain_get_os_type_args *args,
                               remote_domain_get_os_type_ret *ret)
{
    virDomainPtr dom;

1210
    dom = get_nonnull_domain (conn, args->dom);
1211
    if (dom == NULL) {
1212
        remoteDispatchConnError(rerr, conn);
1213
        return -1;
1214 1215 1216 1217
    }

    /* remoteDispatchClientRequest will free this */
    ret->type = virDomainGetOSType (dom);
1218
    if (ret->type == NULL) {
1219
        virDomainFree(dom);
1220
        remoteDispatchConnError(rerr, conn);
1221
        return -1;
1222 1223
    }
    virDomainFree(dom);
1224 1225 1226 1227
    return 0;
}

static int
1228
remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
1229 1230
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
1231
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
1232
                              remote_error *rerr,
1233 1234 1235
                              remote_domain_get_vcpus_args *args,
                              remote_domain_get_vcpus_ret *ret)
{
1236 1237 1238
    virDomainPtr dom = NULL;
    virVcpuInfoPtr info = NULL;
    unsigned char *cpumaps = NULL;
1239 1240
    int info_len, i;

1241
    dom = get_nonnull_domain (conn, args->dom);
1242
    if (dom == NULL) {
1243
        remoteDispatchConnError(rerr, conn);
1244
        return -1;
1245 1246 1247
    }

    if (args->maxinfo > REMOTE_VCPUINFO_MAX) {
1248
        virDomainFree(dom);
1249 1250
        remoteDispatchFormatError (rerr, "%s", _("maxinfo > REMOTE_VCPUINFO_MAX"));
        return -1;
1251 1252
    }

1253
    if (args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) {
1254
        virDomainFree(dom);
1255 1256
        remoteDispatchFormatError (rerr, "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX"));
        return -1;
1257 1258 1259
    }

    /* Allocate buffers to take the results. */
1260 1261
    if (VIR_ALLOC_N(info, args->maxinfo) < 0)
        goto oom;
1262 1263
    if (args->maplen > 0 &&
        VIR_ALLOC_N(cpumaps, args->maxinfo * args->maplen) < 0)
1264
        goto oom;
1265 1266 1267 1268

    info_len = virDomainGetVcpus (dom,
                                  info, args->maxinfo,
                                  cpumaps, args->maplen);
1269
    if (info_len == -1) {
1270 1271
        VIR_FREE(info);
        VIR_FREE(cpumaps);
1272
        virDomainFree(dom);
1273
        remoteDispatchConnError(rerr, conn);
1274 1275
        return -1;
    }
1276 1277 1278

    /* Allocate the return buffer for info. */
    ret->info.info_len = info_len;
1279 1280
    if (VIR_ALLOC_N(ret->info.info_val, info_len) < 0)
        goto oom;
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292

    for (i = 0; i < info_len; ++i) {
        ret->info.info_val[i].number = info[i].number;
        ret->info.info_val[i].state = info[i].state;
        ret->info.info_val[i].cpu_time = info[i].cpuTime;
        ret->info.info_val[i].cpu = info[i].cpu;
    }

    /* Don't need to allocate/copy the cpumaps if we make the reasonable
     * assumption that unsigned char and char are the same size.
     * Note that remoteDispatchClientRequest will free.
     */
1293
    ret->cpumaps.cpumaps_len = args->maxinfo * args->maplen;
1294 1295
    ret->cpumaps.cpumaps_val = (char *) cpumaps;

1296
    VIR_FREE(info);
1297
    virDomainFree(dom);
1298
    return 0;
1299 1300 1301 1302 1303

oom:
    VIR_FREE(info);
    VIR_FREE(cpumaps);
    virDomainFree(dom);
1304 1305
    remoteDispatchOOMError(rerr);
    return -1;
1306 1307
}

1308
static int
1309
remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED,
1310 1311
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
1312
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
1313
                                    remote_error *rerr,
1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
                                    remote_domain_migrate_prepare_args *args,
                                    remote_domain_migrate_prepare_ret *ret)
{
    int r;
    char *cookie = NULL;
    int cookielen = 0;
    char *uri_in;
    char **uri_out;
    char *dname;

    uri_in = args->uri_in == NULL ? NULL : *args->uri_in;
    dname = args->dname == NULL ? NULL : *args->dname;

    /* Wacky world of XDR ... */
1328
    if (VIR_ALLOC(uri_out) < 0) {
1329 1330
        remoteDispatchOOMError(rerr);
        return -1;
1331
    }
1332

1333
    r = virDomainMigratePrepare (conn, &cookie, &cookielen,
D
Daniel P. Berrange 已提交
1334 1335
                                 uri_in, uri_out,
                                 args->flags, dname, args->resource);
D
Daniel P. Berrange 已提交
1336
    if (r == -1) {
1337
        VIR_FREE(uri_out);
1338
        remoteDispatchConnError(rerr, conn);
D
Daniel P. Berrange 已提交
1339 1340
        return -1;
    }
1341 1342 1343 1344 1345 1346

    /* remoteDispatchClientRequest will free cookie, uri_out and
     * the string if there is one.
     */
    ret->cookie.cookie_len = cookielen;
    ret->cookie.cookie_val = cookie;
D
Daniel P. Berrange 已提交
1347 1348
    if (*uri_out == NULL) {
        ret->uri_out = NULL;
1349
        VIR_FREE(uri_out);
D
Daniel P. Berrange 已提交
1350 1351 1352
    } else {
        ret->uri_out = uri_out;
    }
1353 1354 1355 1356 1357

    return 0;
}

static int
1358
remoteDispatchDomainMigratePerform (struct qemud_server *server ATTRIBUTE_UNUSED,
1359 1360
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
1361
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
1362
                                    remote_error *rerr,
1363 1364 1365 1366 1367 1368 1369
                                    remote_domain_migrate_perform_args *args,
                                    void *ret ATTRIBUTE_UNUSED)
{
    int r;
    virDomainPtr dom;
    char *dname;

1370
    dom = get_nonnull_domain (conn, args->dom);
1371
    if (dom == NULL) {
1372
        remoteDispatchConnError(rerr, conn);
1373
        return -1;
1374 1375 1376 1377
    }

    dname = args->dname == NULL ? NULL : *args->dname;

D
Daniel P. Berrange 已提交
1378 1379 1380 1381 1382
    r = virDomainMigratePerform (dom,
                                 args->cookie.cookie_val,
                                 args->cookie.cookie_len,
                                 args->uri,
                                 args->flags, dname, args->resource);
D
Daniel P. Berrange 已提交
1383
    virDomainFree (dom);
1384
    if (r == -1) {
1385
        remoteDispatchConnError(rerr, conn);
1386 1387
        return -1;
    }
1388 1389 1390 1391 1392

    return 0;
}

static int
1393
remoteDispatchDomainMigrateFinish (struct qemud_server *server ATTRIBUTE_UNUSED,
1394 1395
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
1396
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
1397
                                   remote_error *rerr,
1398 1399 1400 1401 1402 1403
                                   remote_domain_migrate_finish_args *args,
                                   remote_domain_migrate_finish_ret *ret)
{
    virDomainPtr ddom;
    CHECK_CONN (client);

1404
    ddom = virDomainMigrateFinish (conn, args->dname,
D
Daniel P. Berrange 已提交
1405 1406 1407 1408
                                   args->cookie.cookie_val,
                                   args->cookie.cookie_len,
                                   args->uri,
                                   args->flags);
1409
    if (ddom == NULL) {
1410
        remoteDispatchConnError(rerr, conn);
1411 1412
        return -1;
    }
1413 1414

    make_nonnull_domain (&ret->ddom, ddom);
D
Daniel P. Berrange 已提交
1415
    virDomainFree (ddom);
1416 1417 1418
    return 0;
}

D
Daniel Veillard 已提交
1419 1420
static int
remoteDispatchDomainMigratePrepare2 (struct qemud_server *server ATTRIBUTE_UNUSED,
1421 1422
                                     struct qemud_client *client ATTRIBUTE_UNUSED,
                                     virConnectPtr conn,
1423
                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
1424
                                     remote_error *rerr,
D
Daniel Veillard 已提交
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
                                     remote_domain_migrate_prepare2_args *args,
                                     remote_domain_migrate_prepare2_ret *ret)
{
    int r;
    char *cookie = NULL;
    int cookielen = 0;
    char *uri_in;
    char **uri_out;
    char *dname;
    CHECK_CONN (client);

    uri_in = args->uri_in == NULL ? NULL : *args->uri_in;
    dname = args->dname == NULL ? NULL : *args->dname;

    /* Wacky world of XDR ... */
    if (VIR_ALLOC(uri_out) < 0) {
1441 1442
        remoteDispatchOOMError(rerr);
        return -1;
D
Daniel Veillard 已提交
1443 1444
    }

1445
    r = virDomainMigratePrepare2 (conn, &cookie, &cookielen,
D
Daniel P. Berrange 已提交
1446 1447 1448
                                  uri_in, uri_out,
                                  args->flags, dname, args->resource,
                                  args->dom_xml);
1449
    if (r == -1) {
1450
        remoteDispatchConnError(rerr, conn);
1451 1452
        return -1;
    }
D
Daniel Veillard 已提交
1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465

    /* remoteDispatchClientRequest will free cookie, uri_out and
     * the string if there is one.
     */
    ret->cookie.cookie_len = cookielen;
    ret->cookie.cookie_val = cookie;
    ret->uri_out = *uri_out == NULL ? NULL : uri_out;

    return 0;
}

static int
remoteDispatchDomainMigrateFinish2 (struct qemud_server *server ATTRIBUTE_UNUSED,
1466 1467
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
1468
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
1469
                                    remote_error *rerr,
D
Daniel Veillard 已提交
1470 1471 1472 1473 1474 1475
                                    remote_domain_migrate_finish2_args *args,
                                    remote_domain_migrate_finish2_ret *ret)
{
    virDomainPtr ddom;
    CHECK_CONN (client);

1476
    ddom = virDomainMigrateFinish2 (conn, args->dname,
D
Daniel P. Berrange 已提交
1477 1478 1479 1480 1481
                                    args->cookie.cookie_val,
                                    args->cookie.cookie_len,
                                    args->uri,
                                    args->flags,
                                    args->retcode);
1482
    if (ddom == NULL) {
1483
        remoteDispatchConnError(rerr, conn);
1484 1485
        return -1;
    }
D
Daniel Veillard 已提交
1486 1487 1488 1489 1490 1491

    make_nonnull_domain (&ret->ddom, ddom);

    return 0;
}

C
Chris Lalancette 已提交
1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
static int
remoteDispatchDomainMigratePrepareTunnel(struct qemud_server *server ATTRIBUTE_UNUSED,
                                         struct qemud_client *client,
                                         virConnectPtr conn,
                                         remote_message_header *hdr,
                                         remote_error *rerr,
                                         remote_domain_migrate_prepare_tunnel_args *args,
                                         void *ret ATTRIBUTE_UNUSED)
{
    int r;
    char *dname;
    struct qemud_client_stream *stream;
    CHECK_CONN (client);

    dname = args->dname == NULL ? NULL : *args->dname;

    stream = remoteCreateClientStream(conn, hdr);
    if (!stream) {
        remoteDispatchOOMError(rerr);
        return -1;
    }

1514
    r = virDomainMigratePrepareTunnel(conn, stream->st,
C
Chris Lalancette 已提交
1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
                                      args->flags, dname, args->resource,
                                      args->dom_xml);
    if (r == -1) {
        remoteFreeClientStream(client, stream);
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    if (remoteAddClientStream(client, stream, 0) < 0) {
        remoteDispatchConnError(rerr, conn);
        virStreamAbort(stream->st);
        remoteFreeClientStream(client, stream);
        return -1;
    }

    return 0;
}

1533
static int
1534
remoteDispatchListDefinedDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
1535 1536
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1537
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1538
                                  remote_error *rerr,
1539 1540 1541 1542 1543
                                  remote_list_defined_domains_args *args,
                                  remote_list_defined_domains_ret *ret)
{

    if (args->maxnames > REMOTE_DOMAIN_NAME_LIST_MAX) {
1544 1545 1546
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_DOMAIN_NAME_LIST_MAX"));
        return -1;
1547 1548 1549
    }

    /* Allocate return buffer. */
1550
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
1551 1552
        remoteDispatchOOMError(rerr);
        return -1;
1553
    }
1554 1555

    ret->names.names_len =
1556
        virConnectListDefinedDomains (conn,
1557
                                      ret->names.names_val, args->maxnames);
1558 1559
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_val);
1560
        remoteDispatchConnError(rerr, conn);
1561 1562
        return -1;
    }
1563 1564 1565 1566 1567

    return 0;
}

static int
1568
remoteDispatchDomainLookupById (struct qemud_server *server ATTRIBUTE_UNUSED,
1569 1570
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
1571
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
1572
                                remote_error *rerr,
1573 1574 1575 1576 1577
                                remote_domain_lookup_by_id_args *args,
                                remote_domain_lookup_by_id_ret *ret)
{
    virDomainPtr dom;

1578
    dom = virDomainLookupByID (conn, args->id);
1579
    if (dom == NULL) {
1580
        remoteDispatchConnError(rerr, conn);
1581 1582
        return -1;
    }
1583 1584

    make_nonnull_domain (&ret->dom, dom);
1585
    virDomainFree(dom);
1586 1587 1588 1589
    return 0;
}

static int
1590
remoteDispatchDomainLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
1591 1592
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1593
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1594
                                  remote_error *rerr,
1595 1596 1597 1598 1599
                                  remote_domain_lookup_by_name_args *args,
                                  remote_domain_lookup_by_name_ret *ret)
{
    virDomainPtr dom;

1600
    dom = virDomainLookupByName (conn, args->name);
1601
    if (dom == NULL) {
1602
        remoteDispatchConnError(rerr, conn);
1603 1604
        return -1;
    }
1605 1606

    make_nonnull_domain (&ret->dom, dom);
1607
    virDomainFree(dom);
1608 1609 1610 1611
    return 0;
}

static int
1612
remoteDispatchDomainLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
1613 1614
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1615
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1616
                                  remote_error *rerr,
1617 1618 1619 1620 1621
                                  remote_domain_lookup_by_uuid_args *args,
                                  remote_domain_lookup_by_uuid_ret *ret)
{
    virDomainPtr dom;

1622
    dom = virDomainLookupByUUID (conn, (unsigned char *) args->uuid);
1623
    if (dom == NULL) {
1624
        remoteDispatchConnError(rerr, conn);
1625 1626
        return -1;
    }
1627 1628

    make_nonnull_domain (&ret->dom, dom);
1629
    virDomainFree(dom);
1630 1631 1632 1633
    return 0;
}

static int
1634
remoteDispatchNumOfDefinedDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
1635 1636
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
1637
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
1638
                                   remote_error *rerr,
1639 1640 1641 1642
                                   void *args ATTRIBUTE_UNUSED,
                                   remote_num_of_defined_domains_ret *ret)
{

1643
    ret->num = virConnectNumOfDefinedDomains (conn);
1644
    if (ret->num == -1) {
1645
        remoteDispatchConnError(rerr, conn);
1646 1647
        return -1;
    }
1648 1649 1650 1651 1652

    return 0;
}

static int
1653
remoteDispatchDomainPinVcpu (struct qemud_server *server ATTRIBUTE_UNUSED,
1654 1655
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
1656
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
1657
                             remote_error *rerr,
1658 1659 1660 1661 1662 1663
                             remote_domain_pin_vcpu_args *args,
                             void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;
    int rv;

1664
    dom = get_nonnull_domain (conn, args->dom);
1665
    if (dom == NULL) {
1666
        remoteDispatchConnError(rerr, conn);
1667
        return -1;
1668 1669 1670
    }

    if (args->cpumap.cpumap_len > REMOTE_CPUMAP_MAX) {
1671
        virDomainFree(dom);
1672 1673
        remoteDispatchFormatError (rerr, "%s", _("cpumap_len > REMOTE_CPUMAP_MAX"));
        return -1;
1674 1675 1676 1677 1678
    }

    rv = virDomainPinVcpu (dom, args->vcpu,
                           (unsigned char *) args->cpumap.cpumap_val,
                           args->cpumap.cpumap_len);
1679 1680
    if (rv == -1) {
        virDomainFree(dom);
1681
        remoteDispatchConnError(rerr, conn);
1682 1683 1684
        return -1;
    }
    virDomainFree(dom);
1685 1686 1687 1688
    return 0;
}

static int
1689
remoteDispatchDomainReboot (struct qemud_server *server ATTRIBUTE_UNUSED,
1690 1691
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn,
1692
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
1693
                            remote_error *rerr,
1694 1695 1696 1697 1698
                            remote_domain_reboot_args *args,
                            void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1699
    dom = get_nonnull_domain (conn, args->dom);
1700
    if (dom == NULL) {
1701
        remoteDispatchConnError(rerr, conn);
1702
        return -1;
1703 1704
    }

1705 1706
    if (virDomainReboot (dom, args->flags) == -1) {
        virDomainFree(dom);
1707
        remoteDispatchConnError(rerr, conn);
1708
        return -1;
1709 1710
    }
    virDomainFree(dom);
1711 1712 1713 1714
    return 0;
}

static int
1715
remoteDispatchDomainRestore (struct qemud_server *server ATTRIBUTE_UNUSED,
1716 1717
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
1718
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
1719
                             remote_error *rerr,
1720 1721 1722 1723
                             remote_domain_restore_args *args,
                             void *ret ATTRIBUTE_UNUSED)
{

1724 1725
    if (virDomainRestore (conn, args->from) == -1) {
        remoteDispatchConnError(rerr, conn);
1726
        return -1;
1727
    }
1728 1729 1730 1731 1732

    return 0;
}

static int
1733
remoteDispatchDomainResume (struct qemud_server *server ATTRIBUTE_UNUSED,
1734 1735
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn,
1736
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
1737
                            remote_error *rerr,
1738 1739 1740 1741 1742
                            remote_domain_resume_args *args,
                            void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1743
    dom = get_nonnull_domain (conn, args->dom);
1744
    if (dom == NULL) {
1745
        remoteDispatchConnError(rerr, conn);
1746
        return -1;
1747 1748
    }

1749 1750
    if (virDomainResume (dom) == -1) {
        virDomainFree(dom);
1751
        remoteDispatchConnError(rerr, conn);
1752
        return -1;
1753 1754
    }
    virDomainFree(dom);
1755 1756 1757 1758
    return 0;
}

static int
1759
remoteDispatchDomainSave (struct qemud_server *server ATTRIBUTE_UNUSED,
1760 1761
                          struct qemud_client *client ATTRIBUTE_UNUSED,
                          virConnectPtr conn,
1762
                          remote_message_header *hdr ATTRIBUTE_UNUSED,
1763
                          remote_error *rerr,
1764 1765 1766 1767 1768
                          remote_domain_save_args *args,
                          void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1769
    dom = get_nonnull_domain (conn, args->dom);
1770
    if (dom == NULL) {
1771
        remoteDispatchConnError(rerr, conn);
1772
        return -1;
1773 1774
    }

1775 1776
    if (virDomainSave (dom, args->to) == -1) {
        virDomainFree(dom);
1777
        remoteDispatchConnError(rerr, conn);
1778
        return -1;
1779 1780
    }
    virDomainFree(dom);
1781 1782 1783 1784
    return 0;
}

static int
1785
remoteDispatchDomainCoreDump (struct qemud_server *server ATTRIBUTE_UNUSED,
1786 1787
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
1788
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
1789
                              remote_error *rerr,
1790 1791 1792 1793 1794
                              remote_domain_core_dump_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1795
    dom = get_nonnull_domain (conn, args->dom);
1796
    if (dom == NULL) {
1797
        remoteDispatchConnError(rerr, conn);
1798
        return -1;
1799 1800
    }

1801 1802
    if (virDomainCoreDump (dom, args->to, args->flags) == -1) {
        virDomainFree(dom);
1803
        remoteDispatchConnError(rerr, conn);
1804
        return -1;
1805 1806
    }
    virDomainFree(dom);
1807 1808 1809 1810
    return 0;
}

static int
1811
remoteDispatchDomainSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
1812 1813
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1814
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1815
                                  remote_error *rerr,
1816 1817 1818 1819 1820
                                  remote_domain_set_autostart_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1821
    dom = get_nonnull_domain (conn, args->dom);
1822
    if (dom == NULL) {
1823
        remoteDispatchConnError(rerr, conn);
1824
        return -1;
1825 1826
    }

1827 1828
    if (virDomainSetAutostart (dom, args->autostart) == -1) {
        virDomainFree(dom);
1829
        remoteDispatchConnError(rerr, conn);
1830
        return -1;
1831 1832
    }
    virDomainFree(dom);
1833 1834 1835 1836
    return 0;
}

static int
1837
remoteDispatchDomainSetMaxMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
1838 1839
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
1840
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
1841
                                  remote_error *rerr,
1842 1843 1844 1845 1846
                                  remote_domain_set_max_memory_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1847
    dom = get_nonnull_domain (conn, args->dom);
1848
    if (dom == NULL) {
1849
        remoteDispatchConnError(rerr, conn);
1850
        return -1;
1851 1852
    }

1853 1854
    if (virDomainSetMaxMemory (dom, args->memory) == -1) {
        virDomainFree(dom);
1855
        remoteDispatchConnError(rerr, conn);
1856
        return -1;
1857 1858
    }
    virDomainFree(dom);
1859 1860 1861 1862
    return 0;
}

static int
1863
remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED,
1864 1865
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
1866
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
1867
                               remote_error *rerr,
1868 1869 1870 1871 1872
                               remote_domain_set_memory_args *args,
                               void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1873
    dom = get_nonnull_domain (conn, args->dom);
1874
    if (dom == NULL) {
1875
        remoteDispatchConnError(rerr, conn);
1876
        return -1;
1877 1878
    }

1879 1880
    if (virDomainSetMemory (dom, args->memory) == -1) {
        virDomainFree(dom);
1881
        remoteDispatchConnError(rerr, conn);
1882
        return -1;
1883 1884
    }
    virDomainFree(dom);
1885 1886 1887 1888
    return 0;
}

static int
1889
remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
1890 1891
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
1892
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
1893
                              remote_error *rerr,
1894 1895 1896 1897 1898
                              remote_domain_set_vcpus_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1899
    dom = get_nonnull_domain (conn, args->dom);
1900
    if (dom == NULL) {
1901
        remoteDispatchConnError(rerr, conn);
1902
        return -1;
1903 1904
    }

1905 1906
    if (virDomainSetVcpus (dom, args->nvcpus) == -1) {
        virDomainFree(dom);
1907
        remoteDispatchConnError(rerr, conn);
1908
        return -1;
1909 1910
    }
    virDomainFree(dom);
1911 1912 1913 1914
    return 0;
}

static int
1915
remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED,
1916 1917
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
1918
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
1919
                              remote_error *rerr,
1920 1921 1922 1923 1924
                              remote_domain_shutdown_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1925
    dom = get_nonnull_domain (conn, args->dom);
1926
    if (dom == NULL) {
1927
        remoteDispatchConnError(rerr, conn);
1928
        return -1;
1929 1930
    }

1931 1932
    if (virDomainShutdown (dom) == -1) {
        virDomainFree(dom);
1933
        remoteDispatchConnError(rerr, conn);
1934
        return -1;
1935 1936
    }
    virDomainFree(dom);
1937 1938 1939 1940
    return 0;
}

static int
1941
remoteDispatchDomainSuspend (struct qemud_server *server ATTRIBUTE_UNUSED,
1942 1943
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
1944
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
1945
                             remote_error *rerr,
1946 1947 1948 1949 1950
                             remote_domain_suspend_args *args,
                             void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1951
    dom = get_nonnull_domain (conn, args->dom);
1952
    if (dom == NULL) {
1953
        remoteDispatchConnError(rerr, conn);
1954
        return -1;
1955 1956
    }

1957 1958
    if (virDomainSuspend (dom) == -1) {
        virDomainFree(dom);
1959
        remoteDispatchConnError(rerr, conn);
1960
        return -1;
1961 1962
    }
    virDomainFree(dom);
1963 1964 1965 1966
    return 0;
}

static int
1967
remoteDispatchDomainUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
1968 1969
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
1970
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
1971
                              remote_error *rerr,
1972 1973 1974 1975 1976
                              remote_domain_undefine_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virDomainPtr dom;

1977
    dom = get_nonnull_domain (conn, args->dom);
1978
    if (dom == NULL) {
1979
        remoteDispatchConnError(rerr, conn);
1980
        return -1;
1981 1982
    }

1983 1984
    if (virDomainUndefine (dom) == -1) {
        virDomainFree(dom);
1985
        remoteDispatchConnError(rerr, conn);
1986
        return -1;
1987 1988
    }
    virDomainFree(dom);
1989 1990 1991 1992
    return 0;
}

static int
1993
remoteDispatchListDefinedNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
1994 1995
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
1996
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
1997
                                   remote_error *rerr,
1998 1999 2000 2001 2002
                                   remote_list_defined_networks_args *args,
                                   remote_list_defined_networks_ret *ret)
{

    if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
2003 2004 2005
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
        return -1;
2006 2007 2008
    }

    /* Allocate return buffer. */
2009
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
2010 2011
        remoteDispatchOOMError(rerr);
        return -1;
2012
    }
2013 2014

    ret->names.names_len =
2015
        virConnectListDefinedNetworks (conn,
2016
                                       ret->names.names_val, args->maxnames);
2017 2018
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_val);
2019
        remoteDispatchConnError(rerr, conn);
2020 2021
        return -1;
    }
2022 2023 2024 2025 2026

    return 0;
}

static int
2027
remoteDispatchListDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
2028 2029
                           struct qemud_client *client ATTRIBUTE_UNUSED,
                           virConnectPtr conn,
2030
                           remote_message_header *hdr ATTRIBUTE_UNUSED,
2031
                           remote_error *rerr,
2032 2033 2034 2035 2036
                           remote_list_domains_args *args,
                           remote_list_domains_ret *ret)
{

    if (args->maxids > REMOTE_DOMAIN_ID_LIST_MAX) {
2037 2038 2039
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxids > REMOTE_DOMAIN_ID_LIST_MAX"));
        return -1;
2040 2041 2042
    }

    /* Allocate return buffer. */
2043
    if (VIR_ALLOC_N(ret->ids.ids_val, args->maxids) < 0) {
2044 2045
        remoteDispatchOOMError(rerr);
        return -1;
2046
    }
2047

2048
    ret->ids.ids_len = virConnectListDomains (conn,
2049
                                              ret->ids.ids_val, args->maxids);
2050 2051
    if (ret->ids.ids_len == -1) {
        VIR_FREE(ret->ids.ids_val);
2052
        remoteDispatchConnError(rerr, conn);
2053 2054
        return -1;
    }
2055 2056 2057 2058 2059

    return 0;
}

static int
2060
remoteDispatchListNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
2061 2062
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn,
2063
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
2064
                            remote_error *rerr,
2065 2066 2067 2068 2069
                            remote_list_networks_args *args,
                            remote_list_networks_ret *ret)
{

    if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
2070 2071 2072
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
        return -1;
2073 2074 2075
    }

    /* Allocate return buffer. */
2076
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
2077 2078
        remoteDispatchOOMError(rerr);
        return -1;
2079
    }
2080 2081

    ret->names.names_len =
2082
        virConnectListNetworks (conn,
2083
                                ret->names.names_val, args->maxnames);
2084 2085
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_len);
2086
        remoteDispatchConnError(rerr, conn);
2087 2088
        return -1;
    }
2089 2090 2091 2092 2093

    return 0;
}

static int
2094
remoteDispatchNetworkCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
2095 2096
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
2097
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
2098
                             remote_error *rerr,
2099 2100 2101 2102 2103
                             remote_network_create_args *args,
                             void *ret ATTRIBUTE_UNUSED)
{
    virNetworkPtr net;

2104
    net = get_nonnull_network (conn, args->net);
2105
    if (net == NULL) {
2106
        remoteDispatchConnError(rerr, conn);
2107
        return -1;
2108 2109
    }

2110 2111
    if (virNetworkCreate (net) == -1) {
        virNetworkFree(net);
2112
        remoteDispatchConnError(rerr, conn);
2113
        return -1;
2114 2115
    }
    virNetworkFree(net);
2116 2117 2118 2119
    return 0;
}

static int
2120
remoteDispatchNetworkCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
2121 2122
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
2123
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
2124
                                remote_error *rerr,
2125 2126 2127 2128 2129
                                remote_network_create_xml_args *args,
                                remote_network_create_xml_ret *ret)
{
    virNetworkPtr net;

2130
    net = virNetworkCreateXML (conn, args->xml);
2131
    if (net == NULL) {
2132
        remoteDispatchConnError(rerr, conn);
2133 2134
        return -1;
    }
2135 2136

    make_nonnull_network (&ret->net, net);
2137
    virNetworkFree(net);
2138 2139 2140 2141
    return 0;
}

static int
2142
remoteDispatchNetworkDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
2143 2144
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
2145
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
2146
                                remote_error *rerr,
2147 2148 2149 2150 2151
                                remote_network_define_xml_args *args,
                                remote_network_define_xml_ret *ret)
{
    virNetworkPtr net;

2152
    net = virNetworkDefineXML (conn, args->xml);
2153
    if (net == NULL) {
2154
        remoteDispatchConnError(rerr, conn);
2155 2156
        return -1;
    }
2157 2158

    make_nonnull_network (&ret->net, net);
2159
    virNetworkFree(net);
2160 2161 2162 2163
    return 0;
}

static int
2164
remoteDispatchNetworkDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
2165 2166
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
2167
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
2168
                              remote_error *rerr,
2169 2170 2171 2172 2173
                              remote_network_destroy_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virNetworkPtr net;

2174
    net = get_nonnull_network (conn, args->net);
2175
    if (net == NULL) {
2176
        remoteDispatchConnError(rerr, conn);
2177
        return -1;
2178 2179
    }

2180 2181
    if (virNetworkDestroy (net) == -1) {
        virNetworkFree(net);
2182
        remoteDispatchConnError(rerr, conn);
2183
        return -1;
2184 2185
    }
    virNetworkFree(net);
2186 2187 2188 2189
    return 0;
}

static int
2190
remoteDispatchNetworkDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
2191 2192
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
2193
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
2194
                              remote_error *rerr,
2195 2196 2197 2198 2199
                              remote_network_dump_xml_args *args,
                              remote_network_dump_xml_ret *ret)
{
    virNetworkPtr net;

2200
    net = get_nonnull_network (conn, args->net);
2201
    if (net == NULL) {
2202
        remoteDispatchConnError(rerr, conn);
2203
        return -1;
2204 2205 2206 2207
    }

    /* remoteDispatchClientRequest will free this. */
    ret->xml = virNetworkGetXMLDesc (net, args->flags);
2208 2209
    if (!ret->xml) {
        virNetworkFree(net);
2210
        remoteDispatchConnError(rerr, conn);
2211 2212 2213
        return -1;
    }
    virNetworkFree(net);
2214 2215 2216 2217
    return 0;
}

static int
2218
remoteDispatchNetworkGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
2219 2220
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
2221
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
2222
                                   remote_error *rerr,
2223 2224 2225 2226 2227
                                   remote_network_get_autostart_args *args,
                                   remote_network_get_autostart_ret *ret)
{
    virNetworkPtr net;

2228
    net = get_nonnull_network (conn, args->net);
2229
    if (net == NULL) {
2230
        remoteDispatchConnError(rerr, conn);
2231
        return -1;
2232 2233
    }

2234 2235
    if (virNetworkGetAutostart (net, &ret->autostart) == -1) {
        virNetworkFree(net);
2236
        remoteDispatchConnError(rerr, conn);
2237
        return -1;
2238 2239
    }
    virNetworkFree(net);
2240 2241 2242 2243
    return 0;
}

static int
2244
remoteDispatchNetworkGetBridgeName (struct qemud_server *server ATTRIBUTE_UNUSED,
2245 2246
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
2247
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
2248
                                    remote_error *rerr,
2249 2250 2251 2252 2253
                                    remote_network_get_bridge_name_args *args,
                                    remote_network_get_bridge_name_ret *ret)
{
    virNetworkPtr net;

2254
    net = get_nonnull_network (conn, args->net);
2255
    if (net == NULL) {
2256
        remoteDispatchConnError(rerr, conn);
2257
        return -1;
2258 2259 2260 2261
    }

    /* remoteDispatchClientRequest will free this. */
    ret->name = virNetworkGetBridgeName (net);
2262 2263
    if (!ret->name) {
        virNetworkFree(net);
2264
        remoteDispatchConnError(rerr, conn);
2265 2266 2267
        return -1;
    }
    virNetworkFree(net);
2268 2269 2270 2271
    return 0;
}

static int
2272
remoteDispatchNetworkLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
2273 2274
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
2275
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
2276
                                   remote_error *rerr,
2277 2278 2279 2280 2281
                                   remote_network_lookup_by_name_args *args,
                                   remote_network_lookup_by_name_ret *ret)
{
    virNetworkPtr net;

2282
    net = virNetworkLookupByName (conn, args->name);
2283
    if (net == NULL) {
2284
        remoteDispatchConnError(rerr, conn);
2285 2286
        return -1;
    }
2287 2288

    make_nonnull_network (&ret->net, net);
2289
    virNetworkFree(net);
2290 2291 2292 2293
    return 0;
}

static int
2294
remoteDispatchNetworkLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
2295 2296
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
2297
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
2298
                                   remote_error *rerr,
2299 2300 2301 2302 2303
                                   remote_network_lookup_by_uuid_args *args,
                                   remote_network_lookup_by_uuid_ret *ret)
{
    virNetworkPtr net;

2304
    net = virNetworkLookupByUUID (conn, (unsigned char *) args->uuid);
2305
    if (net == NULL) {
2306
        remoteDispatchConnError(rerr, conn);
2307 2308
        return -1;
    }
2309 2310

    make_nonnull_network (&ret->net, net);
2311
    virNetworkFree(net);
2312 2313 2314 2315
    return 0;
}

static int
2316
remoteDispatchNetworkSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
2317 2318
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
2319
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
2320
                                   remote_error *rerr,
2321 2322 2323 2324 2325
                                   remote_network_set_autostart_args *args,
                                   void *ret ATTRIBUTE_UNUSED)
{
    virNetworkPtr net;

2326
    net = get_nonnull_network (conn, args->net);
2327
    if (net == NULL) {
2328
        remoteDispatchConnError(rerr, conn);
2329
        return -1;
2330 2331
    }

2332 2333
    if (virNetworkSetAutostart (net, args->autostart) == -1) {
        virNetworkFree(net);
2334
        remoteDispatchConnError(rerr, conn);
2335
        return -1;
2336 2337
    }
    virNetworkFree(net);
2338 2339 2340 2341
    return 0;
}

static int
2342
remoteDispatchNetworkUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
2343 2344
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
2345
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
2346
                               remote_error *rerr,
2347 2348 2349 2350 2351
                               remote_network_undefine_args *args,
                               void *ret ATTRIBUTE_UNUSED)
{
    virNetworkPtr net;

2352
    net = get_nonnull_network (conn, args->net);
2353
    if (net == NULL) {
2354
        remoteDispatchConnError(rerr, conn);
2355
        return -1;
2356 2357
    }

2358 2359
    if (virNetworkUndefine (net) == -1) {
        virNetworkFree(net);
2360
        remoteDispatchConnError(rerr, conn);
2361
        return -1;
2362 2363
    }
    virNetworkFree(net);
2364 2365 2366 2367
    return 0;
}

static int
2368
remoteDispatchNumOfDefinedNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
2369 2370
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
2371
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
2372
                                    remote_error *rerr,
2373 2374 2375 2376
                                    void *args ATTRIBUTE_UNUSED,
                                    remote_num_of_defined_networks_ret *ret)
{

2377
    ret->num = virConnectNumOfDefinedNetworks (conn);
2378
    if (ret->num == -1) {
2379
        remoteDispatchConnError(rerr, conn);
2380 2381
        return -1;
    }
2382 2383 2384 2385 2386

    return 0;
}

static int
2387
remoteDispatchNumOfDomains (struct qemud_server *server ATTRIBUTE_UNUSED,
2388 2389
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn,
2390
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
2391
                            remote_error *rerr,
2392 2393 2394 2395
                            void *args ATTRIBUTE_UNUSED,
                            remote_num_of_domains_ret *ret)
{

2396
    ret->num = virConnectNumOfDomains (conn);
2397
    if (ret->num == -1) {
2398
        remoteDispatchConnError(rerr, conn);
2399 2400
        return -1;
    }
2401 2402 2403 2404 2405

    return 0;
}

static int
2406
remoteDispatchNumOfNetworks (struct qemud_server *server ATTRIBUTE_UNUSED,
2407 2408
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn,
2409
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
2410
                             remote_error *rerr,
2411 2412 2413 2414
                             void *args ATTRIBUTE_UNUSED,
                             remote_num_of_networks_ret *ret)
{

2415
    ret->num = virConnectNumOfNetworks (conn);
2416
    if (ret->num == -1) {
2417
        remoteDispatchConnError(rerr, conn);
2418 2419
        return -1;
    }
2420 2421 2422 2423

    return 0;
}

2424

D
Daniel Veillard 已提交
2425 2426 2427 2428 2429
/*-------------------------------------------------------------*/
static int
remoteDispatchNumOfInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
2430
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
D
Daniel Veillard 已提交
2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448
                               remote_error *rerr,
                               void *args ATTRIBUTE_UNUSED,
                               remote_num_of_interfaces_ret *ret)
{

    ret->num = virConnectNumOfInterfaces (conn);
    if (ret->num == -1) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}

static int
remoteDispatchListInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
                              struct qemud_client *client ATTRIBUTE_UNUSED,
                              virConnectPtr conn,
2449
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
D
Daniel Veillard 已提交
2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478
                              remote_error *rerr,
                              remote_list_interfaces_args *args,
                              remote_list_interfaces_ret *ret)
{

    if (args->maxnames > REMOTE_INTERFACE_NAME_LIST_MAX) {
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_INTERFACE_NAME_LIST_MAX"));
        return -1;
    }

    /* Allocate return buffer. */
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
        remoteDispatchOOMError(rerr);
        return -1;
    }

    ret->names.names_len =
        virConnectListInterfaces (conn,
                                  ret->names.names_val, args->maxnames);
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_len);
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}

2479 2480 2481 2482
static int
remoteDispatchNumOfDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
2483
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501
                                      remote_error *rerr,
                                      void *args ATTRIBUTE_UNUSED,
                                      remote_num_of_defined_interfaces_ret *ret)
{

    ret->num = virConnectNumOfDefinedInterfaces (conn);
    if (ret->num == -1) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}

static int
remoteDispatchListDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
                                     struct qemud_client *client ATTRIBUTE_UNUSED,
                                     virConnectPtr conn,
2502
                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531
                                     remote_error *rerr,
                                     remote_list_defined_interfaces_args *args,
                                     remote_list_defined_interfaces_ret *ret)
{

    if (args->maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX) {
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX"));
        return -1;
    }

    /* Allocate return buffer. */
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
        remoteDispatchOOMError(rerr);
        return -1;
    }

    ret->names.names_len =
        virConnectListDefinedInterfaces (conn,
                                         ret->names.names_val, args->maxnames);
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_len);
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}

D
Daniel Veillard 已提交
2532 2533 2534 2535
static int
remoteDispatchInterfaceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
                                     struct qemud_client *client ATTRIBUTE_UNUSED,
                                     virConnectPtr conn,
2536
                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
D
Daniel Veillard 已提交
2537 2538 2539 2540
                                     remote_error *rerr,
                                     remote_interface_lookup_by_name_args *args,
                                     remote_interface_lookup_by_name_ret *ret)
{
2541
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2542

2543 2544
    iface = virInterfaceLookupByName (conn, args->name);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2545 2546 2547 2548
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

2549 2550
    make_nonnull_interface (&ret->iface, iface);
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2551 2552 2553 2554 2555 2556 2557
    return 0;
}

static int
remoteDispatchInterfaceLookupByMacString (struct qemud_server *server ATTRIBUTE_UNUSED,
                                          struct qemud_client *client ATTRIBUTE_UNUSED,
                                          virConnectPtr conn,
2558
                                          remote_message_header *hdr ATTRIBUTE_UNUSED,
D
Daniel Veillard 已提交
2559 2560 2561 2562
                                          remote_error *rerr,
                                          remote_interface_lookup_by_mac_string_args *args,
                                          remote_interface_lookup_by_mac_string_ret *ret)
{
2563
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2564

2565 2566
    iface = virInterfaceLookupByMACString (conn, args->mac);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2567 2568 2569 2570
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

2571 2572
    make_nonnull_interface (&ret->iface, iface);
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2573 2574 2575 2576 2577 2578 2579
    return 0;
}

static int
remoteDispatchInterfaceGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
2580
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
D
Daniel Veillard 已提交
2581 2582 2583 2584
                                   remote_error *rerr,
                                   remote_interface_get_xml_desc_args *args,
                                   remote_interface_get_xml_desc_ret *ret)
{
2585
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2586

2587 2588
    iface = get_nonnull_interface (conn, args->iface);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2589 2590 2591 2592 2593
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    /* remoteDispatchClientRequest will free this. */
2594
    ret->xml = virInterfaceGetXMLDesc (iface, args->flags);
D
Daniel Veillard 已提交
2595
    if (!ret->xml) {
2596
        virInterfaceFree(iface);
D
Daniel Veillard 已提交
2597 2598 2599
        remoteDispatchConnError(rerr, conn);
        return -1;
    }
2600
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2601 2602 2603 2604 2605 2606 2607
    return 0;
}

static int
remoteDispatchInterfaceDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
2608
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
D
Daniel Veillard 已提交
2609 2610 2611 2612
                                  remote_error *rerr,
                                  remote_interface_define_xml_args *args,
                                  remote_interface_define_xml_ret *ret)
{
2613
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2614

2615 2616
    iface = virInterfaceDefineXML (conn, args->xml, args->flags);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2617 2618 2619 2620
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

2621 2622
    make_nonnull_interface (&ret->iface, iface);
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2623 2624 2625 2626 2627
    return 0;
}

static int
remoteDispatchInterfaceUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
2628 2629 2630 2631 2632 2633
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
                                 remote_error *rerr,
                                 remote_interface_undefine_args *args,
                                 void *ret ATTRIBUTE_UNUSED)
D
Daniel Veillard 已提交
2634
{
2635
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2636

2637 2638
    iface = get_nonnull_interface (conn, args->iface);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2639 2640 2641 2642
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

2643 2644
    if (virInterfaceUndefine (iface) == -1) {
        virInterfaceFree(iface);
D
Daniel Veillard 已提交
2645 2646 2647
        remoteDispatchConnError(rerr, conn);
        return -1;
    }
2648
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2649 2650 2651 2652 2653
    return 0;
}

static int
remoteDispatchInterfaceCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
2654 2655 2656 2657 2658 2659
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
                               remote_error *rerr,
                               remote_interface_create_args *args,
                               void *ret ATTRIBUTE_UNUSED)
D
Daniel Veillard 已提交
2660
{
2661
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2662

2663 2664
    iface = get_nonnull_interface (conn, args->iface);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2665 2666 2667 2668
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

2669 2670
    if (virInterfaceCreate (iface, args->flags) == -1) {
        virInterfaceFree(iface);
D
Daniel Veillard 已提交
2671 2672 2673
        remoteDispatchConnError(rerr, conn);
        return -1;
    }
2674
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2675 2676 2677 2678 2679
    return 0;
}

static int
remoteDispatchInterfaceDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
2680 2681 2682 2683 2684 2685
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
                                remote_error *rerr,
                                remote_interface_destroy_args *args,
                                void *ret ATTRIBUTE_UNUSED)
D
Daniel Veillard 已提交
2686
{
2687
    virInterfacePtr iface;
D
Daniel Veillard 已提交
2688

2689 2690
    iface = get_nonnull_interface (conn, args->iface);
    if (iface == NULL) {
D
Daniel Veillard 已提交
2691 2692 2693 2694
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

2695 2696
    if (virInterfaceDestroy (iface, args->flags) == -1) {
        virInterfaceFree(iface);
D
Daniel Veillard 已提交
2697 2698 2699
        remoteDispatchConnError(rerr, conn);
        return -1;
    }
2700
    virInterfaceFree(iface);
D
Daniel Veillard 已提交
2701 2702 2703 2704 2705
    return 0;
}

/*-------------------------------------------------------------*/

2706
static int
2707
remoteDispatchAuthList (struct qemud_server *server,
2708
                        struct qemud_client *client,
2709
                        virConnectPtr conn ATTRIBUTE_UNUSED,
2710
                        remote_message_header *hdr ATTRIBUTE_UNUSED,
2711
                        remote_error *rerr,
2712 2713 2714 2715
                        void *args ATTRIBUTE_UNUSED,
                        remote_auth_list_ret *ret)
{
    ret->types.types_len = 1;
2716
    if (VIR_ALLOC_N(ret->types.types_val, ret->types.types_len) < 0) {
2717 2718
        remoteDispatchOOMError(rerr);
        return -1;
2719
    }
2720 2721 2722
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
2723
    ret->types.types_val[0] = client->auth;
2724
    virMutexUnlock(&client->lock);
2725

2726 2727 2728 2729 2730 2731 2732 2733
    return 0;
}


#if HAVE_SASL
/*
 * NB, keep in sync with similar method in src/remote_internal.c
 */
2734
static char *addrToString(remote_error *rerr,
2735 2736 2737 2738 2739 2740 2741 2742 2743
                          struct sockaddr_storage *sa, socklen_t salen) {
    char host[1024], port[20];
    char *addr;
    int err;

    if ((err = getnameinfo((struct sockaddr *)sa, salen,
                           host, sizeof(host),
                           port, sizeof(port),
                           NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
2744 2745 2746
        remoteDispatchFormatError(rerr,
                                  _("Cannot resolve address %d: %s"),
                                  err, gai_strerror(err));
2747 2748 2749
        return NULL;
    }

2750 2751
    if (virAsprintf(&addr, "%s;%s", host, port) == -1) {
        virReportOOMError(NULL);
2752 2753 2754 2755 2756 2757 2758 2759 2760
        return NULL;
    }

    return addr;
}


/*
 * Initializes the SASL session in prepare for authentication
2761
 * and gives the client a list of allowed mechanisms to choose
2762 2763 2764 2765
 *
 * XXX callbacks for stuff like password verification ?
 */
static int
2766
remoteDispatchAuthSaslInit (struct qemud_server *server,
2767
                            struct qemud_client *client,
2768
                            virConnectPtr conn ATTRIBUTE_UNUSED,
2769
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
2770
                            remote_error *rerr,
2771 2772 2773 2774
                            void *args ATTRIBUTE_UNUSED,
                            remote_auth_sasl_init_ret *ret)
{
    const char *mechlist = NULL;
2775
    sasl_security_properties_t secprops;
2776 2777 2778 2779 2780
    int err;
    struct sockaddr_storage sa;
    socklen_t salen;
    char *localAddr, *remoteAddr;

2781 2782 2783
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
2784

2785 2786 2787
    REMOTE_DEBUG("Initialize SASL auth %d", client->fd);
    if (client->auth != REMOTE_AUTH_SASL ||
        client->saslconn != NULL) {
2788
        VIR_ERROR0(_("client tried invalid SASL init request"));
2789
        goto authfail;
2790 2791 2792 2793 2794
    }

    /* Get local address in form  IPADDR:PORT */
    salen = sizeof(sa);
    if (getsockname(client->fd, (struct sockaddr*)&sa, &salen) < 0) {
2795
        char ebuf[1024];
2796
        remoteDispatchFormatError(rerr,
2797
                                  _("failed to get sock address: %s"),
2798
                                  virStrerror(errno, ebuf, sizeof ebuf));
2799
        goto error;
2800
    }
2801
    if ((localAddr = addrToString(rerr, &sa, salen)) == NULL) {
2802
        goto error;
2803 2804 2805 2806 2807
    }

    /* Get remote address in form  IPADDR:PORT */
    salen = sizeof(sa);
    if (getpeername(client->fd, (struct sockaddr*)&sa, &salen) < 0) {
2808
        char ebuf[1024];
2809
        remoteDispatchFormatError(rerr, _("failed to get peer address: %s"),
2810
                                  virStrerror(errno, ebuf, sizeof ebuf));
2811
        VIR_FREE(localAddr);
2812
        goto error;
2813
    }
2814
    if ((remoteAddr = addrToString(rerr, &sa, salen)) == NULL) {
2815
        VIR_FREE(localAddr);
2816
        goto error;
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826
    }

    err = sasl_server_new("libvirt",
                          NULL, /* FQDN - just delegates to gethostname */
                          NULL, /* User realm */
                          localAddr,
                          remoteAddr,
                          NULL, /* XXX Callbacks */
                          SASL_SUCCESS_DATA,
                          &client->saslconn);
2827 2828
    VIR_FREE(localAddr);
    VIR_FREE(remoteAddr);
2829
    if (err != SASL_OK) {
2830 2831
        VIR_ERROR(_("sasl context setup failed %d (%s)"),
                  err, sasl_errstring(err, NULL, NULL));
2832
        client->saslconn = NULL;
2833
        goto authfail;
2834 2835
    }

2836 2837 2838 2839 2840 2841 2842
    /* Inform SASL that we've got an external SSF layer from TLS */
    if (client->type == QEMUD_SOCK_TYPE_TLS) {
        gnutls_cipher_algorithm_t cipher;
        sasl_ssf_t ssf;

        cipher = gnutls_cipher_get(client->tlssession);
        if (!(ssf = (sasl_ssf_t)gnutls_cipher_get_key_size(cipher))) {
D
Daniel Veillard 已提交
2843
            VIR_ERROR0(_("cannot get TLS cipher size"));
2844 2845
            sasl_dispose(&client->saslconn);
            client->saslconn = NULL;
2846
            goto authfail;
2847 2848 2849 2850 2851
        }
        ssf *= 8; /* tls key size is bytes, sasl wants bits */

        err = sasl_setprop(client->saslconn, SASL_SSF_EXTERNAL, &ssf);
        if (err != SASL_OK) {
2852 2853
            VIR_ERROR(_("cannot set SASL external SSF %d (%s)"),
                      err, sasl_errstring(err, NULL, NULL));
2854 2855
            sasl_dispose(&client->saslconn);
            client->saslconn = NULL;
2856
            goto authfail;
2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879
        }
    }

    memset (&secprops, 0, sizeof secprops);
    if (client->type == QEMUD_SOCK_TYPE_TLS ||
        client->type == QEMUD_SOCK_TYPE_UNIX) {
        /* If we've got TLS or UNIX domain sock, we don't care about SSF */
        secprops.min_ssf = 0;
        secprops.max_ssf = 0;
        secprops.maxbufsize = 8192;
        secprops.security_flags = 0;
    } else {
        /* Plain TCP, better get an SSF layer */
        secprops.min_ssf = 56; /* Good enough to require kerberos */
        secprops.max_ssf = 100000; /* Arbitrary big number */
        secprops.maxbufsize = 8192;
        /* Forbid any anonymous or trivially crackable auth */
        secprops.security_flags =
            SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT;
    }

    err = sasl_setprop(client->saslconn, SASL_SEC_PROPS, &secprops);
    if (err != SASL_OK) {
2880 2881
        VIR_ERROR(_("cannot set SASL security props %d (%s)"),
                  err, sasl_errstring(err, NULL, NULL));
2882 2883
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
2884
        goto authfail;
2885 2886
    }

2887 2888 2889 2890 2891 2892 2893 2894 2895
    err = sasl_listmech(client->saslconn,
                        NULL, /* Don't need to set user */
                        "", /* Prefix */
                        ",", /* Separator */
                        "", /* Suffix */
                        &mechlist,
                        NULL,
                        NULL);
    if (err != SASL_OK) {
2896 2897
        VIR_ERROR(_("cannot list SASL mechanisms %d (%s)"),
                  err, sasl_errdetail(client->saslconn));
2898 2899
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
2900
        goto authfail;
2901 2902 2903 2904
    }
    REMOTE_DEBUG("Available mechanisms for client: '%s'", mechlist);
    ret->mechlist = strdup(mechlist);
    if (!ret->mechlist) {
2905
        VIR_ERROR0(_("cannot allocate mechlist"));
2906 2907
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
2908
        goto authfail;
2909 2910
    }

2911
    virMutexUnlock(&client->lock);
2912
    return 0;
2913 2914 2915 2916

authfail:
    remoteDispatchAuthError(rerr);
error:
2917
    virMutexUnlock(&client->lock);
2918
    return -1;
2919 2920 2921
}


2922
/* We asked for an SSF layer, so sanity check that we actually
2923 2924 2925
 * got what we asked for */
static int
remoteSASLCheckSSF (struct qemud_client *client,
2926
                    remote_error *rerr) {
2927 2928 2929 2930 2931 2932 2933 2934 2935
    const void *val;
    int err, ssf;

    if (client->type == QEMUD_SOCK_TYPE_TLS ||
        client->type == QEMUD_SOCK_TYPE_UNIX)
        return 0; /* TLS or UNIX domain sockets trivially OK */

    err = sasl_getprop(client->saslconn, SASL_SSF, &val);
    if (err != SASL_OK) {
2936 2937
        VIR_ERROR(_("cannot query SASL ssf on connection %d (%s)"),
                  err, sasl_errstring(err, NULL, NULL));
2938
        remoteDispatchAuthError(rerr);
2939 2940 2941 2942 2943 2944 2945
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
        return -1;
    }
    ssf = *(const int *)val;
    REMOTE_DEBUG("negotiated an SSF of %d", ssf);
    if (ssf < 56) { /* 56 is good for Kerberos */
2946
        VIR_ERROR(_("negotiated SSF %d was not strong enough"), ssf);
2947
        remoteDispatchAuthError(rerr);
2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
        return -1;
    }

    /* Only setup for read initially, because we're about to send an RPC
     * reply which must be in plain text. When the next incoming RPC
     * arrives, we'll switch on writes too
     *
     * cf qemudClientReadSASL  in qemud.c
     */
    client->saslSSF = QEMUD_SASL_SSF_READ;

    /* We have a SSF !*/
    return 0;
}

2965 2966 2967
static int
remoteSASLCheckAccess (struct qemud_server *server,
                       struct qemud_client *client,
2968
                       remote_error *rerr) {
2969 2970 2971 2972 2973 2974
    const void *val;
    int err;
    char **wildcards;

    err = sasl_getprop(client->saslconn, SASL_USERNAME, &val);
    if (err != SASL_OK) {
2975 2976
        VIR_ERROR(_("cannot query SASL username on connection %d (%s)"),
                  err, sasl_errstring(err, NULL, NULL));
2977
        remoteDispatchAuthError(rerr);
2978 2979 2980 2981 2982
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
        return -1;
    }
    if (val == NULL) {
2983
        VIR_ERROR0(_("no client username was found"));
2984
        remoteDispatchAuthError(rerr);
2985 2986 2987 2988 2989 2990 2991 2992
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
        return -1;
    }
    REMOTE_DEBUG("SASL client username %s", (const char *)val);

    client->saslUsername = strdup((const char*)val);
    if (client->saslUsername == NULL) {
2993
        VIR_ERROR0(_("out of memory copying username"));
2994
        remoteDispatchAuthError(rerr);
2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
        return -1;
    }

    /* If the list is not set, allow any DN. */
    wildcards = server->saslUsernameWhitelist;
    if (!wildcards)
        return 0; /* No ACL, allow all */

    while (*wildcards) {
        if (fnmatch (*wildcards, client->saslUsername, 0) == 0)
            return 0; /* Allowed */
        wildcards++;
    }

    /* Denied */
3012
    VIR_ERROR(_("SASL client %s not allowed in whitelist"), client->saslUsername);
3013
    remoteDispatchAuthError(rerr);
3014 3015 3016 3017 3018 3019
    sasl_dispose(&client->saslconn);
    client->saslconn = NULL;
    return -1;
}


3020 3021 3022 3023
/*
 * This starts the SASL authentication negotiation.
 */
static int
3024 3025
remoteDispatchAuthSaslStart (struct qemud_server *server,
                             struct qemud_client *client,
3026
                             virConnectPtr conn ATTRIBUTE_UNUSED,
3027
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
3028
                             remote_error *rerr,
3029 3030 3031 3032 3033 3034 3035
                             remote_auth_sasl_start_args *args,
                             remote_auth_sasl_start_ret *ret)
{
    const char *serverout;
    unsigned int serveroutlen;
    int err;

3036 3037 3038
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
3039

3040 3041 3042
    REMOTE_DEBUG("Start SASL auth %d", client->fd);
    if (client->auth != REMOTE_AUTH_SASL ||
        client->saslconn == NULL) {
3043
        VIR_ERROR0(_("client tried invalid SASL start request"));
3044
        goto authfail;
3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057
    }

    REMOTE_DEBUG("Using SASL mechanism %s. Data %d bytes, nil: %d",
                 args->mech, args->data.data_len, args->nil);
    err = sasl_server_start(client->saslconn,
                            args->mech,
                            /* NB, distinction of NULL vs "" is *critical* in SASL */
                            args->nil ? NULL : args->data.data_val,
                            args->data.data_len,
                            &serverout,
                            &serveroutlen);
    if (err != SASL_OK &&
        err != SASL_CONTINUE) {
3058 3059
        VIR_ERROR(_("sasl start failed %d (%s)"),
                  err, sasl_errdetail(client->saslconn));
3060 3061
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
3062
        goto authfail;
3063 3064
    }
    if (serveroutlen > REMOTE_AUTH_SASL_DATA_MAX) {
3065
        VIR_ERROR(_("sasl start reply data too long %d"), serveroutlen);
3066 3067
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
3068
        goto authfail;
3069 3070 3071 3072
    }

    /* NB, distinction of NULL vs "" is *critical* in SASL */
    if (serverout) {
3073
        if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0) {
3074
            remoteDispatchOOMError(rerr);
3075
            goto error;
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087
        }
        memcpy(ret->data.data_val, serverout, serveroutlen);
    } else {
        ret->data.data_val = NULL;
    }
    ret->nil = serverout ? 0 : 1;
    ret->data.data_len = serveroutlen;

    REMOTE_DEBUG("SASL return data %d bytes, nil; %d", ret->data.data_len, ret->nil);
    if (err == SASL_CONTINUE) {
        ret->complete = 0;
    } else {
3088
        if (remoteSASLCheckSSF(client, rerr) < 0)
3089
            goto error;
3090

3091
        /* Check username whitelist ACL */
3092
        if (remoteSASLCheckAccess(server, client, rerr) < 0)
3093
            goto error;
3094

3095 3096 3097 3098 3099
        REMOTE_DEBUG("Authentication successful %d", client->fd);
        ret->complete = 1;
        client->auth = REMOTE_AUTH_NONE;
    }

3100
    virMutexUnlock(&client->lock);
3101
    return 0;
3102 3103 3104 3105

authfail:
    remoteDispatchAuthError(rerr);
error:
3106
    virMutexUnlock(&client->lock);
3107
    return -1;
3108 3109 3110 3111
}


static int
3112 3113
remoteDispatchAuthSaslStep (struct qemud_server *server,
                            struct qemud_client *client,
3114
                            virConnectPtr conn ATTRIBUTE_UNUSED,
3115
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
3116
                            remote_error *rerr,
3117 3118 3119 3120 3121 3122 3123
                            remote_auth_sasl_step_args *args,
                            remote_auth_sasl_step_ret *ret)
{
    const char *serverout;
    unsigned int serveroutlen;
    int err;

3124 3125 3126
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
3127

3128 3129 3130
    REMOTE_DEBUG("Step SASL auth %d", client->fd);
    if (client->auth != REMOTE_AUTH_SASL ||
        client->saslconn == NULL) {
3131
        VIR_ERROR0(_("client tried invalid SASL start request"));
3132
        goto authfail;
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144
    }

    REMOTE_DEBUG("Using SASL Data %d bytes, nil: %d",
                 args->data.data_len, args->nil);
    err = sasl_server_step(client->saslconn,
                           /* NB, distinction of NULL vs "" is *critical* in SASL */
                           args->nil ? NULL : args->data.data_val,
                           args->data.data_len,
                           &serverout,
                           &serveroutlen);
    if (err != SASL_OK &&
        err != SASL_CONTINUE) {
3145 3146
        VIR_ERROR(_("sasl step failed %d (%s)"),
                  err, sasl_errdetail(client->saslconn));
3147 3148
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
3149
        goto authfail;
3150 3151 3152
    }

    if (serveroutlen > REMOTE_AUTH_SASL_DATA_MAX) {
3153 3154
        VIR_ERROR(_("sasl step reply data too long %d"),
                  serveroutlen);
3155 3156
        sasl_dispose(&client->saslconn);
        client->saslconn = NULL;
3157
        goto authfail;
3158 3159 3160 3161
    }

    /* NB, distinction of NULL vs "" is *critical* in SASL */
    if (serverout) {
3162
        if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0) {
3163
            remoteDispatchOOMError(rerr);
3164
            goto error;
3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176
        }
        memcpy(ret->data.data_val, serverout, serveroutlen);
    } else {
        ret->data.data_val = NULL;
    }
    ret->nil = serverout ? 0 : 1;
    ret->data.data_len = serveroutlen;

    REMOTE_DEBUG("SASL return data %d bytes, nil; %d", ret->data.data_len, ret->nil);
    if (err == SASL_CONTINUE) {
        ret->complete = 0;
    } else {
3177
        if (remoteSASLCheckSSF(client, rerr) < 0)
3178
            goto error;
3179

3180
        /* Check username whitelist ACL */
3181
        if (remoteSASLCheckAccess(server, client, rerr) < 0)
3182
            goto error;
3183

3184 3185 3186 3187 3188
        REMOTE_DEBUG("Authentication successful %d", client->fd);
        ret->complete = 1;
        client->auth = REMOTE_AUTH_NONE;
    }

3189
    virMutexUnlock(&client->lock);
3190
    return 0;
3191 3192 3193 3194

authfail:
    remoteDispatchAuthError(rerr);
error:
3195
    virMutexUnlock(&client->lock);
3196
    return -1;
3197 3198 3199 3200 3201
}


#else /* HAVE_SASL */
static int
3202
remoteDispatchAuthSaslInit (struct qemud_server *server ATTRIBUTE_UNUSED,
3203 3204
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn ATTRIBUTE_UNUSED,
3205
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
3206
                            remote_error *rerr,
3207 3208 3209
                            void *args ATTRIBUTE_UNUSED,
                            remote_auth_sasl_init_ret *ret ATTRIBUTE_UNUSED)
{
3210
    VIR_ERROR0(_("client tried unsupported SASL init request"));
3211
    remoteDispatchAuthError(rerr);
3212 3213 3214 3215
    return -1;
}

static int
3216
remoteDispatchAuthSaslStart (struct qemud_server *server ATTRIBUTE_UNUSED,
3217 3218
                             struct qemud_client *client ATTRIBUTE_UNUSED,
                             virConnectPtr conn ATTRIBUTE_UNUSED,
3219
                             remote_message_header *hdr ATTRIBUTE_UNUSED,
3220
                             remote_error *rerr,
3221 3222 3223
                             remote_auth_sasl_start_args *args ATTRIBUTE_UNUSED,
                             remote_auth_sasl_start_ret *ret ATTRIBUTE_UNUSED)
{
3224
    VIR_ERROR0(_("client tried unsupported SASL start request"));
3225
    remoteDispatchAuthError(rerr);
3226 3227 3228 3229
    return -1;
}

static int
3230
remoteDispatchAuthSaslStep (struct qemud_server *server ATTRIBUTE_UNUSED,
3231 3232
                            struct qemud_client *client ATTRIBUTE_UNUSED,
                            virConnectPtr conn ATTRIBUTE_UNUSED,
3233
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
3234
                            remote_error *rerr,
3235 3236 3237
                            remote_auth_sasl_step_args *args ATTRIBUTE_UNUSED,
                            remote_auth_sasl_step_ret *ret ATTRIBUTE_UNUSED)
{
3238
    VIR_ERROR0(_("client tried unsupported SASL step request"));
3239
    remoteDispatchAuthError(rerr);
3240 3241 3242 3243 3244
    return -1;
}
#endif /* HAVE_SASL */


3245 3246 3247 3248 3249
#if HAVE_POLKIT1
static int
remoteDispatchAuthPolkit (struct qemud_server *server,
                          struct qemud_client *client,
                          virConnectPtr conn ATTRIBUTE_UNUSED,
3250
                          remote_message_header *hdr ATTRIBUTE_UNUSED,
3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
                          remote_error *rerr,
                          void *args ATTRIBUTE_UNUSED,
                          remote_auth_polkit_ret *ret)
{
    pid_t callerPid;
    uid_t callerUid;
    const char *action;
    int status = -1;
    char pidbuf[50];
    int rv;

    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);

    action = client->readonly ?
        "org.libvirt.unix.monitor" :
        "org.libvirt.unix.manage";

    const char * const pkcheck [] = {
      PKCHECK_PATH,
      "--action-id", action,
      "--process", pidbuf,
      "--allow-user-interaction",
      NULL
    };

    REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
    if (client->auth != REMOTE_AUTH_POLKIT) {
        VIR_ERROR0(_("client tried invalid PolicyKit init request"));
        goto authfail;
    }

    if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
        VIR_ERROR0(_("cannot get peer socket identity"));
        goto authfail;
    }

    VIR_INFO(_("Checking PID %d running as %d"), callerPid, callerUid);

    rv = snprintf(pidbuf, sizeof pidbuf, "%d", callerPid);
    if (rv < 0 || rv >= sizeof pidbuf) {
        VIR_ERROR(_("Caller PID was too large %d"), callerPid);
3294
        goto authfail;
3295 3296 3297 3298
    }

    if (virRun(NULL, pkcheck, &status) < 0) {
        VIR_ERROR(_("Cannot invoke %s"), PKCHECK_PATH);
3299
        goto authfail;
3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319
    }
    if (status != 0) {
        VIR_ERROR(_("Policy kit denied action %s from pid %d, uid %d, result: %d\n"),
                  action, callerPid, callerUid, status);
        goto authfail;
    }
    VIR_INFO(_("Policy allowed action %s from pid %d, uid %d"),
             action, callerPid, callerUid);
    ret->complete = 1;
    client->auth = REMOTE_AUTH_NONE;

    virMutexUnlock(&client->lock);
    return 0;

authfail:
    remoteDispatchAuthError(rerr);
    virMutexUnlock(&client->lock);
    return -1;
}
#elif HAVE_POLKIT0
3320
static int
3321
remoteDispatchAuthPolkit (struct qemud_server *server,
3322
                          struct qemud_client *client,
3323
                          virConnectPtr conn ATTRIBUTE_UNUSED,
3324
                          remote_message_header *hdr ATTRIBUTE_UNUSED,
3325
                          remote_error *rerr,
3326 3327 3328 3329 3330
                          void *args ATTRIBUTE_UNUSED,
                          remote_auth_polkit_ret *ret)
{
    pid_t callerPid;
    uid_t callerUid;
3331 3332 3333 3334 3335 3336
    PolKitCaller *pkcaller = NULL;
    PolKitAction *pkaction = NULL;
    PolKitContext *pkcontext = NULL;
    PolKitError *pkerr = NULL;
    PolKitResult pkresult;
    DBusError err;
3337 3338
    const char *action;

3339 3340 3341
    virMutexLock(&server->lock);
    virMutexLock(&client->lock);
    virMutexUnlock(&server->lock);
3342 3343

    action = client->readonly ?
3344 3345
        "org.libvirt.unix.monitor" :
        "org.libvirt.unix.manage";
3346 3347 3348

    REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
    if (client->auth != REMOTE_AUTH_POLKIT) {
3349
        VIR_ERROR0(_("client tried invalid PolicyKit init request"));
3350
        goto authfail;
3351 3352 3353
    }

    if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
3354
        VIR_ERROR0(_("cannot get peer socket identity"));
3355
        goto authfail;
3356 3357
    }

3358
    VIR_INFO(_("Checking PID %d running as %d"), callerPid, callerUid);
3359 3360 3361
    dbus_error_init(&err);
    if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
                                                callerPid, &err))) {
3362
        VIR_ERROR(_("Failed to lookup policy kit caller: %s"), err.message);
3363
        dbus_error_free(&err);
3364
        goto authfail;
3365
    }
3366

3367
    if (!(pkaction = polkit_action_new())) {
3368 3369 3370
        char ebuf[1024];
        VIR_ERROR(_("Failed to create polkit action %s\n"),
                  virStrerror(errno, ebuf, sizeof ebuf));
3371
        polkit_caller_unref(pkcaller);
3372
        goto authfail;
3373 3374 3375 3376 3377
    }
    polkit_action_set_action_id(pkaction, action);

    if (!(pkcontext = polkit_context_new()) ||
        !polkit_context_init(pkcontext, &pkerr)) {
3378
        char ebuf[1024];
3379 3380
        VIR_ERROR(_("Failed to create polkit context %s\n"),
                  (pkerr ? polkit_error_get_error_message(pkerr)
3381
                   : virStrerror(errno, ebuf, sizeof ebuf)));
3382 3383 3384 3385 3386
        if (pkerr)
            polkit_error_free(pkerr);
        polkit_caller_unref(pkcaller);
        polkit_action_unref(pkaction);
        dbus_error_free(&err);
3387
        goto authfail;
3388
    }
3389

3390
#if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
3391 3392 3393 3394 3395 3396
    pkresult = polkit_context_is_caller_authorized(pkcontext,
                                                   pkaction,
                                                   pkcaller,
                                                   0,
                                                   &pkerr);
    if (pkerr && polkit_error_is_set(pkerr)) {
3397 3398 3399
        VIR_ERROR(_("Policy kit failed to check authorization %d %s"),
                  polkit_error_get_error_code(pkerr),
                  polkit_error_get_error_message(pkerr));
3400
        goto authfail;
3401
    }
3402
#else
3403 3404 3405
    pkresult = polkit_context_can_caller_do_action(pkcontext,
                                                   pkaction,
                                                   pkcaller);
3406
#endif
3407 3408 3409 3410
    polkit_context_unref(pkcontext);
    polkit_caller_unref(pkcaller);
    polkit_action_unref(pkaction);
    if (pkresult != POLKIT_RESULT_YES) {
3411 3412 3413
        VIR_ERROR(_("Policy kit denied action %s from pid %d, uid %d, result: %s\n"),
                  action, callerPid, callerUid,
                  polkit_result_to_string_representation(pkresult));
3414
        goto authfail;
3415
    }
3416
    VIR_INFO(_("Policy allowed action %s from pid %d, uid %d, result %s"),
3417 3418 3419 3420
             action, callerPid, callerUid,
             polkit_result_to_string_representation(pkresult));
    ret->complete = 1;
    client->auth = REMOTE_AUTH_NONE;
3421

3422
    virMutexUnlock(&client->lock);
3423
    return 0;
3424 3425 3426

authfail:
    remoteDispatchAuthError(rerr);
3427
    virMutexUnlock(&client->lock);
3428
    return -1;
3429 3430
}

3431
#else /* !HAVE_POLKIT0 & !HAVE_POLKIT1*/
3432 3433

static int
3434
remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
3435
                          struct qemud_client *client ATTRIBUTE_UNUSED,
3436
                          virConnectPtr conn ATTRIBUTE_UNUSED,
3437
                          remote_message_header *hdr ATTRIBUTE_UNUSED,
3438 3439 3440
                          remote_error *rerr,
                          void *args ATTRIBUTE_UNUSED,
                          remote_auth_polkit_ret *ret ATTRIBUTE_UNUSED)
3441
{
3442
    VIR_ERROR0(_("client tried unsupported PolicyKit init request"));
3443
    remoteDispatchAuthError(rerr);
3444 3445
    return -1;
}
3446
#endif /* HAVE_POLKIT1 */
3447

3448 3449 3450 3451 3452 3453 3454 3455

/***************************************************************
 *     STORAGE POOL APIS
 ***************************************************************/


static int
remoteDispatchListDefinedStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
3456 3457
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
3458
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
3459
                                       remote_error *rerr,
3460 3461 3462 3463 3464
                                       remote_list_defined_storage_pools_args *args,
                                       remote_list_defined_storage_pools_ret *ret)
{

    if (args->maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
3465 3466
        remoteDispatchFormatError (rerr, "%s",
                            _("maxnames > REMOTE_NETWORK_NAME_LIST_MAX"));
3467
        return -1;
3468 3469 3470
    }

    /* Allocate return buffer. */
3471
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
3472 3473
        remoteDispatchOOMError(rerr);
        return -1;
3474
    }
3475 3476

    ret->names.names_len =
3477
        virConnectListDefinedStoragePools (conn,
3478 3479 3480
                                           ret->names.names_val, args->maxnames);
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_val);
3481
        remoteDispatchConnError(rerr, conn);
3482 3483
        return -1;
    }
3484 3485 3486 3487 3488 3489

    return 0;
}

static int
remoteDispatchListStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
3490 3491
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
3492
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
3493
                                remote_error *rerr,
3494 3495 3496 3497 3498
                                remote_list_storage_pools_args *args,
                                remote_list_storage_pools_ret *ret)
{

    if (args->maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
3499 3500 3501
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX"));
        return -1;
3502 3503 3504
    }

    /* Allocate return buffer. */
3505
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
3506 3507
        remoteDispatchOOMError(rerr);
        return -1;
3508
    }
3509 3510

    ret->names.names_len =
3511
        virConnectListStoragePools (conn,
3512
                                ret->names.names_val, args->maxnames);
3513 3514
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_val);
3515
        remoteDispatchConnError(rerr, conn);
3516 3517
        return -1;
    }
3518 3519 3520 3521

    return 0;
}

3522 3523
static int
remoteDispatchFindStoragePoolSources (struct qemud_server *server ATTRIBUTE_UNUSED,
3524 3525
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
3526
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
3527
                                      remote_error *rerr,
3528 3529 3530 3531
                                      remote_find_storage_pool_sources_args *args,
                                      remote_find_storage_pool_sources_ret *ret)
{
    ret->xml =
3532
        virConnectFindStoragePoolSources (conn,
3533 3534 3535
                                          args->type,
                                          args->srcSpec ? *args->srcSpec : NULL,
                                          args->flags);
3536
    if (ret->xml == NULL) {
3537
        remoteDispatchConnError(rerr, conn);
3538
        return -1;
3539
    }
3540 3541 3542 3543 3544

    return 0;
}


3545 3546
static int
remoteDispatchStoragePoolCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
3547 3548
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
3549
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
3550
                                 remote_error *rerr,
3551 3552 3553 3554 3555
                                 remote_storage_pool_create_args *args,
                                 void *ret ATTRIBUTE_UNUSED)
{
    virStoragePoolPtr pool;

3556
    pool = get_nonnull_storage_pool (conn, args->pool);
3557
    if (pool == NULL) {
3558
        remoteDispatchConnError(rerr, conn);
3559
        return -1;
3560 3561 3562 3563
    }

    if (virStoragePoolCreate (pool, args->flags) == -1) {
        virStoragePoolFree(pool);
3564
        remoteDispatchConnError(rerr, conn);
3565 3566 3567 3568 3569 3570 3571 3572
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
3573 3574
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
3575
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
3576
                                    remote_error *rerr,
3577 3578 3579 3580 3581
                                    remote_storage_pool_create_xml_args *args,
                                    remote_storage_pool_create_xml_ret *ret)
{
    virStoragePoolPtr pool;

3582
    pool = virStoragePoolCreateXML (conn, args->xml, args->flags);
3583
    if (pool == NULL) {
3584
        remoteDispatchConnError(rerr, conn);
3585 3586
        return -1;
    }
3587 3588 3589 3590 3591 3592 3593 3594

    make_nonnull_storage_pool (&ret->pool, pool);
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
3595 3596
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
3597
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
3598
                                    remote_error *rerr,
3599 3600 3601 3602 3603
                                    remote_storage_pool_define_xml_args *args,
                                    remote_storage_pool_define_xml_ret *ret)
{
    virStoragePoolPtr pool;

3604
    pool = virStoragePoolDefineXML (conn, args->xml, args->flags);
3605
    if (pool == NULL) {
3606
        remoteDispatchConnError(rerr, conn);
3607 3608
        return -1;
    }
3609 3610 3611 3612 3613 3614 3615 3616

    make_nonnull_storage_pool (&ret->pool, pool);
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolBuild (struct qemud_server *server ATTRIBUTE_UNUSED,
3617 3618
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
3619
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
3620 3621 3622
                                remote_error *rerr,
                                remote_storage_pool_build_args *args,
                                void *ret ATTRIBUTE_UNUSED)
3623 3624 3625
{
    virStoragePoolPtr pool;

3626
    pool = get_nonnull_storage_pool (conn, args->pool);
3627
    if (pool == NULL) {
3628
        remoteDispatchConnError(rerr, conn);
3629
        return -1;
3630 3631 3632 3633
    }

    if (virStoragePoolBuild (pool, args->flags) == -1) {
        virStoragePoolFree(pool);
3634
        remoteDispatchConnError(rerr, conn);
3635 3636 3637 3638 3639 3640 3641 3642 3643
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}


static int
remoteDispatchStoragePoolDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
3644 3645
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
3646
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
3647
                                  remote_error *rerr,
3648 3649 3650 3651 3652
                                  remote_storage_pool_destroy_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virStoragePoolPtr pool;

3653
    pool = get_nonnull_storage_pool (conn, args->pool);
3654
    if (pool == NULL) {
3655
        remoteDispatchConnError(rerr, conn);
3656
        return -1;
3657 3658 3659 3660
    }

    if (virStoragePoolDestroy (pool) == -1) {
        virStoragePoolFree(pool);
3661
        remoteDispatchConnError(rerr, conn);
3662 3663 3664 3665 3666 3667 3668 3669
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
3670 3671
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
3672
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
3673
                                 remote_error *rerr,
3674 3675 3676 3677 3678
                                 remote_storage_pool_delete_args *args,
                                 void *ret ATTRIBUTE_UNUSED)
{
    virStoragePoolPtr pool;

3679
    pool = get_nonnull_storage_pool (conn, args->pool);
3680
    if (pool == NULL) {
3681
        remoteDispatchConnError(rerr, conn);
3682
        return -1;
3683 3684 3685 3686
    }

    if (virStoragePoolDelete (pool, args->flags) == -1) {
        virStoragePoolFree(pool);
3687
        remoteDispatchConnError(rerr, conn);
3688 3689 3690 3691 3692 3693 3694 3695
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolRefresh (struct qemud_server *server ATTRIBUTE_UNUSED,
3696 3697
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
3698
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
3699
                                  remote_error *rerr,
3700 3701 3702 3703 3704
                                  remote_storage_pool_refresh_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virStoragePoolPtr pool;

3705
    pool = get_nonnull_storage_pool (conn, args->pool);
3706
    if (pool == NULL) {
3707
        remoteDispatchConnError(rerr, conn);
3708
        return -1;
3709 3710 3711 3712
    }

    if (virStoragePoolRefresh (pool, args->flags) == -1) {
        virStoragePoolFree(pool);
3713
        remoteDispatchConnError(rerr, conn);
3714 3715 3716 3717 3718 3719 3720 3721
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
3722 3723
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
3724
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
3725
                                  remote_error *rerr,
3726 3727 3728 3729 3730 3731
                                  remote_storage_pool_get_info_args *args,
                                  remote_storage_pool_get_info_ret *ret)
{
    virStoragePoolPtr pool;
    virStoragePoolInfo info;

3732
    pool = get_nonnull_storage_pool (conn, args->pool);
3733
    if (pool == NULL) {
3734
        remoteDispatchConnError(rerr, conn);
3735
        return -1;
3736 3737 3738 3739
    }

    if (virStoragePoolGetInfo (pool, &info) == -1) {
        virStoragePoolFree(pool);
3740
        remoteDispatchConnError(rerr, conn);
3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755
        return -1;
    }

    ret->state = info.state;
    ret->capacity = info.capacity;
    ret->allocation = info.allocation;
    ret->available = info.available;

    virStoragePoolFree(pool);

    return 0;
}

static int
remoteDispatchStoragePoolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
3756 3757
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
3758
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
3759
                                  remote_error *rerr,
3760 3761 3762 3763 3764
                                  remote_storage_pool_dump_xml_args *args,
                                  remote_storage_pool_dump_xml_ret *ret)
{
    virStoragePoolPtr pool;

3765
    pool = get_nonnull_storage_pool (conn, args->pool);
3766
    if (pool == NULL) {
3767
        remoteDispatchConnError(rerr, conn);
3768
        return -1;
3769 3770 3771 3772 3773 3774
    }

    /* remoteDispatchClientRequest will free this. */
    ret->xml = virStoragePoolGetXMLDesc (pool, args->flags);
    if (!ret->xml) {
        virStoragePoolFree(pool);
3775
        remoteDispatchConnError(rerr, conn);
3776 3777 3778 3779 3780 3781 3782 3783
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolGetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
3784 3785
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
3786
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
3787
                                       remote_error *rerr,
3788 3789 3790 3791 3792
                                       remote_storage_pool_get_autostart_args *args,
                                       remote_storage_pool_get_autostart_ret *ret)
{
    virStoragePoolPtr pool;

3793
    pool = get_nonnull_storage_pool (conn, args->pool);
3794
    if (pool == NULL) {
3795
        remoteDispatchConnError(rerr, conn);
3796
        return -1;
3797 3798 3799 3800
    }

    if (virStoragePoolGetAutostart (pool, &ret->autostart) == -1) {
        virStoragePoolFree(pool);
3801
        remoteDispatchConnError(rerr, conn);
3802 3803 3804 3805 3806 3807 3808 3809 3810
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}


static int
remoteDispatchStoragePoolLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
3811 3812
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
3813
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
3814
                                       remote_error *rerr,
3815 3816 3817 3818 3819
                                       remote_storage_pool_lookup_by_name_args *args,
                                       remote_storage_pool_lookup_by_name_ret *ret)
{
    virStoragePoolPtr pool;

3820
    pool = virStoragePoolLookupByName (conn, args->name);
3821
    if (pool == NULL) {
3822
        remoteDispatchConnError(rerr, conn);
3823 3824
        return -1;
    }
3825 3826 3827 3828 3829 3830 3831 3832

    make_nonnull_storage_pool (&ret->pool, pool);
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
3833 3834
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
3835
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
3836
                                       remote_error *rerr,
3837 3838 3839 3840 3841
                                       remote_storage_pool_lookup_by_uuid_args *args,
                                       remote_storage_pool_lookup_by_uuid_ret *ret)
{
    virStoragePoolPtr pool;

3842
    pool = virStoragePoolLookupByUUID (conn, (unsigned char *) args->uuid);
3843
    if (pool == NULL) {
3844
        remoteDispatchConnError(rerr, conn);
3845 3846
        return -1;
    }
3847 3848 3849 3850 3851 3852 3853 3854

    make_nonnull_storage_pool (&ret->pool, pool);
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolLookupByVolume (struct qemud_server *server ATTRIBUTE_UNUSED,
3855 3856
                                         struct qemud_client *client ATTRIBUTE_UNUSED,
                                         virConnectPtr conn,
3857
                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
3858
                                         remote_error *rerr,
3859 3860 3861 3862 3863 3864
                                         remote_storage_pool_lookup_by_volume_args *args,
                                         remote_storage_pool_lookup_by_volume_ret *ret)
{
    virStoragePoolPtr pool;
    virStorageVolPtr vol;

3865
    vol = get_nonnull_storage_vol (conn, args->vol);
3866
    if (vol == NULL) {
3867
        remoteDispatchConnError(rerr, conn);
3868 3869
        return -1;
    }
3870 3871 3872

    pool = virStoragePoolLookupByVolume (vol);
    virStorageVolFree(vol);
3873
    if (pool == NULL) {
3874
        remoteDispatchConnError(rerr, conn);
3875 3876
        return -1;
    }
3877 3878 3879 3880 3881 3882 3883 3884

    make_nonnull_storage_pool (&ret->pool, pool);
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolSetAutostart (struct qemud_server *server ATTRIBUTE_UNUSED,
3885 3886
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
3887
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
3888
                                       remote_error *rerr,
3889 3890 3891 3892 3893
                                       remote_storage_pool_set_autostart_args *args,
                                       void *ret ATTRIBUTE_UNUSED)
{
    virStoragePoolPtr pool;

3894
    pool = get_nonnull_storage_pool (conn, args->pool);
3895
    if (pool == NULL) {
3896
        remoteDispatchConnError(rerr, conn);
3897
        return -1;
3898 3899 3900 3901
    }

    if (virStoragePoolSetAutostart (pool, args->autostart) == -1) {
        virStoragePoolFree(pool);
3902
        remoteDispatchConnError(rerr, conn);
3903 3904 3905 3906 3907 3908 3909 3910
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchStoragePoolUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
3911 3912
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
3913
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
3914
                                   remote_error *rerr,
3915 3916 3917 3918 3919
                                   remote_storage_pool_undefine_args *args,
                                   void *ret ATTRIBUTE_UNUSED)
{
    virStoragePoolPtr pool;

3920
    pool = get_nonnull_storage_pool (conn, args->pool);
3921
    if (pool == NULL) {
3922
        remoteDispatchConnError(rerr, conn);
3923
        return -1;
3924 3925 3926 3927
    }

    if (virStoragePoolUndefine (pool) == -1) {
        virStoragePoolFree(pool);
3928
        remoteDispatchConnError(rerr, conn);
3929 3930 3931 3932 3933 3934 3935 3936
        return -1;
    }
    virStoragePoolFree(pool);
    return 0;
}

static int
remoteDispatchNumOfStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
3937 3938
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
3939
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
3940
                                 remote_error *rerr,
3941 3942 3943 3944
                                 void *args ATTRIBUTE_UNUSED,
                                 remote_num_of_storage_pools_ret *ret)
{

3945
    ret->num = virConnectNumOfStoragePools (conn);
3946
    if (ret->num == -1) {
3947
        remoteDispatchConnError(rerr, conn);
3948 3949
        return -1;
    }
3950 3951 3952 3953 3954 3955

    return 0;
}

static int
remoteDispatchNumOfDefinedStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
3956 3957
                                        struct qemud_client *client ATTRIBUTE_UNUSED,
                                        virConnectPtr conn,
3958
                                        remote_message_header *hdr ATTRIBUTE_UNUSED,
3959
                                        remote_error *rerr,
3960 3961 3962 3963
                                        void *args ATTRIBUTE_UNUSED,
                                        remote_num_of_defined_storage_pools_ret *ret)
{

3964
    ret->num = virConnectNumOfDefinedStoragePools (conn);
3965
    if (ret->num == -1) {
3966
        remoteDispatchConnError(rerr, conn);
3967 3968
        return -1;
    }
3969 3970 3971 3972 3973 3974

    return 0;
}

static int
remoteDispatchStoragePoolListVolumes (struct qemud_server *server ATTRIBUTE_UNUSED,
3975 3976
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
3977
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
3978
                                      remote_error *rerr,
3979 3980 3981 3982 3983 3984
                                      remote_storage_pool_list_volumes_args *args,
                                      remote_storage_pool_list_volumes_ret *ret)
{
    virStoragePoolPtr pool;

    if (args->maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX) {
3985 3986 3987
        remoteDispatchFormatError (rerr,
                                   "%s", _("maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX"));
        return -1;
3988 3989
    }

3990
    pool = get_nonnull_storage_pool (conn, args->pool);
3991
    if (pool == NULL) {
3992
        remoteDispatchConnError(rerr, conn);
3993
        return -1;
3994 3995 3996
    }

    /* Allocate return buffer. */
3997 3998
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
        virStoragePoolFree(pool);
3999 4000
        remoteDispatchOOMError(rerr);
        return -1;
4001
    }
4002 4003 4004 4005 4006

    ret->names.names_len =
        virStoragePoolListVolumes (pool,
                                   ret->names.names_val, args->maxnames);
    virStoragePoolFree(pool);
4007 4008
    if (ret->names.names_len == -1) {
        VIR_FREE(ret->names.names_val);
4009
        remoteDispatchConnError(rerr, conn);
4010 4011
        return -1;
    }
4012 4013 4014 4015 4016 4017 4018

    return 0;
}


static int
remoteDispatchStoragePoolNumOfVolumes (struct qemud_server *server ATTRIBUTE_UNUSED,
4019 4020
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
4021
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
4022
                                       remote_error *rerr,
4023 4024 4025 4026 4027
                                       remote_storage_pool_num_of_volumes_args *args,
                                       remote_storage_pool_num_of_volumes_ret *ret)
{
    virStoragePoolPtr pool;

4028
    pool = get_nonnull_storage_pool (conn, args->pool);
4029
    if (pool == NULL) {
4030
        remoteDispatchConnError(rerr, conn);
4031
        return -1;
4032 4033 4034 4035
    }

    ret->num = virStoragePoolNumOfVolumes (pool);
    virStoragePoolFree(pool);
4036
    if (ret->num == -1) {
4037
        remoteDispatchConnError(rerr, conn);
4038 4039
        return -1;
    }
4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052

    return 0;
}


/***************************************************************
 *     STORAGE VOL APIS
 ***************************************************************/



static int
remoteDispatchStorageVolCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
4053 4054
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
4055
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
4056
                                   remote_error *rerr,
4057 4058 4059 4060 4061 4062
                                   remote_storage_vol_create_xml_args *args,
                                   remote_storage_vol_create_xml_ret *ret)
{
    virStoragePoolPtr pool;
    virStorageVolPtr vol;

4063
    pool = get_nonnull_storage_pool (conn, args->pool);
4064
    if (pool == NULL) {
4065
        remoteDispatchConnError(rerr, conn);
4066
        return -1;
4067 4068 4069 4070
    }

    vol = virStorageVolCreateXML (pool, args->xml, args->flags);
    virStoragePoolFree(pool);
4071
    if (vol == NULL) {
4072
        remoteDispatchConnError(rerr, conn);
4073 4074
        return -1;
    }
4075 4076 4077 4078 4079 4080

    make_nonnull_storage_vol (&ret->vol, vol);
    virStorageVolFree(vol);
    return 0;
}

4081 4082 4083 4084
static int
remoteDispatchStorageVolCreateXmlFrom (struct qemud_server *server ATTRIBUTE_UNUSED,
                                       struct qemud_client *client ATTRIBUTE_UNUSED,
                                       virConnectPtr conn,
4085
                                       remote_message_header *hdr ATTRIBUTE_UNUSED,
4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115
                                       remote_error *rerr,
                                       remote_storage_vol_create_xml_from_args *args,
                                       remote_storage_vol_create_xml_from_ret *ret)
{
    virStoragePoolPtr pool;
    virStorageVolPtr clonevol, newvol;

    pool = get_nonnull_storage_pool (conn, args->pool);
    if (pool == NULL) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    clonevol = get_nonnull_storage_vol (conn, args->clonevol);
    if (clonevol == NULL) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    newvol = virStorageVolCreateXMLFrom (pool, args->xml, clonevol,
                                         args->flags);
    if (newvol == NULL) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    make_nonnull_storage_vol (&ret->vol, newvol);
    virStorageVolFree(newvol);
    return 0;
}
4116 4117 4118

static int
remoteDispatchStorageVolDelete (struct qemud_server *server ATTRIBUTE_UNUSED,
4119 4120
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
4121
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
4122
                                remote_error *rerr,
4123 4124 4125 4126 4127
                                remote_storage_vol_delete_args *args,
                                void *ret ATTRIBUTE_UNUSED)
{
    virStorageVolPtr vol;

4128
    vol = get_nonnull_storage_vol (conn, args->vol);
4129
    if (vol == NULL) {
4130
        remoteDispatchConnError(rerr, conn);
4131
        return -1;
4132 4133 4134 4135
    }

    if (virStorageVolDelete (vol, args->flags) == -1) {
        virStorageVolFree(vol);
4136
        remoteDispatchConnError(rerr, conn);
4137 4138 4139 4140 4141 4142 4143 4144
        return -1;
    }
    virStorageVolFree(vol);
    return 0;
}

static int
remoteDispatchStorageVolGetInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
4145 4146
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
4147
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
4148
                                 remote_error *rerr,
4149 4150 4151 4152 4153 4154
                                 remote_storage_vol_get_info_args *args,
                                 remote_storage_vol_get_info_ret *ret)
{
    virStorageVolPtr vol;
    virStorageVolInfo info;

4155
    vol = get_nonnull_storage_vol (conn, args->vol);
4156
    if (vol == NULL) {
4157
        remoteDispatchConnError(rerr, conn);
4158
        return -1;
4159 4160 4161 4162
    }

    if (virStorageVolGetInfo (vol, &info) == -1) {
        virStorageVolFree(vol);
4163
        remoteDispatchConnError(rerr, conn);
4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177
        return -1;
    }

    ret->type = info.type;
    ret->capacity = info.capacity;
    ret->allocation = info.allocation;

    virStorageVolFree(vol);

    return 0;
}

static int
remoteDispatchStorageVolDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
4178 4179
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
4180
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
4181
                                 remote_error *rerr,
4182 4183 4184 4185 4186
                                 remote_storage_vol_dump_xml_args *args,
                                 remote_storage_vol_dump_xml_ret *ret)
{
    virStorageVolPtr vol;

4187
    vol = get_nonnull_storage_vol (conn, args->vol);
4188
    if (vol == NULL) {
4189
        remoteDispatchConnError(rerr, conn);
4190
        return -1;
4191 4192 4193 4194 4195 4196
    }

    /* remoteDispatchClientRequest will free this. */
    ret->xml = virStorageVolGetXMLDesc (vol, args->flags);
    if (!ret->xml) {
        virStorageVolFree(vol);
4197
        remoteDispatchConnError(rerr, conn);
4198 4199 4200 4201 4202 4203 4204 4205 4206
        return -1;
    }
    virStorageVolFree(vol);
    return 0;
}


static int
remoteDispatchStorageVolGetPath (struct qemud_server *server ATTRIBUTE_UNUSED,
4207 4208
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
4209
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
4210
                                 remote_error *rerr,
4211 4212 4213 4214 4215
                                 remote_storage_vol_get_path_args *args,
                                 remote_storage_vol_get_path_ret *ret)
{
    virStorageVolPtr vol;

4216
    vol = get_nonnull_storage_vol (conn, args->vol);
4217
    if (vol == NULL) {
4218
        remoteDispatchConnError(rerr, conn);
4219
        return -1;
4220 4221 4222 4223 4224 4225
    }

    /* remoteDispatchClientRequest will free this. */
    ret->name = virStorageVolGetPath (vol);
    if (!ret->name) {
        virStorageVolFree(vol);
4226
        remoteDispatchConnError(rerr, conn);
4227 4228 4229 4230 4231 4232 4233 4234 4235
        return -1;
    }
    virStorageVolFree(vol);
    return 0;
}


static int
remoteDispatchStorageVolLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
4236 4237
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
4238
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
4239
                                      remote_error *rerr,
4240 4241 4242 4243 4244 4245
                                      remote_storage_vol_lookup_by_name_args *args,
                                      remote_storage_vol_lookup_by_name_ret *ret)
{
    virStoragePoolPtr pool;
    virStorageVolPtr vol;

4246
    pool = get_nonnull_storage_pool (conn, args->pool);
4247
    if (pool == NULL) {
4248
        remoteDispatchConnError(rerr, conn);
4249
        return -1;
4250 4251 4252 4253
    }

    vol = virStorageVolLookupByName (pool, args->name);
    virStoragePoolFree(pool);
4254
    if (vol == NULL) {
4255
        remoteDispatchConnError(rerr, conn);
4256 4257
        return -1;
    }
4258 4259 4260 4261 4262 4263 4264 4265

    make_nonnull_storage_vol (&ret->vol, vol);
    virStorageVolFree(vol);
    return 0;
}

static int
remoteDispatchStorageVolLookupByKey (struct qemud_server *server ATTRIBUTE_UNUSED,
4266 4267
                                     struct qemud_client *client ATTRIBUTE_UNUSED,
                                     virConnectPtr conn,
4268
                                     remote_message_header *hdr ATTRIBUTE_UNUSED,
4269
                                     remote_error *rerr,
4270 4271 4272 4273 4274
                                     remote_storage_vol_lookup_by_key_args *args,
                                     remote_storage_vol_lookup_by_key_ret *ret)
{
    virStorageVolPtr vol;

4275
    vol = virStorageVolLookupByKey (conn, args->key);
4276
    if (vol == NULL) {
4277
        remoteDispatchConnError(rerr, conn);
4278 4279
        return -1;
    }
4280 4281 4282 4283 4284 4285 4286 4287 4288

    make_nonnull_storage_vol (&ret->vol, vol);
    virStorageVolFree(vol);
    return 0;
}


static int
remoteDispatchStorageVolLookupByPath (struct qemud_server *server ATTRIBUTE_UNUSED,
4289 4290
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
4291
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
4292
                                      remote_error *rerr,
4293 4294 4295 4296 4297
                                      remote_storage_vol_lookup_by_path_args *args,
                                      remote_storage_vol_lookup_by_path_ret *ret)
{
    virStorageVolPtr vol;

4298
    vol = virStorageVolLookupByPath (conn, args->path);
4299
    if (vol == NULL) {
4300
        remoteDispatchConnError(rerr, conn);
4301 4302
        return -1;
    }
4303 4304 4305 4306 4307 4308 4309

    make_nonnull_storage_vol (&ret->vol, vol);
    virStorageVolFree(vol);
    return 0;
}


4310 4311 4312 4313 4314 4315
/***************************************************************
 *     NODE INFO APIS
 **************************************************************/

static int
remoteDispatchNodeNumOfDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
4316 4317
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
4318
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
4319
                                remote_error *rerr,
4320 4321 4322 4323 4324
                                remote_node_num_of_devices_args *args,
                                remote_node_num_of_devices_ret *ret)
{
    CHECK_CONN(client);

4325
    ret->num = virNodeNumOfDevices (conn,
4326 4327
                                    args->cap ? *args->cap : NULL,
                                    args->flags);
4328
    if (ret->num == -1) {
4329
        remoteDispatchConnError(rerr, conn);
4330 4331
        return -1;
    }
4332 4333 4334 4335 4336 4337 4338

    return 0;
}


static int
remoteDispatchNodeListDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
4339 4340
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
4341
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
4342
                               remote_error *rerr,
4343 4344 4345 4346 4347 4348
                               remote_node_list_devices_args *args,
                               remote_node_list_devices_ret *ret)
{
    CHECK_CONN(client);

    if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
4349 4350 4351
        remoteDispatchFormatError(rerr,
                                  "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
        return -1;
4352 4353 4354 4355
    }

    /* Allocate return buffer. */
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
4356 4357
        remoteDispatchOOMError(rerr);
        return -1;
4358 4359 4360
    }

    ret->names.names_len =
4361
        virNodeListDevices (conn,
4362 4363 4364
                            args->cap ? *args->cap : NULL,
                            ret->names.names_val, args->maxnames, args->flags);
    if (ret->names.names_len == -1) {
4365
        remoteDispatchConnError(rerr, conn);
4366 4367 4368 4369 4370 4371 4372 4373 4374 4375
        VIR_FREE(ret->names.names_val);
        return -1;
    }

    return 0;
}


static int
remoteDispatchNodeDeviceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
4376 4377
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
4378
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
4379
                                      remote_error *rerr,
4380 4381 4382 4383 4384 4385 4386
                                      remote_node_device_lookup_by_name_args *args,
                                      remote_node_device_lookup_by_name_ret *ret)
{
    virNodeDevicePtr dev;

    CHECK_CONN(client);

4387
    dev = virNodeDeviceLookupByName (conn, args->name);
4388
    if (dev == NULL) {
4389
        remoteDispatchConnError(rerr, conn);
4390 4391
        return -1;
    }
4392 4393 4394 4395 4396 4397 4398 4399 4400

    make_nonnull_node_device (&ret->dev, dev);
    virNodeDeviceFree(dev);
    return 0;
}


static int
remoteDispatchNodeDeviceDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
4401 4402
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
4403
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
4404
                                 remote_error *rerr,
4405 4406 4407 4408 4409 4410
                                 remote_node_device_dump_xml_args *args,
                                 remote_node_device_dump_xml_ret *ret)
{
    virNodeDevicePtr dev;
    CHECK_CONN(client);

4411
    dev = virNodeDeviceLookupByName(conn, args->name);
4412
    if (dev == NULL) {
4413 4414
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
4415 4416 4417 4418 4419
    }

    /* remoteDispatchClientRequest will free this. */
    ret->xml = virNodeDeviceGetXMLDesc (dev, args->flags);
    if (!ret->xml) {
4420
        remoteDispatchConnError(rerr, conn);
4421 4422 4423 4424 4425 4426 4427 4428 4429 4430
        virNodeDeviceFree(dev);
        return -1;
    }
    virNodeDeviceFree(dev);
    return 0;
}


static int
remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
4431 4432
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
4433
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
4434
                                   remote_error *rerr,
4435 4436 4437 4438 4439 4440 4441
                                   remote_node_device_get_parent_args *args,
                                   remote_node_device_get_parent_ret *ret)
{
    virNodeDevicePtr dev;
    const char *parent;
    CHECK_CONN(client);

4442
    dev = virNodeDeviceLookupByName(conn, args->name);
4443
    if (dev == NULL) {
4444 4445
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
4446 4447 4448 4449 4450 4451 4452 4453 4454 4455
    }

    parent = virNodeDeviceGetParent(dev);

    if (parent == NULL) {
        ret->parent = NULL;
    } else {
        /* remoteDispatchClientRequest will free this. */
        char **parent_p;
        if (VIR_ALLOC(parent_p) < 0) {
4456 4457
            remoteDispatchOOMError(rerr);
            return -1;
4458 4459 4460
        }
        *parent_p = strdup(parent);
        if (*parent_p == NULL) {
4461 4462
            remoteDispatchOOMError(rerr);
            return -1;
4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473
        }
        ret->parent = parent_p;
    }

    virNodeDeviceFree(dev);
    return 0;
}


static int
remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
4474 4475
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
                                   virConnectPtr conn,
4476
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
4477
                                   remote_error *rerr,
4478 4479 4480 4481 4482 4483
                                   remote_node_device_num_of_caps_args *args,
                                   remote_node_device_num_of_caps_ret *ret)
{
    virNodeDevicePtr dev;
    CHECK_CONN(client);

4484
    dev = virNodeDeviceLookupByName(conn, args->name);
4485
    if (dev == NULL) {
4486 4487
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
4488 4489 4490
    }

    ret->num = virNodeDeviceNumOfCaps(dev);
4491
    if (ret->num < 0) {
4492
        remoteDispatchConnError(rerr, conn);
4493 4494
        return -1;
    }
4495 4496 4497 4498 4499 4500 4501 4502

    virNodeDeviceFree(dev);
    return 0;
}


static int
remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
4503 4504
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
4505
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
4506
                                  remote_error *rerr,
4507 4508 4509 4510 4511 4512
                                  remote_node_device_list_caps_args *args,
                                  remote_node_device_list_caps_ret *ret)
{
    virNodeDevicePtr dev;
    CHECK_CONN(client);

4513
    dev = virNodeDeviceLookupByName(conn, args->name);
4514
    if (dev == NULL) {
4515 4516
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
4517 4518 4519
    }

    if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
4520 4521 4522
        remoteDispatchFormatError(rerr,
                                  "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
        return -1;
4523 4524 4525 4526
    }

    /* Allocate return buffer. */
    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
4527 4528
        remoteDispatchOOMError(rerr);
        return -1;
4529 4530 4531 4532 4533 4534
    }

    ret->names.names_len =
        virNodeDeviceListCaps (dev, ret->names.names_val,
                               args->maxnames);
    if (ret->names.names_len == -1) {
4535
        remoteDispatchConnError(rerr, conn);
4536 4537 4538 4539 4540 4541 4542 4543
        VIR_FREE(ret->names.names_val);
        return -1;
    }

    return 0;
}


4544 4545 4546 4547
static int
remoteDispatchNodeDeviceDettach (struct qemud_server *server ATTRIBUTE_UNUSED,
                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                 virConnectPtr conn,
4548
                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574
                                 remote_error *rerr,
                                 remote_node_device_dettach_args *args,
                                 void *ret ATTRIBUTE_UNUSED)
{
    virNodeDevicePtr dev;
    CHECK_CONN(client);

    dev = virNodeDeviceLookupByName(conn, args->name);
    if (dev == NULL) {
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
    }

    if (virNodeDeviceDettach(dev) == -1) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}


static int
remoteDispatchNodeDeviceReAttach (struct qemud_server *server ATTRIBUTE_UNUSED,
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
4575
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601
                                  remote_error *rerr,
                                  remote_node_device_re_attach_args *args,
                                  void *ret ATTRIBUTE_UNUSED)
{
    virNodeDevicePtr dev;
    CHECK_CONN(client);

    dev = virNodeDeviceLookupByName(conn, args->name);
    if (dev == NULL) {
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
    }

    if (virNodeDeviceReAttach(dev) == -1) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}


static int
remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED,
                               struct qemud_client *client ATTRIBUTE_UNUSED,
                               virConnectPtr conn,
4602
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624
                               remote_error *rerr,
                               remote_node_device_reset_args *args,
                               void *ret ATTRIBUTE_UNUSED)
{
    virNodeDevicePtr dev;
    CHECK_CONN(client);

    dev = virNodeDeviceLookupByName(conn, args->name);
    if (dev == NULL) {
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
    }

    if (virNodeDeviceReset(dev) == -1) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}


4625 4626 4627 4628
static int
remoteDispatchNodeDeviceCreateXml(struct qemud_server *server ATTRIBUTE_UNUSED,
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
4629
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652
                                  remote_error *rerr,
                                  remote_node_device_create_xml_args *args,
                                  remote_node_device_create_xml_ret *ret)
{
    virNodeDevicePtr dev;

    dev = virNodeDeviceCreateXML (conn, args->xml_desc, args->flags);
    if (dev == NULL) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    make_nonnull_node_device (&ret->dev, dev);
    virNodeDeviceFree(dev);

    return 0;
}


static int
remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED,
                                struct qemud_client *client ATTRIBUTE_UNUSED,
                                virConnectPtr conn,
4653
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674
                                remote_error *rerr,
                                remote_node_device_destroy_args *args,
                                void *ret ATTRIBUTE_UNUSED)
{
    virNodeDevicePtr dev;

    dev = virNodeDeviceLookupByName(conn, args->name);
    if (dev == NULL) {
        remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
        return -1;
    }

    if (virNodeDeviceDestroy(dev) == -1) {
        remoteDispatchConnError(rerr, conn);
        return -1;
    }

    return 0;
}


4675 4676 4677 4678 4679 4680

/***************************
 * Register / deregister events
 ***************************/
static int
remoteDispatchDomainEventsRegister (struct qemud_server *server ATTRIBUTE_UNUSED,
4681 4682
                                    struct qemud_client *client ATTRIBUTE_UNUSED,
                                    virConnectPtr conn,
4683
                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
4684
                                    remote_error *rerr ATTRIBUTE_UNUSED,
4685 4686 4687 4688 4689 4690 4691
                                    void *args ATTRIBUTE_UNUSED,
                                    remote_domain_events_register_ret *ret ATTRIBUTE_UNUSED)
{
    CHECK_CONN(client);

    /* Register event delivery callback */
    REMOTE_DEBUG("%s","Registering to relay remote events");
4692
    virConnectDomainEventRegister(conn, remoteRelayDomainEvent, client, NULL);
4693 4694 4695 4696 4697 4698 4699 4700

    if(ret)
        ret->cb_registered = 1;
    return 0;
}

static int
remoteDispatchDomainEventsDeregister (struct qemud_server *server ATTRIBUTE_UNUSED,
4701 4702
                                      struct qemud_client *client ATTRIBUTE_UNUSED,
                                      virConnectPtr conn,
4703
                                      remote_message_header *hdr ATTRIBUTE_UNUSED,
4704
                                      remote_error *rerr ATTRIBUTE_UNUSED,
4705 4706 4707 4708 4709 4710 4711
                                      void *args ATTRIBUTE_UNUSED,
                                      remote_domain_events_deregister_ret *ret ATTRIBUTE_UNUSED)
{
    CHECK_CONN(client);

    /* Deregister event delivery callback */
    REMOTE_DEBUG("%s","Deregistering to relay remote events");
4712
    virConnectDomainEventDeregister(conn, remoteRelayDomainEvent);
4713 4714 4715 4716 4717 4718 4719 4720

    if(ret)
        ret->cb_registered = 0;
    return 0;
}

static void
remoteDispatchDomainEventSend (struct qemud_client *client,
4721
                               remote_domain_event_msg *data)
4722
{
4723
    struct qemud_client_message *msg = NULL;
4724
    XDR xdr;
4725
    unsigned int len;
4726

4727
    if (VIR_ALLOC(msg) < 0)
4728 4729
        return;

4730 4731 4732
    msg->hdr.prog = REMOTE_PROGRAM;
    msg->hdr.vers = REMOTE_PROTOCOL_VERSION;
    msg->hdr.proc = REMOTE_PROC_DOMAIN_EVENT;
4733
    msg->hdr.type = REMOTE_MESSAGE;
4734 4735
    msg->hdr.serial = 1;
    msg->hdr.status = REMOTE_OK;
4736

4737 4738
    if (remoteEncodeClientMessageHeader(msg) < 0)
        goto error;
4739

4740 4741
    /* Serialise the return header and event. */
    xdrmem_create (&xdr,
4742 4743
                   msg->buffer,
                   msg->bufferLength,
4744
                   XDR_ENCODE);
4745

4746 4747
    /* Skip over the header we just wrote */
    if (xdr_setpos (&xdr, msg->bufferOffset) == 0)
4748
        goto xdr_error;
4749

4750 4751
    if (!xdr_remote_domain_event_msg(&xdr, data))
        goto xdr_error;
4752

4753 4754
    /* Update length word to include payload*/
    len = msg->bufferOffset = xdr_getpos (&xdr);
4755 4756
    if (xdr_setpos (&xdr, 0) == 0)
        goto xdr_error;
4757

4758 4759
    if (!xdr_u_int (&xdr, &len))
        goto xdr_error;
4760 4761

    /* Send it. */
4762 4763 4764 4765
    msg->async = 1;
    msg->bufferLength = len;
    msg->bufferOffset = 0;
    qemudClientMessageQueuePush(&client->tx, msg);
4766
    qemudUpdateClientEvent(client);
4767 4768 4769 4770 4771 4772 4773 4774

    xdr_destroy (&xdr);
    return;

xdr_error:
    xdr_destroy(&xdr);
error:
    VIR_FREE(msg);
4775
}
4776

4777 4778 4779
static int
remoteDispatchNumOfSecrets (struct qemud_server *server ATTRIBUTE_UNUSED,
                            struct qemud_client *client ATTRIBUTE_UNUSED,
4780 4781 4782
                            virConnectPtr conn,
                            remote_message_header *hdr ATTRIBUTE_UNUSED,
                            remote_error *err,
4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797
                            void *args ATTRIBUTE_UNUSED,
                            remote_num_of_secrets_ret *ret)
{
    ret->num = virConnectNumOfSecrets (conn);
    if (ret->num == -1) {
        remoteDispatchConnError (err, conn);
        return -1;
    }

    return 0;
}

static int
remoteDispatchListSecrets (struct qemud_server *server ATTRIBUTE_UNUSED,
                           struct qemud_client *client ATTRIBUTE_UNUSED,
4798 4799 4800
                           virConnectPtr conn,
                           remote_message_header *hdr ATTRIBUTE_UNUSED,
                           remote_error *err,
4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828
                           remote_list_secrets_args *args,
                           remote_list_secrets_ret *ret)
{
    if (args->maxuuids > REMOTE_SECRET_UUID_LIST_MAX) {
        remoteDispatchFormatError (err, "%s",
                                   _("maxuuids > REMOTE_SECRET_UUID_LIST_MAX"));
        return -1;
    }

    if (VIR_ALLOC_N (ret->uuids.uuids_val, args->maxuuids) < 0) {
        remoteDispatchOOMError (err);
        return -1;
    }

    ret->uuids.uuids_len = virConnectListSecrets (conn, ret->uuids.uuids_val,
                                                  args->maxuuids);
    if (ret->uuids.uuids_len == -1) {
        VIR_FREE (ret->uuids.uuids_val);
        remoteDispatchConnError (err, conn);
        return -1;
    }

    return 0;
}

static int
remoteDispatchSecretDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
                               struct qemud_client *client ATTRIBUTE_UNUSED,
4829 4830 4831
                               virConnectPtr conn,
                               remote_message_header *hdr ATTRIBUTE_UNUSED,
                               remote_error *err,
4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850
                               remote_secret_define_xml_args *args,
                               remote_secret_define_xml_ret *ret)
{
    virSecretPtr secret;

    secret = virSecretDefineXML (conn, args->xml, args->flags);
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }

    make_nonnull_secret (&ret->secret, secret);
    virSecretFree (secret);
    return 0;
}

static int
remoteDispatchSecretGetValue (struct qemud_server *server ATTRIBUTE_UNUSED,
                              struct qemud_client *client ATTRIBUTE_UNUSED,
4851 4852 4853
                              virConnectPtr conn,
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
                              remote_error *err,
4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882
                              remote_secret_get_value_args *args,
                              remote_secret_get_value_ret *ret)
{
    virSecretPtr secret;
    size_t value_size;
    unsigned char *value;

    secret = get_nonnull_secret (conn, args->secret);
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }

    value = virSecretGetValue (secret, &value_size, args->flags);
    if (value == NULL) {
        remoteDispatchConnError (err, conn);
        virSecretFree(secret);
        return -1;
    }

    ret->value.value_len = value_size;
    ret->value.value_val = (char *)value;
    virSecretFree(secret);
    return 0;
}

static int
remoteDispatchSecretGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
                                struct qemud_client *client ATTRIBUTE_UNUSED,
4883 4884 4885
                                virConnectPtr conn,
                                remote_message_header *hdr ATTRIBUTE_UNUSED,
                                remote_error *err,
4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906
                                remote_secret_get_xml_desc_args *args,
                                remote_secret_get_xml_desc_ret *ret)
{
    virSecretPtr secret;

    secret = get_nonnull_secret (conn, args->secret);
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }
    ret->xml = virSecretGetXMLDesc (secret, args->flags);
    if (ret->xml == NULL) {
        remoteDispatchConnError (err, conn);
        virSecretFree(secret);
        return -1;
    }
    virSecretFree(secret);
    return 0;
}

static int
4907 4908
remoteDispatchSecretLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
4909 4910 4911
                                  virConnectPtr conn,
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
                                  remote_error *err,
4912 4913
                                  remote_secret_lookup_by_uuid_args *args,
                                  remote_secret_lookup_by_uuid_ret *ret)
4914 4915 4916
{
    virSecretPtr secret;

4917
    secret = virSecretLookupByUUID (conn, (unsigned char *)args->uuid);
4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }

    make_nonnull_secret (&ret->secret, secret);
    virSecretFree (secret);
    return 0;
}

static int
remoteDispatchSecretSetValue (struct qemud_server *server ATTRIBUTE_UNUSED,
                              struct qemud_client *client ATTRIBUTE_UNUSED,
4931 4932 4933
                              virConnectPtr conn,
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
                              remote_error *err,
4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957
                              remote_secret_set_value_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virSecretPtr secret;

    secret = get_nonnull_secret (conn, args->secret);
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }
    if (virSecretSetValue (secret, (const unsigned char *)args->value.value_val,
                           args->value.value_len, args->flags) < 0) {
        remoteDispatchConnError (err, conn);
        virSecretFree(secret);
        return -1;
    }

    virSecretFree(secret);
    return 0;
}

static int
remoteDispatchSecretUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
                              struct qemud_client *client ATTRIBUTE_UNUSED,
4958 4959 4960
                              virConnectPtr conn,
                              remote_message_header *hdr ATTRIBUTE_UNUSED,
                              remote_error *err,
4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980
                              remote_secret_undefine_args *args,
                              void *ret ATTRIBUTE_UNUSED)
{
    virSecretPtr secret;

    secret = get_nonnull_secret (conn, args->secret);
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }
    if (virSecretUndefine (secret) < 0) {
        remoteDispatchConnError (err, conn);
        virSecretFree(secret);
        return -1;
    }

    virSecretFree(secret);
    return 0;
}

4981 4982 4983
static int
remoteDispatchSecretLookupByUsage (struct qemud_server *server ATTRIBUTE_UNUSED,
                                   struct qemud_client *client ATTRIBUTE_UNUSED,
4984 4985 4986
                                   virConnectPtr conn,
                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
                                   remote_error *err,
4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002
                                   remote_secret_lookup_by_usage_args *args,
                                   remote_secret_lookup_by_usage_ret *ret)
{
    virSecretPtr secret;

    secret = virSecretLookupByUsage (conn, args->usageType, args->usageID);
    if (secret == NULL) {
        remoteDispatchConnError (err, conn);
        return -1;
    }

    make_nonnull_secret (&ret->secret, secret);
    virSecretFree (secret);
    return 0;
}

5003

5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205
static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
                                        struct qemud_client *client ATTRIBUTE_UNUSED,
                                        virConnectPtr conn,
                                        remote_message_header *hdr ATTRIBUTE_UNUSED,
                                        remote_error *err,
                                        remote_domain_is_active_args *args,
                                        remote_domain_is_active_ret *ret)
{
    virDomainPtr domain;

    domain = get_nonnull_domain(conn, args->dom);
    if (domain == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->active = virDomainIsActive(domain);

    if (ret->active < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}

static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
                                            struct qemud_client *client ATTRIBUTE_UNUSED,
                                            virConnectPtr conn,
                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
                                            remote_error *err,
                                            remote_domain_is_persistent_args *args,
                                            remote_domain_is_persistent_ret *ret)
{
    virDomainPtr domain;

    domain = get_nonnull_domain(conn, args->dom);
    if (domain == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->persistent = virDomainIsPersistent(domain);

    if (ret->persistent < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}

static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
                                           struct qemud_client *client ATTRIBUTE_UNUSED,
                                           virConnectPtr conn,
                                           remote_message_header *hdr ATTRIBUTE_UNUSED,
                                           remote_error *err,
                                           remote_interface_is_active_args *args,
                                           remote_interface_is_active_ret *ret)
{
    virInterfacePtr iface;

    iface = get_nonnull_interface(conn, args->iface);
    if (iface == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->active = virInterfaceIsActive(iface);

    if (ret->active < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}

static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
                                         struct qemud_client *client ATTRIBUTE_UNUSED,
                                         virConnectPtr conn,
                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
                                         remote_error *err,
                                         remote_network_is_active_args *args,
                                         remote_network_is_active_ret *ret)
{
    virNetworkPtr network;

    network = get_nonnull_network(conn, args->net);
    if (network == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->active = virNetworkIsActive(network);

    if (ret->active < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}

static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
                                             struct qemud_client *client ATTRIBUTE_UNUSED,
                                             virConnectPtr conn,
                                             remote_message_header *hdr ATTRIBUTE_UNUSED,
                                             remote_error *err,
                                             remote_network_is_persistent_args *args,
                                             remote_network_is_persistent_ret *ret)
{
    virNetworkPtr network;

    network = get_nonnull_network(conn, args->net);
    if (network == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->persistent = virNetworkIsPersistent(network);

    if (ret->persistent < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}

static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
                                             struct qemud_client *client ATTRIBUTE_UNUSED,
                                             virConnectPtr conn,
                                             remote_message_header *hdr ATTRIBUTE_UNUSED,
                                             remote_error *err,
                                             remote_storage_pool_is_active_args *args,
                                             remote_storage_pool_is_active_ret *ret)
{
    virStoragePoolPtr pool;

    pool = get_nonnull_storage_pool(conn, args->pool);
    if (pool == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->active = virStoragePoolIsActive(pool);

    if (ret->active < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}

static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
                                                 struct qemud_client *client ATTRIBUTE_UNUSED,
                                                 virConnectPtr conn,
                                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
                                                 remote_error *err,
                                                 remote_storage_pool_is_persistent_args *args,
                                                 remote_storage_pool_is_persistent_ret *ret)
{
    virStoragePoolPtr pool;

    pool = get_nonnull_storage_pool(conn, args->pool);
    if (pool == NULL) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    ret->persistent = virStoragePoolIsPersistent(pool);

    if (ret->persistent < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}


static int remoteDispatchIsSecure(struct qemud_server *server ATTRIBUTE_UNUSED,
                                  struct qemud_client *client ATTRIBUTE_UNUSED,
                                  virConnectPtr conn,
                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
                                  remote_error *err,
                                  void *args ATTRIBUTE_UNUSED,
                                  remote_is_secure_ret *ret)
{
    ret->secure = virConnectIsSecure(conn);

    if (ret->secure < 0) {
        remoteDispatchConnError(err, conn);
        return -1;
    }

    return 0;
}


5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231
/*----- Helpers. -----*/

/* get_nonnull_domain and get_nonnull_network turn an on-wire
 * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
 * virDomainPtr or virNetworkPtr cannot be NULL.
 *
 * NB. If these return NULL then the caller must return an error.
 */
static virDomainPtr
get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain)
{
    virDomainPtr dom;
    dom = virGetDomain (conn, domain.name, BAD_CAST domain.uuid);
    /* Should we believe the domain.id sent by the client?  Maybe
     * this should be a check rather than an assignment? XXX
     */
    if (dom) dom->id = domain.id;
    return dom;
}

static virNetworkPtr
get_nonnull_network (virConnectPtr conn, remote_nonnull_network network)
{
    return virGetNetwork (conn, network.name, BAD_CAST network.uuid);
}

D
Daniel Veillard 已提交
5232
static virInterfacePtr
5233
get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface iface)
D
Daniel Veillard 已提交
5234
{
5235
    return virGetInterface (conn, iface.name, iface.mac);
D
Daniel Veillard 已提交
5236 5237
}

5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251
static virStoragePoolPtr
get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool)
{
    return virGetStoragePool (conn, pool.name, BAD_CAST pool.uuid);
}

static virStorageVolPtr
get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol)
{
    virStorageVolPtr ret;
    ret = virGetStorageVol (conn, vol.pool, vol.name, vol.key);
    return ret;
}

5252 5253 5254
static virSecretPtr
get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
{
5255
    return virGetSecret (conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID);
5256 5257
}

5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273
/* Make remote_nonnull_domain and remote_nonnull_network. */
static void
make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
{
    dom_dst->id = dom_src->id;
    dom_dst->name = strdup (dom_src->name);
    memcpy (dom_dst->uuid, dom_src->uuid, VIR_UUID_BUFLEN);
}

static void
make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src)
{
    net_dst->name = strdup (net_src->name);
    memcpy (net_dst->uuid, net_src->uuid, VIR_UUID_BUFLEN);
}

D
Daniel Veillard 已提交
5274 5275 5276 5277 5278 5279 5280 5281
static void
make_nonnull_interface (remote_nonnull_interface *interface_dst,
                        virInterfacePtr interface_src)
{
    interface_dst->name = strdup (interface_src->name);
    interface_dst->mac = strdup (interface_src->mac);
}

5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295
static void
make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src)
{
    pool_dst->name = strdup (pool_src->name);
    memcpy (pool_dst->uuid, pool_src->uuid, VIR_UUID_BUFLEN);
}

static void
make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src)
{
    vol_dst->pool = strdup (vol_src->pool);
    vol_dst->name = strdup (vol_src->name);
    vol_dst->key = strdup (vol_src->key);
}
5296 5297 5298 5299 5300 5301

static void
make_nonnull_node_device (remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src)
{
    dev_dst->name = strdup(dev_src->name);
}
5302 5303 5304 5305

static void
make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
{
5306
    memcpy (secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
5307 5308
    secret_dst->usageType = secret_src->usageType;
    secret_dst->usageID = strdup (secret_src->usageID);
5309
}