dispatch.c 29.1 KB
Newer Older
D
Daniel P. Berrange 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * dispatch.c: (De-)marshall wire messages to driver functions.
 *
 * Copyright (C) 2006, 2007 Red Hat, Inc.
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * 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: Daniel P. Berrange <berrange@redhat.com>
 */

24 25
#include <config.h>

26
#include <unistd.h>
D
Daniel P. Berrange 已提交
27 28 29 30 31 32 33 34 35
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <libvirt/virterror.h>

#include "internal.h"
#include "driver.h"
#include "dispatch.h"
36
#include "conf.h"
37
extern struct qemud_driver *qemu_driver;
D
Daniel P. Berrange 已提交
38 39


40
static int qemudDispatchFailure(struct qemud_packet_server_data *out) {
41 42
    virErrorPtr err = virGetLastError();

43
    out->type = QEMUD_SERVER_PKT_FAILURE;
44 45 46 47 48

    out->qemud_packet_server_data_u.failureReply.code = err->code;
    strncpy(out->qemud_packet_server_data_u.failureReply.message,
            err->message, QEMUD_MAX_ERROR_LEN-1);
    out->qemud_packet_server_data_u.failureReply.message[QEMUD_MAX_ERROR_LEN-1] = '\0';
D
Daniel P. Berrange 已提交
49 50 51 52
    return 0;
}


53 54
static int qemudDispatchGetVersion(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
    int version = qemudGetVersion(qemu_driver);
D
Daniel P. Berrange 已提交
55
    if (version < 0) {
56
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
57 58
            return -1;
    } else {
59 60
        out->type = QEMUD_SERVER_PKT_GET_VERSION;
        out->qemud_packet_server_data_u.getVersionReply.versionNum = version;
D
Daniel P. Berrange 已提交
61 62 63 64
    }
    return 0;
}

65
static int qemudDispatchGetNodeInfo(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
66 67 68 69 70 71 72 73 74
    if (qemudGetNodeInfo(&out->qemud_packet_server_data_u.getNodeInfoReply.memory,
                         out->qemud_packet_server_data_u.getNodeInfoReply.model,
                         sizeof(out->qemud_packet_server_data_u.getNodeInfoReply.model),
                         &out->qemud_packet_server_data_u.getNodeInfoReply.cpus,
                         &out->qemud_packet_server_data_u.getNodeInfoReply.mhz,
                         &out->qemud_packet_server_data_u.getNodeInfoReply.nodes,
                         &out->qemud_packet_server_data_u.getNodeInfoReply.sockets,
                         &out->qemud_packet_server_data_u.getNodeInfoReply.cores,
                         &out->qemud_packet_server_data_u.getNodeInfoReply.threads) < 0) {
75
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
76 77 78 79
            return -1;
        return 0;
    }

80 81
    out->type = QEMUD_SERVER_PKT_GET_NODEINFO;
    out->qemud_packet_server_data_u.getNodeInfoReply.model[sizeof(out->qemud_packet_server_data_u.getNodeInfoReply.model)-1] = '\0';
D
Daniel P. Berrange 已提交
82 83 84 85

    return 0;
}

86
static int
87
qemudDispatchGetCapabilities (struct qemud_packet_client_data *in ATTRIBUTE_UNUSED,
88
                              struct qemud_packet_server_data *out)
89
{
90
    char *xml = qemudGetCapabilities(qemu_driver);
91

92
    if (strlen(xml) > QEMUD_MAX_XML_LEN) {
93
        qemudReportError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, NULL);
94
        qemudDispatchFailure(out);
95
        free(xml);
96 97
        return 0;
    }
98

99
    out->type = QEMUD_SERVER_PKT_GET_CAPABILITIES;
100 101
    strcpy (out->qemud_packet_server_data_u.getCapabilitiesReply.xml, xml);
    free(xml);
102 103 104
    return 0;
}

105
static int qemudDispatchListDomains(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
106 107
    int i, ndomains, domains[QEMUD_MAX_NUM_DOMAINS];

108
    ndomains = qemudListDomains(qemu_driver,
D
Daniel P. Berrange 已提交
109 110 111
                                domains,
                                QEMUD_MAX_NUM_DOMAINS);
    if (ndomains < 0) {
112
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
113 114
            return -1;
    } else {
115
        out->type = QEMUD_SERVER_PKT_LIST_DOMAINS;
D
Daniel P. Berrange 已提交
116
        for (i = 0 ; i < ndomains ; i++) {
117
            out->qemud_packet_server_data_u.listDomainsReply.domains[i] = domains[i];
D
Daniel P. Berrange 已提交
118
        }
119
        out->qemud_packet_server_data_u.listDomainsReply.numDomains = ndomains;
D
Daniel P. Berrange 已提交
120 121 122 123
    }
    return 0;
}

124 125
static int qemudDispatchNumDomains(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
    int ndomains = qemudNumDomains(qemu_driver);
D
Daniel P. Berrange 已提交
126
    if (ndomains < 0) {
127
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
128 129
            return -1;
    } else {
130 131
        out->type = QEMUD_SERVER_PKT_NUM_DOMAINS;
        out->qemud_packet_server_data_u.numDomainsReply.numDomains = ndomains;
D
Daniel P. Berrange 已提交
132 133 134 135
    }
    return 0;
}

136
static int qemudDispatchDomainCreate(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
137
    in->qemud_packet_client_data_u.domainCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0';
D
Daniel P. Berrange 已提交
138

139
    struct qemud_vm *vm = qemudDomainCreate(qemu_driver, in->qemud_packet_client_data_u.domainCreateRequest.xml);
D
Daniel P. Berrange 已提交
140
    if (!vm) {
141
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
142 143
            return -1;
    } else {
144 145 146 147 148
        out->type = QEMUD_SERVER_PKT_DOMAIN_CREATE;
        out->qemud_packet_server_data_u.domainCreateReply.id = vm->id;
        memcpy(out->qemud_packet_server_data_u.domainCreateReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
        strncpy(out->qemud_packet_server_data_u.domainCreateReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.domainCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
D
Daniel P. Berrange 已提交
149 150 151 152
    }
    return 0;
}

153 154
static int qemudDispatchDomainLookupByID(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    struct qemud_vm *vm = qemudFindVMByID(qemu_driver, in->qemud_packet_client_data_u.domainLookupByIDRequest.id);
D
Daniel P. Berrange 已提交
155
    if (!vm) {
156
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
157 158
            return -1;
    } else {
159 160 161 162
        out->type = QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_ID;
        memcpy(out->qemud_packet_server_data_u.domainLookupByIDReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
        strncpy(out->qemud_packet_server_data_u.domainLookupByIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.domainLookupByIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
D
Daniel P. Berrange 已提交
163 164 165 166
    }
    return 0;
}

167 168
static int qemudDispatchDomainLookupByUUID(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    struct qemud_vm *vm = qemudFindVMByUUID(qemu_driver, in->qemud_packet_client_data_u.domainLookupByUUIDRequest.uuid);
D
Daniel P. Berrange 已提交
169
    if (!vm) {
170
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
171 172
            return -1;
    } else {
173 174 175 176
        out->type = QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_UUID;
        out->qemud_packet_server_data_u.domainLookupByUUIDReply.id = vm->id;
        strncpy(out->qemud_packet_server_data_u.domainLookupByUUIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.domainLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
D
Daniel P. Berrange 已提交
177 178 179 180
    }
    return 0;
}

181
static int qemudDispatchDomainLookupByName(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
182
    /* Paranoia NULL termination */
183
    in->qemud_packet_client_data_u.domainLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0';
184
    struct qemud_vm *vm = qemudFindVMByName(qemu_driver, in->qemud_packet_client_data_u.domainLookupByNameRequest.name);
D
Daniel P. Berrange 已提交
185
    if (!vm) {
186
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
187 188
            return -1;
    } else {
189 190 191
        out->type = QEMUD_SERVER_PKT_DOMAIN_LOOKUP_BY_NAME;
        out->qemud_packet_server_data_u.domainLookupByNameReply.id = vm->id;
        memcpy(out->qemud_packet_server_data_u.domainLookupByNameReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
D
Daniel P. Berrange 已提交
192 193 194 195
    }
    return 0;
}

196 197
static int qemudDispatchDomainSuspend(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    int ret = qemudDomainSuspend(qemu_driver, in->qemud_packet_client_data_u.domainSuspendRequest.id);
D
Daniel P. Berrange 已提交
198
    if (ret < 0) {
199
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
200 201
            return -1;
    } else {
202
        out->type = QEMUD_SERVER_PKT_DOMAIN_SUSPEND;
D
Daniel P. Berrange 已提交
203 204 205 206
    }
    return 0;
}

207 208
static int qemudDispatchDomainResume(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    int ret = qemudDomainResume(qemu_driver, in->qemud_packet_client_data_u.domainResumeRequest.id);
D
Daniel P. Berrange 已提交
209
    if (ret < 0) {
210
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
211 212
            return -1;
    } else {
213
        out->type = QEMUD_SERVER_PKT_DOMAIN_RESUME;
D
Daniel P. Berrange 已提交
214 215 216 217
    }
    return 0;
}

218 219 220
static int qemudDispatchDomainDestroy(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    if (qemudDomainDestroy(qemu_driver, in->qemud_packet_client_data_u.domainDestroyRequest.id) < 0) {
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
221 222
            return -1;
    } else {
223
        out->type = QEMUD_SERVER_PKT_DOMAIN_DESTROY;
D
Daniel P. Berrange 已提交
224 225 226 227
    }
    return 0;
}

228
static int qemudDispatchDomainGetInfo(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
229 230 231 232 233 234
    int runstate;
    unsigned long long cpuTime;
    unsigned long memory;
    unsigned long maxmem;
    unsigned int nrVirtCpu;

235
    int ret = qemudDomainGetInfo(qemu_driver, in->qemud_packet_client_data_u.domainGetInfoRequest.uuid,
D
Daniel P. Berrange 已提交
236 237 238 239 240 241
                                 &runstate,
                                 &cpuTime,
                                 &maxmem,
                                 &memory,
                                 &nrVirtCpu);
    if (ret < 0) {
242
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
243 244
            return -1;
    } else {
245 246 247 248 249 250
        out->type = QEMUD_SERVER_PKT_DOMAIN_GET_INFO;
        out->qemud_packet_server_data_u.domainGetInfoReply.runstate = runstate;
        out->qemud_packet_server_data_u.domainGetInfoReply.cpuTime = cpuTime;
        out->qemud_packet_server_data_u.domainGetInfoReply.maxmem = maxmem;
        out->qemud_packet_server_data_u.domainGetInfoReply.memory = memory;
        out->qemud_packet_server_data_u.domainGetInfoReply.nrVirtCpu = nrVirtCpu;
D
Daniel P. Berrange 已提交
251 252 253 254
    }
    return 0;
}

255
static int qemudDispatchDomainSave(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
256
    /* Paranoia NULL termination */
257
    in->qemud_packet_client_data_u.domainSaveRequest.file[PATH_MAX-1] ='\0';
D
Daniel P. Berrange 已提交
258

259
    int ret = qemudDomainSave(qemu_driver,
260 261
                              in->qemud_packet_client_data_u.domainSaveRequest.id,
                              in->qemud_packet_client_data_u.domainSaveRequest.file);
D
Daniel P. Berrange 已提交
262
    if (ret < 0) {
263
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
264 265
            return -1;
    } else {
266
        out->type = QEMUD_SERVER_PKT_DOMAIN_SAVE;
D
Daniel P. Berrange 已提交
267 268 269 270
    }
    return 0;
}

271
static int qemudDispatchDomainRestore(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
272 273 274
    int id;

    /* Paranoia null termination */
275
    in->qemud_packet_client_data_u.domainRestoreRequest.file[PATH_MAX-1] ='\0';
D
Daniel P. Berrange 已提交
276

277
    id = qemudDomainRestore(qemu_driver, in->qemud_packet_client_data_u.domainRestoreRequest.file);
D
Daniel P. Berrange 已提交
278
    if (id < 0) {
279
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
280 281
            return -1;
    } else {
282 283
        out->type = QEMUD_SERVER_PKT_DOMAIN_RESTORE;
        out->qemud_packet_server_data_u.domainRestoreReply.id = id;
D
Daniel P. Berrange 已提交
284 285 286 287
    }
    return 0;
}

288
static int qemudDispatchDumpXML(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
289
    int ret;
290
    ret = qemudDomainDumpXML(qemu_driver,
291 292
                             in->qemud_packet_client_data_u.domainDumpXMLRequest.uuid,
                             out->qemud_packet_server_data_u.domainDumpXMLReply.xml,
D
Daniel P. Berrange 已提交
293 294
                             QEMUD_MAX_XML_LEN);
    if (ret < 0) {
295
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
296 297
            return -1;
    } else {
298
        out->type = QEMUD_SERVER_PKT_DUMP_XML;
D
Daniel P. Berrange 已提交
299 300 301 302
    }
    return 0;
}

303
static int qemudDispatchListDefinedDomains(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
304 305 306 307 308 309 310
    char **names;
    int i, ndomains;

    if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_DOMAINS)))
        return -1;

    for (i = 0 ; i < QEMUD_MAX_NUM_DOMAINS ; i++) {
311
        names[i] = &out->qemud_packet_server_data_u.listDefinedDomainsReply.domains[i*QEMUD_MAX_NAME_LEN];
D
Daniel P. Berrange 已提交
312 313
    }

314
    ndomains = qemudListDefinedDomains(qemu_driver,
D
Daniel P. Berrange 已提交
315 316 317 318
                                       names,
                                       QEMUD_MAX_NUM_DOMAINS);
    free(names);
    if (ndomains < 0) {
319
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
320 321
            return -1;
    } else {
322 323 324 325 326 327
        out->type = QEMUD_SERVER_PKT_LIST_DEFINED_DOMAINS;
        out->qemud_packet_server_data_u.listDefinedDomainsReply.numDomains = ndomains;
    }
    printf("%d %d\n", out->type, out->qemud_packet_server_data_u.listDefinedDomainsReply.numDomains);
    for (i = 0 ; i < ndomains;i++) {
        printf("[%s]\n", &out->qemud_packet_server_data_u.listDefinedDomainsReply.domains[i*QEMUD_MAX_NAME_LEN]);
D
Daniel P. Berrange 已提交
328 329 330 331
    }
    return 0;
}

332 333
static int qemudDispatchNumDefinedDomains(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
    int ndomains = qemudNumDefinedDomains(qemu_driver);
D
Daniel P. Berrange 已提交
334
    if (ndomains < 0) {
335
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
336 337
            return -1;
    } else {
338 339
        out->type = QEMUD_SERVER_PKT_NUM_DEFINED_DOMAINS;
        out->qemud_packet_server_data_u.numDefinedDomainsReply.numDomains = ndomains;
D
Daniel P. Berrange 已提交
340 341 342 343
    }
    return 0;
}

344
static int qemudDispatchDomainStart(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
345 346
    struct qemud_vm *vm;

347 348
    if (!(vm = qemudDomainStart(qemu_driver, in->qemud_packet_client_data_u.domainStartRequest.uuid))) {
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
349 350
            return -1;
    } else {
351 352
        out->type = QEMUD_SERVER_PKT_DOMAIN_START;
        out->qemud_packet_server_data_u.domainStartReply.id = vm->id;
D
Daniel P. Berrange 已提交
353 354 355 356
    }
    return 0;
}

357
static int qemudDispatchDomainDefine(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
358
    in->qemud_packet_client_data_u.domainDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0';
D
Daniel P. Berrange 已提交
359

360
    struct qemud_vm *vm = qemudDomainDefine(qemu_driver, in->qemud_packet_client_data_u.domainDefineRequest.xml);
D
Daniel P. Berrange 已提交
361
    if (!vm) {
362
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
363 364
            return -1;
    } else {
365 366 367 368
        out->type = QEMUD_SERVER_PKT_DOMAIN_DEFINE;
        memcpy(out->qemud_packet_server_data_u.domainDefineReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
        strncpy(out->qemud_packet_server_data_u.domainDefineReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.domainDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
D
Daniel P. Berrange 已提交
369 370 371 372
    }
    return 0;
}

373 374
static int qemudDispatchDomainUndefine(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    int ret = qemudDomainUndefine(qemu_driver, in->qemud_packet_client_data_u.domainUndefineRequest.uuid);
D
Daniel P. Berrange 已提交
375
    if (ret < 0) {
376
        if (qemudDispatchFailure(out) < 0)
D
Daniel P. Berrange 已提交
377 378
            return -1;
    } else {
379
        out->type = QEMUD_SERVER_PKT_DOMAIN_UNDEFINE;
D
Daniel P. Berrange 已提交
380 381 382 383
    }
    return 0;
}

384 385
static int qemudDispatchNumNetworks(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
    int nnetworks = qemudNumNetworks(qemu_driver);
386
    if (nnetworks < 0) {
387
        if (qemudDispatchFailure(out) < 0)
388 389
            return -1;
    } else {
390 391
        out->type = QEMUD_SERVER_PKT_NUM_NETWORKS;
        out->qemud_packet_server_data_u.numNetworksReply.numNetworks = nnetworks;
392 393 394 395
    }
    return 0;
}

396
static int qemudDispatchListNetworks(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
397 398 399 400 401 402 403
    char **names;
    int i;

    if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_NETWORKS)))
        return -1;

    for (i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i++) {
404
        names[i] = &out->qemud_packet_server_data_u.listNetworksReply.networks[i*QEMUD_MAX_NAME_LEN];
405 406
    }

407
    int nnetworks = qemudListNetworks(qemu_driver,
408 409 410 411
                                      names,
                                      QEMUD_MAX_NUM_NETWORKS);
    free(names);
    if (nnetworks < 0) {
412
        if (qemudDispatchFailure(out) < 0)
413 414
            return -1;
    } else {
415 416
        out->type = QEMUD_SERVER_PKT_LIST_NETWORKS;
        out->qemud_packet_server_data_u.listNetworksReply.numNetworks = nnetworks;
417 418 419 420
    }
    return 0;
}

421 422
static int qemudDispatchNumDefinedNetworks(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
    int nnetworks = qemudNumDefinedNetworks(qemu_driver);
423
    if (nnetworks < 0) {
424
        if (qemudDispatchFailure(out) < 0)
425 426
            return -1;
    } else {
427 428
        out->type = QEMUD_SERVER_PKT_NUM_DEFINED_NETWORKS;
        out->qemud_packet_server_data_u.numDefinedNetworksReply.numNetworks = nnetworks;
429 430 431 432
    }
    return 0;
}

433
static int qemudDispatchListDefinedNetworks(struct qemud_packet_client_data *in ATTRIBUTE_UNUSED, struct qemud_packet_server_data *out) {
434 435 436 437 438 439 440
    char **names;
    int i;

    if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_NETWORKS)))
        return -1;

    for (i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i++) {
441
        names[i] = &out->qemud_packet_server_data_u.listDefinedNetworksReply.networks[i*QEMUD_MAX_NAME_LEN];
442 443
    }

444
    int nnetworks = qemudListDefinedNetworks(qemu_driver,
445 446 447 448
                                             names,
                                             QEMUD_MAX_NUM_NETWORKS);
    free(names);
    if (nnetworks < 0) {
449
        if (qemudDispatchFailure(out) < 0)
450 451
            return -1;
    } else {
452 453
        out->type = QEMUD_SERVER_PKT_LIST_DEFINED_NETWORKS;
        out->qemud_packet_server_data_u.listDefinedNetworksReply.numNetworks = nnetworks;
454 455 456 457
    }
    return 0;
}

458
static int qemudDispatchNetworkLookupByName(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
459
    /* Paranoia NULL termination */
460
    in->qemud_packet_client_data_u.networkLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0';
461
    struct qemud_network *network = qemudFindNetworkByName(qemu_driver, in->qemud_packet_client_data_u.networkLookupByNameRequest.name);
462
    if (!network) {
463
        if (qemudDispatchFailure(out) < 0)
464 465
            return -1;
    } else {
466 467
        out->type = QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_NAME;
        memcpy(out->qemud_packet_server_data_u.networkLookupByNameReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN);
468 469 470 471
    }
    return 0;
}

472 473
static int qemudDispatchNetworkLookupByUUID(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    struct qemud_network *network = qemudFindNetworkByUUID(qemu_driver, in->qemud_packet_client_data_u.networkLookupByUUIDRequest.uuid);
474
    if (!network) {
475
        if (qemudDispatchFailure(out) < 0)
476 477
            return -1;
    } else {
478 479 480
        out->type = QEMUD_SERVER_PKT_NETWORK_LOOKUP_BY_UUID;
        strncpy(out->qemud_packet_server_data_u.networkLookupByUUIDReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
481 482 483 484
    }
    return 0;
}

485
static int qemudDispatchNetworkCreate(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
486
    in->qemud_packet_client_data_u.networkCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0';
487

488
    struct qemud_network *network = qemudNetworkCreate(qemu_driver, in->qemud_packet_client_data_u.networkCreateRequest.xml);
489
    if (!network) {
490
        if (qemudDispatchFailure(out) < 0)
491 492
            return -1;
    } else {
493 494 495 496
        out->type = QEMUD_SERVER_PKT_NETWORK_CREATE;
        memcpy(out->qemud_packet_server_data_u.networkCreateReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN);
        strncpy(out->qemud_packet_server_data_u.networkCreateReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
497 498 499 500
    }
    return 0;
}

501
static int qemudDispatchNetworkDefine(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
502
    in->qemud_packet_client_data_u.networkDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0';
503

504
    struct qemud_network *network = qemudNetworkDefine(qemu_driver, in->qemud_packet_client_data_u.networkDefineRequest.xml);
505
    if (!network) {
506
        if (qemudDispatchFailure(out) < 0)
507 508
            return -1;
    } else {
509 510 511 512
        out->type = QEMUD_SERVER_PKT_NETWORK_DEFINE;
        memcpy(out->qemud_packet_server_data_u.networkDefineReply.uuid, network->def->uuid, QEMUD_UUID_RAW_LEN);
        strncpy(out->qemud_packet_server_data_u.networkDefineReply.name, network->def->name, QEMUD_MAX_NAME_LEN-1);
        out->qemud_packet_server_data_u.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
513 514 515 516
    }
    return 0;
}

517 518
static int qemudDispatchNetworkUndefine(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    int ret = qemudNetworkUndefine(qemu_driver, in->qemud_packet_client_data_u.networkUndefineRequest.uuid);
519
    if (ret < 0) {
520
        if (qemudDispatchFailure(out) < 0)
521 522
            return -1;
    } else {
523
        out->type = QEMUD_SERVER_PKT_NETWORK_UNDEFINE;
524 525 526 527
    }
    return 0;
}

528
static int qemudDispatchNetworkStart(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
529 530
    struct qemud_network *network;

531 532
    if (!(network = qemudNetworkStart(qemu_driver, in->qemud_packet_client_data_u.networkStartRequest.uuid))) {
        if (qemudDispatchFailure(out) < 0)
533 534
            return -1;
    } else {
535
        out->type = QEMUD_SERVER_PKT_NETWORK_START;
536 537 538 539
    }
    return 0;
}

540 541 542
static int qemudDispatchNetworkDestroy(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    if (qemudNetworkDestroy(qemu_driver, in->qemud_packet_client_data_u.networkDestroyRequest.uuid) < 0) {
        if (qemudDispatchFailure(out) < 0)
543 544
            return -1;
    } else {
545
        out->type = QEMUD_SERVER_PKT_NETWORK_DESTROY;
546 547 548 549
    }
    return 0;
}

550 551
static int qemudDispatchNetworkDumpXML(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    int ret = qemudNetworkDumpXML(qemu_driver,
552 553
                                  in->qemud_packet_client_data_u.networkDumpXMLRequest.uuid,
                                  out->qemud_packet_server_data_u.networkDumpXMLReply.xml, QEMUD_MAX_XML_LEN);
554
    if (ret < 0) {
555
        if (qemudDispatchFailure(out) < 0)
556 557
            return -1;
    } else {
558
        out->type = QEMUD_SERVER_PKT_NETWORK_DUMP_XML;
559 560 561 562
    }
    return 0;
}

563 564
static int qemudDispatchNetworkGetBridgeName(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out) {
    int ret = qemudNetworkGetBridgeName(qemu_driver,
565 566
                                        in->qemud_packet_client_data_u.networkDumpXMLRequest.uuid,
                                        out->qemud_packet_server_data_u.networkGetBridgeNameReply.ifname, QEMUD_MAX_IFNAME_LEN);
567
    if (ret < 0) {
568
        if (qemudDispatchFailure(out) < 0)
569 570
            return -1;
    } else {
571
        out->type = QEMUD_SERVER_PKT_NETWORK_GET_BRIDGE_NAME;
572 573 574 575
    }
    return 0;
}

576
static int qemudDispatchDomainGetAutostart(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out)
577 578 579 580 581 582
{
    int ret;
    int autostart;

    autostart = 0;

583
    ret = qemudDomainGetAutostart(qemu_driver,
584
                                  in->qemud_packet_client_data_u.domainGetAutostartRequest.uuid,
585 586
                                  &autostart);
    if (ret < 0) {
587
        if (qemudDispatchFailure(out) < 0)
588 589
            return -1;
    } else {
590 591
        out->type = QEMUD_SERVER_PKT_DOMAIN_GET_AUTOSTART;
        out->qemud_packet_server_data_u.networkGetAutostartReply.autostart = (autostart != 0);
592 593 594 595
    }
    return 0;
}

596
static int qemudDispatchDomainSetAutostart(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out)
597 598 599
{
    int ret;

600
    ret = qemudDomainSetAutostart(qemu_driver,
601 602
                                  in->qemud_packet_client_data_u.domainGetAutostartRequest.uuid,
                                  in->qemud_packet_client_data_u.domainSetAutostartRequest.autostart);
603
    if (ret < 0) {
604
        if (qemudDispatchFailure(out) < 0)
605 606
            return -1;
    } else {
607
        out->type = QEMUD_SERVER_PKT_DOMAIN_SET_AUTOSTART;
608 609 610 611
    }
    return 0;
}

612
static int qemudDispatchNetworkGetAutostart(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out)
613 614 615 616 617 618
{
    int ret;
    int autostart;

    autostart = 0;

619
    ret = qemudNetworkGetAutostart(qemu_driver,
620
                                   in->qemud_packet_client_data_u.networkGetAutostartRequest.uuid,
621 622
                                   &autostart);
    if (ret < 0) {
623
        if (qemudDispatchFailure(out) < 0)
624 625
            return -1;
    } else {
626 627
        out->type = QEMUD_SERVER_PKT_NETWORK_GET_AUTOSTART;
        out->qemud_packet_server_data_u.networkGetAutostartReply.autostart = (autostart != 0);
628 629 630 631
    }
    return 0;
}

632
static int qemudDispatchNetworkSetAutostart(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out)
633 634 635
{
    int ret;

636
    ret = qemudNetworkSetAutostart(qemu_driver,
637 638
                                   in->qemud_packet_client_data_u.networkGetAutostartRequest.uuid,
                                   in->qemud_packet_client_data_u.networkSetAutostartRequest.autostart);
639
    if (ret < 0) {
640
        if (qemudDispatchFailure(out) < 0)
641 642
            return -1;
    } else {
643
        out->type = QEMUD_SERVER_PKT_NETWORK_SET_AUTOSTART;
644 645 646
    }
    return 0;
}
D
Daniel P. Berrange 已提交
647

648
typedef int (*clientFunc)(struct qemud_packet_client_data *in, struct qemud_packet_server_data *out);
D
Daniel P. Berrange 已提交
649 650 651 652


/* One per message type recorded in qemud_packet_type enum */

653
clientFunc funcsTransmitRW[QEMUD_CLIENT_PKT_MAX] = {
D
Daniel P. Berrange 已提交
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
    qemudDispatchGetVersion,
    qemudDispatchGetNodeInfo,
    qemudDispatchListDomains,
    qemudDispatchNumDomains,
    qemudDispatchDomainCreate,
    qemudDispatchDomainLookupByID,
    qemudDispatchDomainLookupByUUID,
    qemudDispatchDomainLookupByName,
    qemudDispatchDomainSuspend,
    qemudDispatchDomainResume,
    qemudDispatchDomainDestroy,
    qemudDispatchDomainGetInfo,
    qemudDispatchDomainSave,
    qemudDispatchDomainRestore,
    qemudDispatchDumpXML,
    qemudDispatchListDefinedDomains,
    qemudDispatchNumDefinedDomains,
    qemudDispatchDomainStart,
    qemudDispatchDomainDefine,
673 674 675 676 677 678 679 680 681 682 683 684 685
    qemudDispatchDomainUndefine,
    qemudDispatchNumNetworks,
    qemudDispatchListNetworks,
    qemudDispatchNumDefinedNetworks,
    qemudDispatchListDefinedNetworks,
    qemudDispatchNetworkLookupByUUID,
    qemudDispatchNetworkLookupByName,
    qemudDispatchNetworkCreate,
    qemudDispatchNetworkDefine,
    qemudDispatchNetworkUndefine,
    qemudDispatchNetworkStart,
    qemudDispatchNetworkDestroy,
    qemudDispatchNetworkDumpXML,
686
    qemudDispatchNetworkGetBridgeName,
687 688 689 690
    qemudDispatchDomainGetAutostart,
    qemudDispatchDomainSetAutostart,
    qemudDispatchNetworkGetAutostart,
    qemudDispatchNetworkSetAutostart,
691
    qemudDispatchGetCapabilities,
D
Daniel P. Berrange 已提交
692 693
};

694
clientFunc funcsTransmitRO[QEMUD_CLIENT_PKT_MAX] = {
D
Daniel P. Berrange 已提交
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
    qemudDispatchGetVersion,
    qemudDispatchGetNodeInfo,
    qemudDispatchListDomains,
    qemudDispatchNumDomains,
    NULL,
    qemudDispatchDomainLookupByID,
    qemudDispatchDomainLookupByUUID,
    qemudDispatchDomainLookupByName,
    NULL,
    NULL,
    NULL,
    qemudDispatchDomainGetInfo,
    NULL,
    NULL,
    qemudDispatchDumpXML,
    qemudDispatchListDefinedDomains,
    qemudDispatchNumDefinedDomains,
    NULL,
    NULL,
    NULL,
715 716 717 718 719 720 721 722 723 724 725 726
    qemudDispatchNumNetworks,
    qemudDispatchListNetworks,
    qemudDispatchNumDefinedNetworks,
    qemudDispatchListDefinedNetworks,
    qemudDispatchNetworkLookupByUUID,
    qemudDispatchNetworkLookupByName,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    qemudDispatchNetworkDumpXML,
727
    qemudDispatchNetworkGetBridgeName,
728 729 730 731
    qemudDispatchDomainGetAutostart,
    NULL,
    qemudDispatchNetworkGetAutostart,
    NULL,
D
Daniel P. Berrange 已提交
732 733 734 735 736 737 738 739 740 741 742 743
};

/*
 * Returns -1 if message processing failed - eg, illegal header sizes,
 * a memory error dealing with stuff, or any other bad stuff which
 * should trigger immediate client disconnect
 *
 * Return 0 if message processing succeeded. NB, this does not mean
 * the operation itself succeeded - success/failure of the operation
 * is recorded by the return message type - either it matches the
 * incoming type, or is QEMUD_PKT_FAILURE
 */
744 745 746

int qemudDispatch(struct qemud_server *server ATTRIBUTE_UNUSED,
                  struct qemud_client *client,
747
                  qemud_packet_client_data *in, qemud_packet_server_data *out) {
D
Daniel P. Berrange 已提交
748
    clientFunc *funcs;
749 750 751
    unsigned int type = in->type;
    qemudDebug("> Dispatching request type %d, readonly ? %d",
               in->type, client->readonly);
D
Daniel P. Berrange 已提交
752

753
    virResetLastError();
D
Daniel P. Berrange 已提交
754

755
    memset(out, 0, sizeof(*out));
D
Daniel P. Berrange 已提交
756

757
    if (type >= QEMUD_CLIENT_PKT_MAX) {
758
        qemudDebug("Illegal request type");
D
Daniel P. Berrange 已提交
759 760 761 762 763 764 765 766 767
        return -1;
    }

    if (client->readonly)
        funcs = funcsTransmitRO;
    else
        funcs = funcsTransmitRW;

    if (!funcs[type]) {
768
        qemudDebug("Illegal operation requested");
769
        qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_DENIED, NULL);
770
        qemudDispatchFailure(out);
D
Daniel P. Berrange 已提交
771
    } else {
772
        if ((funcs[type])(in, out) < 0) {
773
            qemudDebug("Dispatch failed");
D
Daniel P. Berrange 已提交
774 775 776 777
            return -1;
        }
    }

778
    qemudDebug("< Returning reply %d", out->type);
D
Daniel P. Berrange 已提交
779 780 781 782 783 784 785 786 787 788 789 790

    return 0;
}

/*
 * Local variables:
 *  indent-tabs-mode: nil
 *  c-indent-level: 4
 *  c-basic-offset: 4
 *  tab-width: 4
 * End:
 */