test.c 94.2 KB
Newer Older
1 2 3
/*
 * test.c: A "mock" hypervisor for use by application unit tests
 *
4
 * Copyright (C) 2006-2008 Red Hat, Inc.
5
 * Copyright (C) 2006 Daniel P. Berrange
6
 *
7 8 9 10 11 12 13 14 15 16 17 18 19
 * 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
20 21 22 23
 *
 * Daniel Berrange <berrange@redhat.com>
 */

24
#include <config.h>
25

26 27 28
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
29 30
#include <fcntl.h>
#include <unistd.h>
31
#include <sys/stat.h>
C
Cole Robinson 已提交
32
#include <libxml/xmlsave.h>
33

34 35

#include "virterror_internal.h"
36
#include "datatypes.h"
37
#include "test.h"
38
#include "buf.h"
39
#include "util.h"
40
#include "uuid.h"
41
#include "capabilities.h"
42
#include "memory.h"
43
#include "network_conf.h"
44
#include "domain_conf.h"
C
Cole Robinson 已提交
45
#include "storage_conf.h"
46
#include "xml.h"
47

48 49 50 51 52 53 54 55 56 57 58
#define MAX_CPUS 128

struct _testCell {
    unsigned long mem;
    int numCpus;
    int cpus[MAX_CPUS];
};
typedef struct _testCell testCell;
typedef struct _testCell *testCellPtr;

#define MAX_CELLS 128
59

60
struct _testConn {
61 62
    PTHREAD_MUTEX_T(lock);

63 64
    char path[PATH_MAX];
    int nextDomID;
65
    virCapsPtr caps;
66
    virNodeInfo nodeInfo;
67
    virDomainObjList domains;
68
    virNetworkObjList networks;
C
Cole Robinson 已提交
69
    virStoragePoolObjList pools;
70 71
    int numCells;
    testCell cells[MAX_CELLS];
72 73 74
};
typedef struct _testConn testConn;
typedef struct _testConn *testConnPtr;
75

76
#define TEST_MODEL "i686"
77
#define TEST_MODEL_WORDSIZE 32
78
#define TEST_EMULATOR "/usr/bin/test-hv"
79

80
static const virNodeInfo defaultNodeInfo = {
81
    TEST_MODEL,
82 83 84 85 86 87 88
    1024*1024*3, /* 3 GB */
    16,
    1400,
    2,
    2,
    2,
    2,
89 90
};

91

92
#define testError(conn, code, fmt...)                               \
93
        virReportErrorHelper(conn, VIR_FROM_TEST, code, __FILE__, \
94
                               __FUNCTION__, __LINE__, fmt)
95

96 97 98 99 100 101 102 103 104 105
static void testDriverLock(testConnPtr driver)
{
    pthread_mutex_lock(&driver->lock);
}

static void testDriverUnlock(testConnPtr driver)
{
    pthread_mutex_unlock(&driver->lock);
}

106 107
static virCapsPtr
testBuildCapabilities(virConnectPtr conn) {
108
    testConnPtr privconn = conn->privateData;
109 110 111 112
    virCapsPtr caps;
    virCapsGuestPtr guest;
    const char *const guest_types[] = { "hvm", "xen" };
    int i;
113

114 115
    if ((caps = virCapabilitiesNew(TEST_MODEL, 0, 0)) == NULL)
        goto no_memory;
116

117 118 119 120
    if (virCapabilitiesAddHostFeature(caps, "pae") < 0)
        goto no_memory;
    if (virCapabilitiesAddHostFeature(caps ,"nonpae") < 0)
        goto no_memory;
121

122 123 124 125
    for (i = 0; i < privconn->numCells; i++) {
        if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].numCpus,
                                           privconn->cells[i].cpus) < 0)
            goto no_memory;
126 127
    }

128 129 130 131 132 133 134 135 136 137
    for (i = 0; i < ARRAY_CARDINALITY(guest_types) ; i++) {
        if ((guest = virCapabilitiesAddGuest(caps,
                                             guest_types[i],
                                             TEST_MODEL,
                                             TEST_MODEL_WORDSIZE,
                                             TEST_EMULATOR,
                                             NULL,
                                             0,
                                             NULL)) == NULL)
            goto no_memory;
138

139 140 141 142 143 144 145
        if (virCapabilitiesAddGuestDomain(guest,
                                          "test",
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL)
            goto no_memory;
146

147 148 149 150
        if (virCapabilitiesAddGuestFeature(guest, "pae", 1, 1) == NULL)
            goto no_memory;
        if (virCapabilitiesAddGuestFeature(guest ,"nonpae", 1, 1) == NULL)
            goto no_memory;
151 152
    }

153
    return caps;
154

155
no_memory:
156
    testError(conn, VIR_ERR_NO_MEMORY, NULL);
157 158
    virCapabilitiesFree(caps);
    return NULL;
159 160
}

161

162 163 164 165 166 167 168 169 170 171
static const char *defaultDomainXML =
"<domain type='test'>"
"  <name>test</name>"
"  <memory>8388608</memory>"
"  <currentMemory>2097152</currentMemory>"
"  <vcpu>2</vcpu>"
"  <os>"
"    <type>hvm</type>"
"  </os>"
"</domain>";
172 173


174 175 176 177 178 179 180 181 182 183 184
static const char *defaultNetworkXML =
"<network>"
"  <name>default</name>"
"  <bridge name='virbr0' />"
"  <forward/>"
"  <ip address='192.168.122.1' netmask='255.255.255.0'>"
"    <dhcp>"
"      <range start='192.168.122.2' end='192.168.122.254' />"
"    </dhcp>"
"  </ip>"
"</network>";
185

C
Cole Robinson 已提交
186 187 188 189 190 191 192 193 194 195 196 197
static const char *defaultPoolXML =
"<pool type='dir'>"
"  <name>default-pool</name>"
"  <target>"
"    <path>/default-pool</path>"
"  </target>"
"</pool>";

static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ul);
static const unsigned long long defaultPoolAlloc = 0;

static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool);
198

199
static int testOpenDefault(virConnectPtr conn) {
200 201
    int u;
    struct timeval tv;
202
    testConnPtr privconn;
203 204 205 206
    virDomainDefPtr domdef = NULL;
    virDomainObjPtr domobj = NULL;
    virNetworkDefPtr netdef = NULL;
    virNetworkObjPtr netobj = NULL;
C
Cole Robinson 已提交
207 208
    virStoragePoolDefPtr pooldef = NULL;
    virStoragePoolObjPtr poolobj = NULL;
209

210
    if (VIR_ALLOC(privconn) < 0) {
211
        testError(conn, VIR_ERR_NO_MEMORY, "testConn");
212 213
        return VIR_DRV_OPEN_ERROR;
    }
214
    conn->privateData = privconn;
215 216
    pthread_mutex_init(&privconn->lock, NULL);
    testDriverLock(privconn);
217 218

    if (gettimeofday(&tv, NULL) < 0) {
J
Jim Meyering 已提交
219
        testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("getting time of day"));
220
        goto error;
221 222
    }

223
    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
224

225 226 227 228 229 230 231 232 233 234
    // Numa setup
    privconn->numCells = 2;
    for (u = 0; u < 2; ++u) {
        privconn->cells[u].numCpus = 8;
        privconn->cells[u].mem = (u + 1) * 2048 * 1024;
    }
    for (u = 0 ; u < 16 ; u++) {
        privconn->cells[u % 2].cpus[(u / 2)] = u;
    }

235 236 237 238 239 240 241 242 243 244 245
    if (!(privconn->caps = testBuildCapabilities(conn)))
        goto error;

    privconn->nextDomID = 1;

    if (!(domdef = virDomainDefParseString(conn, privconn->caps, defaultDomainXML)))
        goto error;
    if (!(domobj = virDomainAssignDef(conn, &privconn->domains, domdef))) {
        virDomainDefFree(domdef);
        goto error;
    }
246
    domobj->def->id = privconn->nextDomID++;
247 248
    domobj->state = VIR_DOMAIN_RUNNING;
    domobj->persistent = 1;
249
    virDomainObjUnlock(domobj);
250 251 252 253 254 255 256 257 258

    if (!(netdef = virNetworkDefParseString(conn, defaultNetworkXML)))
        goto error;
    if (!(netobj = virNetworkAssignDef(conn, &privconn->networks, netdef))) {
        virNetworkDefFree(netdef);
        goto error;
    }
    netobj->active = 1;
    netobj->persistent = 1;
259
    virNetworkObjUnlock(netobj);
260

C
Cole Robinson 已提交
261 262 263 264 265 266 267 268
    if (!(pooldef = virStoragePoolDefParse(conn, defaultPoolXML, NULL)))
        goto error;

    if (!(poolobj = virStoragePoolObjAssignDef(conn, &privconn->pools,
                                               pooldef))) {
        virStoragePoolDefFree(pooldef);
        goto error;
    }
269 270 271

    if (testStoragePoolObjSetDefaults(poolobj) == -1) {
        virStoragePoolObjUnlock(poolobj);
C
Cole Robinson 已提交
272
        goto error;
273
    }
C
Cole Robinson 已提交
274
    poolobj->active = 1;
275
    virStoragePoolObjUnlock(poolobj);
C
Cole Robinson 已提交
276

277
    testDriverUnlock(privconn);
278 279 280
    return VIR_DRV_OPEN_SUCCESS;

error:
281
    virDomainObjListFree(&privconn->domains);
282
    virNetworkObjListFree(&privconn->networks);
C
Cole Robinson 已提交
283
    virStoragePoolObjListFree(&privconn->pools);
284
    virCapabilitiesFree(privconn->caps);
285
    testDriverUnlock(privconn);
286 287
    VIR_FREE(privconn);
    return VIR_DRV_OPEN_ERROR;
288 289 290 291
}


static char *testBuildFilename(const char *relativeTo,
292 293 294 295 296 297 298 299
                               const char *filename) {
    char *offset;
    int baseLen;
    if (!filename || filename[0] == '\0')
        return (NULL);
    if (filename[0] == '/')
        return strdup(filename);

300
    offset = strrchr(relativeTo, '/');
301
    if ((baseLen = (offset-relativeTo+1))) {
302 303 304
        char *absFile;
        if (VIR_ALLOC_N(absFile, baseLen + strlen(filename) + 1) < 0)
            return NULL;
305 306 307 308 309 310 311
        strncpy(absFile, relativeTo, baseLen);
        absFile[baseLen] = '\0';
        strcat(absFile, filename);
        return absFile;
    } else {
        return strdup(filename);
    }
312 313 314
}

static int testOpenFromFile(virConnectPtr conn,
315
                            const char *file) {
316
    int fd = -1, i, ret;
317 318
    long l;
    char *str;
319
    xmlDocPtr xml = NULL;
320
    xmlNodePtr root = NULL;
C
Cole Robinson 已提交
321
    xmlNodePtr *domains = NULL, *networks = NULL, *pools = NULL;
322 323
    xmlXPathContextPtr ctxt = NULL;
    virNodeInfoPtr nodeInfo;
324 325
    virNetworkObjPtr net;
    virDomainObjPtr dom;
326 327
    testConnPtr privconn;
    if (VIR_ALLOC(privconn) < 0) {
328
        testError(NULL, VIR_ERR_NO_MEMORY, "testConn");
329 330
        return VIR_DRV_OPEN_ERROR;
    }
331
    conn->privateData = privconn;
332 333
    pthread_mutex_init(&privconn->lock, NULL);
    testDriverLock(privconn);
334 335 336

    if (!(privconn->caps = testBuildCapabilities(conn)))
        goto error;
337 338

    if ((fd = open(file, O_RDONLY)) < 0) {
C
Cole Robinson 已提交
339 340 341
        testError(NULL, VIR_ERR_INTERNAL_ERROR,
                  _("loading host definition file '%s': %s"),
                  file, strerror(errno));
342
        goto error;
343 344
    }

345 346 347
    if (!(xml = xmlReadFd(fd, file, NULL,
                          XML_PARSE_NOENT | XML_PARSE_NONET |
                          XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
J
Jim Meyering 已提交
348
        testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("host"));
349
        goto error;
350
    }
351 352
    close(fd);
    fd = -1;
353

354 355
    root = xmlDocGetRootElement(xml);
    if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
J
Jim Meyering 已提交
356
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node"));
357
        goto error;
358 359
    }

360 361
    ctxt = xmlXPathNewContext(xml);
    if (ctxt == NULL) {
C
Cole Robinson 已提交
362 363
        testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
                  _("creating xpath context"));
364
        goto error;
365
    }
366

367
    privconn->nextDomID = 1;
368
    privconn->numCells = 0;
369 370 371 372 373
    strncpy(privconn->path, file, PATH_MAX-1);
    privconn->path[PATH_MAX-1] = '\0';
    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));

    nodeInfo = &privconn->nodeInfo;
374
    ret = virXPathLong(conn, "string(/node/cpu/nodes[1])", ctxt, &l);
375 376 377
    if (ret == 0) {
        nodeInfo->nodes = l;
    } else if (ret == -2) {
J
Jim Meyering 已提交
378
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu numa nodes"));
379
        goto error;
380
    }
381

382
    ret = virXPathLong(conn, "string(/node/cpu/sockets[1])", ctxt, &l);
383 384 385
    if (ret == 0) {
        nodeInfo->sockets = l;
    } else if (ret == -2) {
J
Jim Meyering 已提交
386
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu sockets"));
387
        goto error;
388
    }
389

390
    ret = virXPathLong(conn, "string(/node/cpu/cores[1])", ctxt, &l);
391 392 393
    if (ret == 0) {
        nodeInfo->cores = l;
    } else if (ret == -2) {
J
Jim Meyering 已提交
394
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu cores"));
395
        goto error;
396 397
    }

398
    ret = virXPathLong(conn, "string(/node/cpu/threads[1])", ctxt, &l);
399 400 401
    if (ret == 0) {
        nodeInfo->threads = l;
    } else if (ret == -2) {
J
Jim Meyering 已提交
402
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu threads"));
403
        goto error;
404
    }
405

406
    nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
407
    ret = virXPathLong(conn, "string(/node/cpu/active[1])", ctxt, &l);
408 409
    if (ret == 0) {
        if (l < nodeInfo->cpus) {
410 411
            nodeInfo->cpus = l;
        }
412
    } else if (ret == -2) {
J
Jim Meyering 已提交
413
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node active cpu"));
414
        goto error;
415
    }
416
    ret = virXPathLong(conn, "string(/node/cpu/mhz[1])", ctxt, &l);
417 418 419
    if (ret == 0) {
        nodeInfo->mhz = l;
    } else if (ret == -2) {
J
Jim Meyering 已提交
420
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu mhz"));
421
        goto error;
422 423
    }

424
    str = virXPathString(conn, "string(/node/cpu/model[1])", ctxt);
425 426
    if (str != NULL) {
        strncpy(nodeInfo->model, str, sizeof(nodeInfo->model)-1);
427
        nodeInfo->model[sizeof(nodeInfo->model)-1] = '\0';
428
        VIR_FREE(str);
429 430
    }

431
    ret = virXPathLong(conn, "string(/node/memory[1])", ctxt, &l);
432 433 434
    if (ret == 0) {
        nodeInfo->memory = l;
    } else if (ret == -2) {
J
Jim Meyering 已提交
435
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node memory"));
436
        goto error;
437
    }
438

439
    ret = virXPathNodeSet(conn, "/node/domain", ctxt, &domains);
440
    if (ret < 0) {
J
Jim Meyering 已提交
441
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node domain list"));
442
        goto error;
443
    }
444

445
    for (i = 0 ; i < ret ; i++) {
446 447 448 449 450 451
        virDomainDefPtr def;
        char *relFile = virXMLPropString(domains[i], "file");
        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);
            if (!absFile) {
J
Jim Meyering 已提交
452
                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving domain filename"));
453 454
                goto error;
            }
455 456
            def = virDomainDefParseFile(conn, privconn->caps, absFile,
                                        VIR_DOMAIN_XML_INACTIVE);
457
            VIR_FREE(absFile);
458 459 460
            if (!def)
                goto error;
        } else {
461 462
            if ((def = virDomainDefParseNode(conn, privconn->caps, xml, domains[i],
                                   VIR_DOMAIN_XML_INACTIVE)) == NULL)
463 464 465 466 467
                goto error;
        }

        if (!(dom = virDomainAssignDef(conn, &privconn->domains, def))) {
            virDomainDefFree(def);
468 469
            goto error;
        }
470 471 472 473

        dom->state = VIR_DOMAIN_RUNNING;
        dom->def->id = privconn->nextDomID++;
        dom->persistent = 1;
474
        virDomainObjUnlock(dom);
475
    }
476
    if (domains != NULL)
477
        VIR_FREE(domains);
478

479
    ret = virXPathNodeSet(conn, "/node/network", ctxt, &networks);
480
    if (ret < 0) {
J
Jim Meyering 已提交
481
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node network list"));
482 483 484 485 486 487 488 489
        goto error;
    }
    for (i = 0 ; i < ret ; i++) {
        virNetworkDefPtr def;
        char *relFile = virXMLPropString(networks[i], "file");
        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);
490
            if (!absFile) {
J
Jim Meyering 已提交
491
                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving network filename"));
492 493
                goto error;
            }
494 495

            def = virNetworkDefParseFile(conn, absFile);
496
            VIR_FREE(absFile);
497 498 499 500 501
            if (!def)
                goto error;
        } else {
            if ((def = virNetworkDefParseNode(conn, xml, networks[i])) == NULL)
                goto error;
502
        }
503 504 505 506
        if (!(net = virNetworkAssignDef(conn, &privconn->networks,
                                        def))) {
            virNetworkDefFree(def);
            goto error;
507
        }
508
        net->persistent = 1;
509
        virNetworkObjUnlock(net);
510
    }
511
    if (networks != NULL)
512
        VIR_FREE(networks);
513

C
Cole Robinson 已提交
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
    /* Parse Storage Pool list */
    ret = virXPathNodeSet(conn, "/node/pool", ctxt, &pools);
    if (ret < 0) {
        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node pool list"));
        goto error;
    }
    for (i = 0 ; i < ret ; i++) {
        virStoragePoolDefPtr def;
        virStoragePoolObjPtr pool;
        char *relFile = virXMLPropString(pools[i], "file");
        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);
            if (!absFile) {
                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
                          _("resolving pool filename"));
                goto error;
            }

            def = virStoragePoolDefParse(conn, NULL, absFile);
            VIR_FREE(absFile);
            if (!def)
                goto error;
        } else {
            xmlBufferPtr buf;
            xmlSaveCtxtPtr sctxt;

            buf = xmlBufferCreate();
            sctxt = xmlSaveToBuffer(buf, NULL, 0);
            xmlSaveTree(sctxt, pools[i]);
            xmlSaveClose(sctxt);
            if ((def = virStoragePoolDefParse(conn,
                                              (const char *) buf->content,
                                              NULL)) == NULL) {
                xmlBufferFree(buf);
                goto error;
            }
        }

        if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools,
                                                def))) {
            virStoragePoolDefFree(def);
            goto error;
        }

559 560
        if (testStoragePoolObjSetDefaults(pool) == -1) {
            virStoragePoolObjUnlock(pool);
C
Cole Robinson 已提交
561
            goto error;
562
        }
C
Cole Robinson 已提交
563
        pool->active = 1;
564
        virStoragePoolObjUnlock(pool);
C
Cole Robinson 已提交
565 566 567 568
    }
    if (pools != NULL)
        VIR_FREE(pools);

J
Jim Meyering 已提交
569
    xmlXPathFreeContext(ctxt);
570
    xmlFreeDoc(xml);
571
    testDriverUnlock(privconn);
572

573
    return (0);
574 575

 error:
J
Jim Meyering 已提交
576
    xmlXPathFreeContext(ctxt);
577
    xmlFreeDoc(xml);
578 579
    VIR_FREE(domains);
    VIR_FREE(networks);
C
Cole Robinson 已提交
580
    VIR_FREE(pools);
581 582
    if (fd != -1)
        close(fd);
583
    virDomainObjListFree(&privconn->domains);
584
    virNetworkObjListFree(&privconn->networks);
C
Cole Robinson 已提交
585
    virStoragePoolObjListFree(&privconn->pools);
586
    testDriverUnlock(privconn);
587
    VIR_FREE(privconn);
588
    conn->privateData = NULL;
589
    return VIR_DRV_OPEN_ERROR;
590 591
}

592

593
static int testOpen(virConnectPtr conn,
594
                    virConnectAuthPtr auth ATTRIBUTE_UNUSED,
595
                    int flags ATTRIBUTE_UNUSED)
596
{
597
    int ret;
598

599
    if (!conn->uri)
600
        return VIR_DRV_OPEN_DECLINED;
601

602
    if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "test"))
603
        return VIR_DRV_OPEN_DECLINED;
604

605
    /* Remote driver should handle these. */
606
    if (conn->uri->server)
607 608
        return VIR_DRV_OPEN_DECLINED;

609
    if (conn->uri->server)
610 611
        return VIR_DRV_OPEN_DECLINED;

612
    /* From this point on, the connection is for us. */
613 614 615
    if (!conn->uri->path
        || conn->uri->path[0] == '\0'
        || (conn->uri->path[0] == '/' && conn->uri->path[1] == '\0')) {
616
        testError (NULL, VIR_ERR_INVALID_ARG,
J
Jim Meyering 已提交
617
                   "%s", _("testOpen: supply a path or use test:///default"));
618 619
        return VIR_DRV_OPEN_ERROR;
    }
620

621
    if (STREQ(conn->uri->path, "/default"))
622 623
        ret = testOpenDefault(conn);
    else
624
        ret = testOpenFromFile(conn,
625
                               conn->uri->path);
626 627

    return (ret);
628 629
}

630
static int testClose(virConnectPtr conn)
631
{
632
    testConnPtr privconn = conn->privateData;
633
    testDriverLock(privconn);
634
    virCapabilitiesFree(privconn->caps);
635
    virDomainObjListFree(&privconn->domains);
636
    virNetworkObjListFree(&privconn->networks);
C
Cole Robinson 已提交
637
    virStoragePoolObjListFree(&privconn->pools);
638
    testDriverUnlock(privconn);
639

640
    VIR_FREE (privconn);
641
    conn->privateData = NULL;
642
    return 0;
643 644
}

645 646
static int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
                          unsigned long *hvVer)
647
{
648 649
    *hvVer = 2;
    return (0);
650 651
}

652
static char *testGetHostname (virConnectPtr conn)
653 654 655 656 657 658
{
    int r;
    char hostname [HOST_NAME_MAX+1], *str;

    r = gethostname (hostname, HOST_NAME_MAX+1);
    if (r == -1) {
659
        testError (conn, VIR_ERR_SYSTEM_ERROR, "%s",
660
                   strerror (errno));
661 662 663 664
        return NULL;
    }
    str = strdup (hostname);
    if (str == NULL) {
665
        testError (conn, VIR_ERR_SYSTEM_ERROR, "%s",
666
                   strerror (errno));
667 668 669 670 671
        return NULL;
    }
    return str;
}

672 673 674 675 676 677 678 679
static int testGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
                           const char *type ATTRIBUTE_UNUSED)
{
    return 32;
}

static int testNodeGetInfo(virConnectPtr conn,
                           virNodeInfoPtr info)
680
{
681
    testConnPtr privconn = conn->privateData;
682
    testDriverLock(privconn);
683
    memcpy(info, &privconn->nodeInfo, sizeof(virNodeInfo));
684
    testDriverUnlock(privconn);
685
    return (0);
686 687
}

688
static char *testGetCapabilities (virConnectPtr conn)
689
{
690
    testConnPtr privconn = conn->privateData;
691
    char *xml;
692
    testDriverLock(privconn);
693
    if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
694
        testError(conn, VIR_ERR_NO_MEMORY, NULL);
695
    testDriverUnlock(privconn);
696
    return xml;
697 698
}

699
static int testNumOfDomains(virConnectPtr conn)
700
{
701
    testConnPtr privconn = conn->privateData;
702
    unsigned int numActive = 0, i;
703

704
    testDriverLock(privconn);
705 706
    for (i = 0 ; i < privconn->domains.count ; i++)
        if (virDomainIsActive(privconn->domains.objs[i]))
707
            numActive++;
708
    testDriverUnlock(privconn);
709

710
    return numActive;
711 712
}

713
static virDomainPtr
714
testDomainCreateXML(virConnectPtr conn, const char *xml,
715
                      unsigned int flags ATTRIBUTE_UNUSED)
716
{
717
    testConnPtr privconn = conn->privateData;
718
    virDomainPtr ret = NULL;
719
    virDomainDefPtr def;
720
    virDomainObjPtr dom = NULL;
721

722
    testDriverLock(privconn);
723
    if ((def = virDomainDefParseString(conn, privconn->caps, xml)) == NULL)
724
        goto cleanup;
725

726 727 728
    if ((dom = virDomainAssignDef(conn, &privconn->domains,
                                  def)) == NULL) {
        virDomainDefFree(def);
729
        goto cleanup;
730
    }
731 732
    dom->state = VIR_DOMAIN_RUNNING;
    dom->def->id = privconn->nextDomID++;
733

734
    ret = virGetDomain(conn, def->name, def->uuid);
735 736 737 738
    if (ret)
        ret->id = def->id;

cleanup:
739 740 741
    if (dom)
        virDomainObjUnlock(dom);
    testDriverUnlock(privconn);
742
    return ret;
743 744 745
}


746 747
static virDomainPtr testLookupDomainByID(virConnectPtr conn,
                                         int id)
748
{
749
    testConnPtr privconn = conn->privateData;
750 751
    virDomainPtr ret = NULL;
    virDomainObjPtr dom;
752

753 754 755 756 757
    testDriverLock(privconn);
    dom = virDomainFindByID(&privconn->domains, id);
    testDriverUnlock(privconn);

    if (dom == NULL) {
758
        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
759
        goto cleanup;
760 761
    }

762
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
763 764 765 766
    if (ret)
        ret->id = dom->def->id;

cleanup:
767 768
    if (dom)
        virDomainObjUnlock(dom);
769
    return ret;
770 771
}

772 773
static virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
                                           const unsigned char *uuid)
774
{
775
    testConnPtr privconn = conn->privateData;
776 777
    virDomainPtr ret = NULL;
    virDomainObjPtr dom ;
778

779 780 781 782 783
    testDriverLock(privconn);
    dom = virDomainFindByUUID(&privconn->domains, uuid);
    testDriverUnlock(privconn);

    if (dom == NULL) {
784
        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
785
        goto cleanup;
786
    }
787

788
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
789 790 791 792
    if (ret)
        ret->id = dom->def->id;

cleanup:
793 794
    if (dom)
        virDomainObjUnlock(dom);
795
    return ret;
796 797
}

798 799
static virDomainPtr testLookupDomainByName(virConnectPtr conn,
                                           const char *name)
800
{
801
    testConnPtr privconn = conn->privateData;
802 803
    virDomainPtr ret = NULL;
    virDomainObjPtr dom;
804

805 806 807 808 809
    testDriverLock(privconn);
    dom = virDomainFindByName(&privconn->domains, name);
    testDriverUnlock(privconn);

    if (dom == NULL) {
810
        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
811
        goto cleanup;
812
    }
813

814
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
815 816 817 818
    if (ret)
        ret->id = dom->def->id;

cleanup:
819 820
    if (dom)
        virDomainObjUnlock(dom);
821
    return ret;
822 823
}

824 825 826
static int testListDomains (virConnectPtr conn,
                            int *ids,
                            int maxids)
827
{
828
    testConnPtr privconn = conn->privateData;
829
    unsigned int n = 0, i;
830

831 832 833
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->domains.count && n < maxids ; i++) {
        virDomainObjLock(privconn->domains.objs[i]);
834 835
        if (virDomainIsActive(privconn->domains.objs[i]))
            ids[n++] = privconn->domains.objs[i]->def->id;
836 837 838
        virDomainObjUnlock(privconn->domains.objs[i]);
    }
    testDriverUnlock(privconn);
839

840
    return n;
841 842
}

843
static int testDestroyDomain (virDomainPtr domain)
844
{
845 846
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
847
    int ret = -1;
848

849
    testDriverLock(privconn);
850 851 852 853 854
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
855
        goto cleanup;
856
    }
857

858
    privdom->state = VIR_DOMAIN_SHUTOFF;
859 860
    privdom->def->id = -1;
    domain->id = -1;
861 862 863
    if (!privdom->persistent) {
        virDomainRemoveInactive(&privconn->domains,
                                privdom);
864
        privdom = NULL;
865
    }
866 867 868

    ret = 0;
cleanup:
869 870 871
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
872
    return ret;
873 874
}

875
static int testResumeDomain (virDomainPtr domain)
876
{
877 878
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
879
    int ret = -1;
880

881
    testDriverLock(privconn);
882 883
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
884
    testDriverUnlock(privconn);
885 886 887

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
888
        goto cleanup;
889
    }
890

891
    if (privdom->state != VIR_DOMAIN_PAUSED) {
892 893 894
        testError(domain->conn,
                  VIR_ERR_INTERNAL_ERROR, _("domain '%s' not paused"),
                  domain->name);
895
        goto cleanup;
896
    }
897

898
    privdom->state = VIR_DOMAIN_RUNNING;
899 900 901
    ret = 0;

cleanup:
902 903
    if (privdom)
        virDomainObjUnlock(privdom);
904
    return ret;
905 906
}

907
static int testPauseDomain (virDomainPtr domain)
908
{
909 910
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
911
    int ret = -1;
912

913
    testDriverLock(privconn);
914 915
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
916
    testDriverUnlock(privconn);
917 918 919

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
920
        goto cleanup;
921
    }
922

923 924
    if (privdom->state == VIR_DOMAIN_SHUTOFF ||
        privdom->state == VIR_DOMAIN_PAUSED) {
925 926 927
        testError(domain->conn,
                  VIR_ERR_INTERNAL_ERROR, _("domain '%s' not running"),
                  domain->name);
928
        goto cleanup;
929
    }
930

931
    privdom->state = VIR_DOMAIN_PAUSED;
932 933 934
    ret = 0;

cleanup:
935 936
    if (privdom)
        virDomainObjUnlock(privdom);
937
    return ret;
938 939
}

940
static int testShutdownDomain (virDomainPtr domain)
941
{
942 943
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
944
    int ret = -1;
945

946
    testDriverLock(privconn);
947 948 949 950 951
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
952
        goto cleanup;
953
    }
954

955
    if (privdom->state == VIR_DOMAIN_SHUTOFF) {
956 957
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("domain '%s' not running"), domain->name);
958
        goto cleanup;
959
    }
960

961
    privdom->state = VIR_DOMAIN_SHUTOFF;
962
    domain->id = -1;
963
    privdom->def->id = -1;
964 965 966 967 968
    if (!privdom->persistent) {
        virDomainRemoveInactive(&privconn->domains,
                                privdom);
        privdom = NULL;
    }
969
    ret = 0;
970

971
cleanup:
972 973 974
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
975
    return ret;
976 977 978
}

/* Similar behaviour as shutdown */
979 980
static int testRebootDomain (virDomainPtr domain,
                             unsigned int action ATTRIBUTE_UNUSED)
981
{
982 983
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
984
    int ret = -1;
985

986
    testDriverLock(privconn);
987 988 989 990 991
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
992
        goto cleanup;
993
    }
994

995 996 997 998
    privdom->state = VIR_DOMAIN_SHUTDOWN;
    switch (privdom->def->onReboot) {
    case VIR_DOMAIN_LIFECYCLE_DESTROY:
        privdom->state = VIR_DOMAIN_SHUTOFF;
999
        domain->id = -1;
1000
        privdom->def->id = -1;
1001 1002
        break;

1003 1004
    case VIR_DOMAIN_LIFECYCLE_RESTART:
        privdom->state = VIR_DOMAIN_RUNNING;
1005 1006
        break;

1007 1008
    case VIR_DOMAIN_LIFECYCLE_PRESERVE:
        privdom->state = VIR_DOMAIN_SHUTOFF;
1009
        domain->id = -1;
1010
        privdom->def->id = -1;
1011 1012
        break;

1013 1014
    case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME:
        privdom->state = VIR_DOMAIN_RUNNING;
1015
        break;
1016

1017
    default:
1018
        privdom->state = VIR_DOMAIN_SHUTOFF;
1019
        domain->id = -1;
1020
        privdom->def->id = -1;
1021 1022
        break;
    }
1023

1024 1025 1026 1027 1028 1029
    if (privdom->state == VIR_DOMAIN_SHUTOFF && !privdom->persistent) {
        virDomainRemoveInactive(&privconn->domains,
                                privdom);
        privdom = NULL;
    }

1030 1031 1032
    ret = 0;

cleanup:
1033 1034 1035
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
1036
    return ret;
1037 1038
}

1039 1040
static int testGetDomainInfo (virDomainPtr domain,
                              virDomainInfoPtr info)
1041
{
1042
    testConnPtr privconn = domain->conn->privateData;
1043
    struct timeval tv;
1044
    virDomainObjPtr privdom;
1045
    int ret = -1;
1046

1047
    testDriverLock(privconn);
1048 1049
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1050
    testDriverUnlock(privconn);
1051 1052 1053

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1054
        goto cleanup;
1055
    }
1056 1057

    if (gettimeofday(&tv, NULL) < 0) {
1058
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1059
                  "%s", _("getting time of day"));
1060
        goto cleanup;
1061 1062
    }

1063 1064 1065 1066 1067
    info->state = privdom->state;
    info->memory = privdom->def->memory;
    info->maxMem = privdom->def->maxmem;
    info->nrVirtCpu = privdom->def->vcpus;
    info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll  * 1000ll) + (tv.tv_usec * 1000ll));
1068 1069 1070
    ret = 0;

cleanup:
1071 1072
    if (privdom)
        virDomainObjUnlock(privdom);
1073
    return ret;
1074 1075
}

1076
static char *testDomainDumpXML(virDomainPtr domain, int flags);
1077

1078 1079 1080 1081 1082
#define TEST_SAVE_MAGIC "TestGuestMagic"

static int testDomainSave(virDomainPtr domain,
                          const char *path)
{
1083
    testConnPtr privconn = domain->conn->privateData;
1084 1085 1086
    char *xml = NULL;
    int fd = -1;
    int len;
1087
    virDomainObjPtr privdom;
1088
    int ret = -1;
1089

1090
    testDriverLock(privconn);
1091 1092 1093 1094 1095
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1096
        goto cleanup;
1097
    }
1098

1099
    xml = testDomainDumpXML(domain, 0);
1100
    if (xml == NULL) {
1101 1102 1103
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("saving domain '%s' failed to allocate space for metadata: %s"),
                  domain->name, strerror(errno));
1104
        goto cleanup;
1105
    }
1106 1107

    if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
1108 1109 1110
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("saving domain '%s' to '%s': open failed: %s"),
                  domain->name, path, strerror(errno));
1111
        goto cleanup;
1112
    }
1113
    len = strlen(xml);
1114
    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
1115 1116 1117
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("saving domain '%s' to '%s': write failed: %s"),
                  domain->name, path, strerror(errno));
1118
        goto cleanup;
1119
    }
1120
    if (safewrite(fd, (char*)&len, sizeof(len)) < 0) {
1121 1122 1123
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("saving domain '%s' to '%s': write failed: %s"),
                  domain->name, path, strerror(errno));
1124
        goto cleanup;
1125
    }
1126
    if (safewrite(fd, xml, len) < 0) {
1127 1128 1129
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("saving domain '%s' to '%s': write failed: %s"),
                  domain->name, path, strerror(errno));
1130
        goto cleanup;
1131
    }
1132

1133
    if (close(fd) < 0) {
1134 1135 1136
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("saving domain '%s' to '%s': write failed: %s"),
                  domain->name, path, strerror(errno));
1137
        goto cleanup;
1138
    }
1139 1140
    fd = -1;

1141 1142 1143 1144
    privdom->state = VIR_DOMAIN_SHUTOFF;
    if (!privdom->persistent) {
        virDomainRemoveInactive(&privconn->domains,
                                privdom);
1145
        privdom = NULL;
1146
    }
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
    ret = 0;

cleanup:
    VIR_FREE(xml);

    /* Don't report failure in close or unlink, because
     * in either case we're already in a failure scenario
     * and have reported a earlier error */
    if (ret != 0) {
        if (fd != -1)
            close(fd);
        unlink(path);
    }
1160 1161 1162
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
1163
    return ret;
1164 1165
}

1166 1167
static int testDomainRestore(virConnectPtr conn,
                             const char *path)
1168
{
1169
    testConnPtr privconn = conn->privateData;
1170
    char *xml = NULL;
1171
    char magic[15];
1172 1173 1174
    int fd = -1;
    int len;
    virDomainDefPtr def = NULL;
1175
    virDomainObjPtr dom = NULL;
1176
    int ret = -1;
1177 1178

    if ((fd = open(path, O_RDONLY)) < 0) {
1179
        testError(conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1180
                  "%s", _("cannot read domain image"));
1181
        goto cleanup;
1182
    }
1183
    if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {
1184
        testError(conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1185
                  "%s", _("incomplete save header"));
1186
        goto cleanup;
1187
    }
1188
    if (memcmp(magic, TEST_SAVE_MAGIC, sizeof(magic))) {
1189
        testError(conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1190
                  "%s", _("mismatched header magic"));
1191
        goto cleanup;
1192 1193
    }
    if (read(fd, (char*)&len, sizeof(len)) != sizeof(len)) {
1194
        testError(conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1195
                  "%s", _("failed to read metadata length"));
1196
        goto cleanup;
1197 1198
    }
    if (len < 1 || len > 8192) {
1199
        testError(conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1200
                  "%s", _("length of metadata out of range"));
1201
        goto cleanup;
1202
    }
1203
    if (VIR_ALLOC_N(xml, len+1) < 0) {
1204
        testError(conn, VIR_ERR_NO_MEMORY, "xml");
1205
        goto cleanup;
1206 1207
    }
    if (read(fd, xml, len) != len) {
1208
        testError(conn, VIR_ERR_INTERNAL_ERROR,
J
Jim Meyering 已提交
1209
                  "%s", _("incomplete metdata"));
1210
        goto cleanup;
1211 1212
    }
    xml[len] = '\0';
1213

1214
    testDriverLock(privconn);
1215 1216
    def = virDomainDefParseString(conn, privconn->caps, xml);
    if (!def)
1217
        goto cleanup;
1218 1219

    if ((dom = virDomainAssignDef(conn, &privconn->domains,
1220 1221 1222
                                  def)) == NULL)
        goto cleanup;

1223 1224
    dom->state = VIR_DOMAIN_RUNNING;
    dom->def->id = privconn->nextDomID++;
1225 1226 1227 1228 1229 1230 1231 1232
    def = NULL;
    ret = dom->def->id;

cleanup:
    virDomainDefFree(def);
    VIR_FREE(xml);
    if (fd != -1)
        close(fd);
1233 1234 1235
    if (dom)
        virDomainObjUnlock(dom);
    testDriverUnlock(privconn);
1236
    return ret;
1237 1238
}

1239 1240 1241
static int testDomainCoreDump(virDomainPtr domain,
                              const char *to,
                              int flags ATTRIBUTE_UNUSED)
1242
{
1243
    testConnPtr privconn = domain->conn->privateData;
1244
    int fd = -1;
1245
    virDomainObjPtr privdom;
1246
    int ret = -1;
1247

1248
    testDriverLock(privconn);
1249 1250 1251 1252 1253
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1254
        goto cleanup;
1255
    }
1256 1257

    if ((fd = open(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
1258 1259 1260
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("domain '%s' coredump: failed to open %s: %s"),
                  domain->name, to, strerror (errno));
1261
        goto cleanup;
1262
    }
1263
    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
1264 1265 1266
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("domain '%s' coredump: failed to write header to %s: %s"),
                  domain->name, to, strerror (errno));
1267
        goto cleanup;
1268
    }
1269
    if (close(fd) < 0) {
1270 1271 1272
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("domain '%s' coredump: write failed: %s: %s"),
                  domain->name, to, strerror (errno));
1273
        goto cleanup;
1274
    }
1275 1276 1277 1278
    privdom->state = VIR_DOMAIN_SHUTOFF;
    if (!privdom->persistent) {
        virDomainRemoveInactive(&privconn->domains,
                                privdom);
1279
        privdom = NULL;
1280
    }
1281 1282 1283 1284 1285
    ret = 0;

cleanup:
    if (fd != -1)
        close(fd);
1286 1287 1288
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
1289
    return ret;
1290 1291
}

1292 1293 1294
static char *testGetOSType(virDomainPtr dom) {
    char *ret = strdup("linux");
    if (!ret)
1295
        testError(dom->conn, VIR_ERR_NO_MEMORY, NULL);
1296
    return ret;
1297 1298 1299
}

static unsigned long testGetMaxMemory(virDomainPtr domain) {
1300 1301
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1302
    unsigned long ret = -1;
1303

1304
    testDriverLock(privconn);
1305 1306
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1307
    testDriverUnlock(privconn);
1308 1309 1310

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1311
        goto cleanup;
1312
    }
1313

1314 1315 1316
    ret = privdom->def->maxmem;

cleanup:
1317 1318
    if (privdom)
        virDomainObjUnlock(privdom);
1319
    return ret;
1320 1321 1322 1323 1324
}

static int testSetMaxMemory(virDomainPtr domain,
                            unsigned long memory)
{
1325 1326
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1327
    int ret = -1;
1328

1329
    testDriverLock(privconn);
1330 1331
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1332
    testDriverUnlock(privconn);
1333 1334 1335

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1336
        goto cleanup;
1337
    }
1338 1339

    /* XXX validate not over host memory wrt to other domains */
1340
    privdom->def->maxmem = memory;
1341 1342 1343
    ret = 0;

cleanup:
1344 1345
    if (privdom)
        virDomainObjUnlock(privdom);
1346
    return ret;
1347 1348
}

1349 1350 1351
static int testSetMemory(virDomainPtr domain,
                         unsigned long memory)
{
1352 1353
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1354
    int ret = -1;
1355

1356
    testDriverLock(privconn);
1357 1358
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1359
    testDriverUnlock(privconn);
1360 1361 1362

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1363
        goto cleanup;
1364
    }
1365

1366
    if (memory > privdom->def->maxmem) {
1367
        testError(domain->conn,
1368
                  VIR_ERR_INVALID_ARG, __FUNCTION__);
1369
        goto cleanup;
1370
    }
1371

1372
    privdom->def->memory = memory;
1373 1374 1375
    ret = 0;

cleanup:
1376 1377
    if (privdom)
        virDomainObjUnlock(privdom);
1378
    return ret;
1379 1380 1381 1382
}

static int testSetVcpus(virDomainPtr domain,
                        unsigned int nrCpus) {
1383 1384
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1385 1386
    int ret = -1;

1387 1388 1389 1390 1391 1392
    testDriverLock(privconn);
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
    testDriverUnlock(privconn);

    if (privdom == NULL) {
1393
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1394
        goto cleanup;
1395
    }
1396

1397 1398
    /* We allow more cpus in guest than host */
    if (nrCpus > 32) {
1399
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1400
        goto cleanup;
1401
    }
1402

1403
    privdom->def->vcpus = nrCpus;
1404 1405 1406
    ret = 0;

cleanup:
1407 1408
    if (privdom)
        virDomainObjUnlock(privdom);
1409
    return ret;
1410 1411
}

1412
static char *testDomainDumpXML(virDomainPtr domain, int flags)
1413
{
1414
    testConnPtr privconn = domain->conn->privateData;
1415
    virDomainDefPtr def;
1416
    virDomainObjPtr privdom;
1417 1418
    char *ret = NULL;

1419 1420 1421 1422 1423 1424
    testDriverLock(privconn);
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
    testDriverUnlock(privconn);

    if (privdom == NULL) {
1425
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1426
        goto cleanup;
1427
    }
1428

1429 1430
    def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
        privdom->newDef ? privdom->newDef : privdom->def;
1431

1432 1433 1434 1435 1436
    ret = virDomainDefFormat(domain->conn,
                             def,
                             flags);

cleanup:
1437 1438
    if (privdom)
        virDomainObjUnlock(privdom);
1439
    return ret;
1440
}
1441

1442
static int testNumOfDefinedDomains(virConnectPtr conn) {
1443
    testConnPtr privconn = conn->privateData;
1444
    unsigned int numInactive = 0, i;
1445

1446 1447 1448
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->domains.count ; i++) {
        virDomainObjLock(privconn->domains.objs[i]);
1449
        if (!virDomainIsActive(privconn->domains.objs[i]))
1450
            numInactive++;
1451 1452 1453
        virDomainObjUnlock(privconn->domains.objs[i]);
    }
    testDriverUnlock(privconn);
1454

1455
    return numInactive;
1456 1457
}

1458 1459 1460
static int testListDefinedDomains(virConnectPtr conn,
                                  char **const names,
                                  int maxnames) {
1461
    testConnPtr privconn = conn->privateData;
1462
    unsigned int n = 0, i;
1463

1464
    testDriverLock(privconn);
1465
    memset(names, 0, sizeof(*names)*maxnames);
1466 1467
    for (i = 0 ; i < privconn->domains.count && n < maxnames ; i++) {
        virDomainObjLock(privconn->domains.objs[i]);
1468
        if (!virDomainIsActive(privconn->domains.objs[i]) &&
1469 1470
            !(names[n++] = strdup(privconn->domains.objs[i]->def->name))) {
            virDomainObjUnlock(privconn->domains.objs[i]);
1471
            goto no_memory;
1472 1473 1474 1475
        }
        virDomainObjUnlock(privconn->domains.objs[i]);
    }
    testDriverUnlock(privconn);
1476

1477 1478 1479
    return n;

no_memory:
1480
    testError(conn, VIR_ERR_NO_MEMORY, NULL);
1481 1482
    for (n = 0 ; n < maxnames ; n++)
        VIR_FREE(names[n]);
1483
    testDriverUnlock(privconn);
1484
    return -1;
1485 1486
}

1487
static virDomainPtr testDomainDefineXML(virConnectPtr conn,
1488
                                        const char *xml) {
1489
    testConnPtr privconn = conn->privateData;
1490
    virDomainPtr ret = NULL;
1491
    virDomainDefPtr def;
1492
    virDomainObjPtr dom = NULL;
1493

1494
    testDriverLock(privconn);
1495
    if ((def = virDomainDefParseString(conn, privconn->caps, xml)) == NULL)
1496
        goto cleanup;
1497

1498 1499
    if ((dom = virDomainAssignDef(conn, &privconn->domains,
                                  def)) == NULL) {
1500
        goto cleanup;
1501 1502 1503
    }
    dom->persistent = 1;
    dom->def->id = -1;
1504

1505
    ret = virGetDomain(conn, def->name, def->uuid);
1506 1507 1508 1509 1510 1511
    def = NULL;
    if (ret)
        ret->id = -1;

cleanup:
    virDomainDefFree(def);
1512 1513 1514
    if (dom)
        virDomainObjUnlock(dom);
    testDriverUnlock(privconn);
1515
    return ret;
1516 1517
}

1518 1519 1520
static int testNodeGetCellsFreeMemory(virConnectPtr conn,
                                      unsigned long long *freemems,
                                      int startCell, int maxCells) {
1521
    testConnPtr privconn = conn->privateData;
1522
    int i, j;
1523
    int ret = -1;
1524

1525
    testDriverLock(privconn);
1526
    if (startCell > privconn->numCells) {
1527
        testError(conn, VIR_ERR_INVALID_ARG,
J
Jim Meyering 已提交
1528
                  "%s", _("Range exceeds available cells"));
1529
        goto cleanup;
1530 1531 1532 1533 1534 1535 1536
    }

    for (i = startCell, j = 0;
         (i < privconn->numCells && j < maxCells) ;
         ++i, ++j) {
        freemems[j] = privconn->cells[i].mem;
    }
1537
    ret = j;
1538

1539
cleanup:
1540
    testDriverUnlock(privconn);
1541
    return ret;
1542 1543 1544
}


1545
static int testDomainCreate(virDomainPtr domain) {
1546 1547
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1548
    int ret = -1;
1549

1550
    testDriverLock(privconn);
1551 1552 1553 1554 1555
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1556
        goto cleanup;
1557
    }
1558

1559
    if (privdom->state != VIR_DOMAIN_SHUTOFF) {
1560 1561
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("Domain '%s' is already running"), domain->name);
1562
        goto cleanup;
1563 1564
    }

1565 1566
    domain->id = privdom->def->id = privconn->nextDomID++;
    privdom->state = VIR_DOMAIN_RUNNING;
1567
    ret = 0;
1568

1569
cleanup:
1570 1571 1572
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
1573
    return ret;
1574 1575 1576
}

static int testDomainUndefine(virDomainPtr domain) {
1577 1578
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1579
    int ret = -1;
1580

1581
    testDriverLock(privconn);
1582 1583 1584 1585 1586
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1587
        goto cleanup;
1588
    }
1589

1590
    if (privdom->state != VIR_DOMAIN_SHUTOFF) {
1591 1592
        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
                  _("Domain '%s' is still running"), domain->name);
1593
        goto cleanup;
1594 1595
    }

1596 1597 1598
    privdom->state = VIR_DOMAIN_SHUTOFF;
    virDomainRemoveInactive(&privconn->domains,
                            privdom);
1599
    privdom = NULL;
1600
    ret = 0;
1601

1602
cleanup:
1603 1604 1605
    if (privdom)
        virDomainObjUnlock(privdom);
    testDriverUnlock(privconn);
1606
    return ret;
1607 1608
}

1609 1610 1611
static int testDomainGetAutostart(virDomainPtr domain,
                                  int *autostart)
{
1612 1613
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1614
    int ret = -1;
1615

1616
    testDriverLock(privconn);
1617 1618
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1619
    testDriverUnlock(privconn);
1620 1621 1622

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1623
        goto cleanup;
1624 1625
    }

1626
    *autostart = privdom->autostart;
1627 1628 1629
    ret = 0;

cleanup:
1630 1631
    if (privdom)
        virDomainObjUnlock(privdom);
1632
    return ret;
1633 1634 1635 1636 1637 1638
}


static int testDomainSetAutostart(virDomainPtr domain,
                                  int autostart)
{
1639 1640
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1641
    int ret = -1;
1642

1643
    testDriverLock(privconn);
1644 1645
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1646
    testDriverUnlock(privconn);
1647 1648 1649

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1650
        goto cleanup;
1651 1652
    }

1653
    privdom->autostart = autostart ? 1 : 0;
1654 1655 1656
    ret = 0;

cleanup:
1657 1658
    if (privdom)
        virDomainObjUnlock(privdom);
1659
    return ret;
1660
}
1661

1662 1663 1664
static char *testDomainGetSchedulerType(virDomainPtr domain,
                                        int *nparams)
{
1665 1666
    char *type = NULL;

1667 1668
    *nparams = 1;
    type = strdup("fair");
1669
    if (!type)
1670
        testError(domain->conn, VIR_ERR_NO_MEMORY, "schedular");
1671

1672 1673 1674 1675 1676 1677 1678
    return type;
}

static int testDomainGetSchedulerParams(virDomainPtr domain,
                                        virSchedParameterPtr params,
                                        int *nparams)
{
1679 1680
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1681
    int ret = -1;
1682

1683
    testDriverLock(privconn);
1684 1685
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1686
    testDriverUnlock(privconn);
1687 1688 1689

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1690
        goto cleanup;
1691 1692
    }

1693
    if (*nparams != 1) {
1694
        testError(domain->conn, VIR_ERR_INVALID_ARG, "nparams");
1695
        goto cleanup;
1696
    }
1697 1698
    strcpy(params[0].field, "weight");
    params[0].type = VIR_DOMAIN_SCHED_FIELD_UINT;
1699 1700 1701
    /* XXX */
    /*params[0].value.ui = privdom->weight;*/
    params[0].value.ui = 50;
1702 1703 1704
    ret = 0;

cleanup:
1705 1706
    if (privdom)
        virDomainObjUnlock(privdom);
1707
    return ret;
1708
}
1709 1710


1711 1712 1713 1714
static int testDomainSetSchedulerParams(virDomainPtr domain,
                                        virSchedParameterPtr params,
                                        int nparams)
{
1715 1716
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1717
    int ret = -1;
1718

1719
    testDriverLock(privconn);
1720 1721
    privdom = virDomainFindByName(&privconn->domains,
                                  domain->name);
1722
    testDriverUnlock(privconn);
1723 1724 1725

    if (privdom == NULL) {
        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1726
        goto cleanup;
1727 1728
    }

1729
    if (nparams != 1) {
1730
        testError(domain->conn, VIR_ERR_INVALID_ARG, "nparams");
1731
        goto cleanup;
1732
    }
1733
    if (STRNEQ(params[0].field, "weight")) {
1734
        testError(domain->conn, VIR_ERR_INVALID_ARG, "field");
1735
        goto cleanup;
1736 1737
    }
    if (params[0].type != VIR_DOMAIN_SCHED_FIELD_UINT) {
1738
        testError(domain->conn, VIR_ERR_INVALID_ARG, "type");
1739
        goto cleanup;
1740
    }
1741 1742
    /* XXX */
    /*privdom->weight = params[0].value.ui;*/
1743 1744 1745
    ret = 0;

cleanup:
1746 1747
    if (privdom)
        virDomainObjUnlock(privdom);
1748
    return ret;
1749 1750 1751
}

static virDrvOpenStatus testOpenNetwork(virConnectPtr conn,
1752
                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769
                                        int flags ATTRIBUTE_UNUSED) {
    if (STRNEQ(conn->driver->name, "Test"))
        return VIR_DRV_OPEN_DECLINED;

    conn->networkPrivateData = conn->privateData;
    return VIR_DRV_OPEN_SUCCESS;
}

static int testCloseNetwork(virConnectPtr conn) {
    conn->networkPrivateData = NULL;
    return 0;
}


static virNetworkPtr testLookupNetworkByUUID(virConnectPtr conn,
                                           const unsigned char *uuid)
{
1770 1771
    testConnPtr privconn = conn->privateData;
    virNetworkObjPtr net;
1772
    virNetworkPtr ret = NULL;
1773

1774 1775 1776 1777 1778
    testDriverLock(privconn);
    net = virNetworkFindByUUID(&privconn->networks, uuid);
    testDriverUnlock(privconn);

    if (net == NULL) {
1779
        testError (conn, VIR_ERR_NO_NETWORK, NULL);
1780
        goto cleanup;
1781 1782
    }

1783 1784 1785
    ret = virGetNetwork(conn, net->def->name, net->def->uuid);

cleanup:
1786 1787
    if (net)
        virNetworkObjUnlock(net);
1788
    return ret;
1789
}
1790

1791
static virNetworkPtr testLookupNetworkByName(virConnectPtr conn,
1792
                                             const char *name)
1793
{
1794
    testConnPtr privconn = conn->privateData;
1795 1796
    virNetworkObjPtr net;
    virNetworkPtr ret = NULL;
1797

1798 1799 1800 1801 1802
    testDriverLock(privconn);
    net = virNetworkFindByName(&privconn->networks, name);
    testDriverUnlock(privconn);

    if (net == NULL) {
1803
        testError (conn, VIR_ERR_NO_NETWORK, NULL);
1804
        goto cleanup;
1805 1806
    }

1807 1808 1809
    ret = virGetNetwork(conn, net->def->name, net->def->uuid);

cleanup:
1810 1811
    if (net)
        virNetworkObjUnlock(net);
1812
    return ret;
1813 1814 1815 1816
}


static int testNumNetworks(virConnectPtr conn) {
1817
    testConnPtr privconn = conn->privateData;
1818
    int numActive = 0, i;
1819

1820 1821 1822
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->networks.count ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
1823
        if (virNetworkIsActive(privconn->networks.objs[i]))
1824
            numActive++;
1825 1826 1827
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
1828

1829
    return numActive;
1830 1831 1832
}

static int testListNetworks(virConnectPtr conn, char **const names, int nnames) {
1833
    testConnPtr privconn = conn->privateData;
1834
    int n = 0, i;
1835

1836
    testDriverLock(privconn);
1837
    memset(names, 0, sizeof(*names)*nnames);
1838 1839
    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
1840
        if (virNetworkIsActive(privconn->networks.objs[i]) &&
1841 1842
            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
            virNetworkObjUnlock(privconn->networks.objs[i]);
1843
            goto no_memory;
1844 1845 1846 1847
        }
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
1848

1849 1850 1851
    return n;

no_memory:
1852
    testError(conn, VIR_ERR_NO_MEMORY, NULL);
1853 1854
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
1855
    testDriverUnlock(privconn);
1856
    return -1;
1857 1858 1859
}

static int testNumDefinedNetworks(virConnectPtr conn) {
1860
    testConnPtr privconn = conn->privateData;
1861
    int numInactive = 0, i;
1862

1863 1864 1865
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->networks.count ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
1866
        if (!virNetworkIsActive(privconn->networks.objs[i]))
1867
            numInactive++;
1868 1869 1870
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
1871

1872
    return numInactive;
1873 1874 1875
}

static int testListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
1876
    testConnPtr privconn = conn->privateData;
1877
    int n = 0, i;
1878

1879
    testDriverLock(privconn);
1880
    memset(names, 0, sizeof(*names)*nnames);
1881 1882
    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
1883
        if (!virNetworkIsActive(privconn->networks.objs[i]) &&
1884 1885
            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
            virNetworkObjUnlock(privconn->networks.objs[i]);
1886
            goto no_memory;
1887 1888 1889 1890
        }
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
1891

1892 1893 1894
    return n;

no_memory:
1895
    testError(conn, VIR_ERR_NO_MEMORY, NULL);
1896 1897
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
1898
    testDriverUnlock(privconn);
1899
    return -1;
1900 1901 1902
}

static virNetworkPtr testNetworkCreate(virConnectPtr conn, const char *xml) {
1903
    testConnPtr privconn = conn->privateData;
1904
    virNetworkDefPtr def;
1905
    virNetworkObjPtr net = NULL;
1906
    virNetworkPtr ret = NULL;
1907

1908
    testDriverLock(privconn);
1909
    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
1910
        goto cleanup;
1911

1912 1913
    if ((net = virNetworkAssignDef(conn, &privconn->networks,
                                   def)) == NULL) {
1914
        goto cleanup;
1915
    }
1916
    net->active = 1;
1917 1918 1919
    def = NULL;

    ret = virGetNetwork(conn, def->name, def->uuid);
1920

1921 1922
cleanup:
    virNetworkDefFree(def);
1923 1924 1925
    if (net)
        virNetworkObjUnlock(net);
    testDriverUnlock(privconn);
1926
    return ret;
1927 1928 1929
}

static virNetworkPtr testNetworkDefine(virConnectPtr conn, const char *xml) {
1930
    testConnPtr privconn = conn->privateData;
1931
    virNetworkDefPtr def;
1932
    virNetworkObjPtr net = NULL;
1933
    virNetworkPtr ret = NULL;
1934

1935
    testDriverLock(privconn);
1936
    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
1937
        goto cleanup;
1938

1939 1940
    if ((net = virNetworkAssignDef(conn, &privconn->networks,
                                   def)) == NULL) {
1941
        goto cleanup;
1942
    }
1943
    net->persistent = 1;
1944
    def = NULL;
1945

1946 1947 1948 1949
    ret = virGetNetwork(conn, def->name, def->uuid);

cleanup:
    virNetworkDefFree(def);
1950 1951 1952
    if (net)
        virNetworkObjUnlock(net);
    testDriverUnlock(privconn);
1953
    return ret;
1954 1955 1956
}

static int testNetworkUndefine(virNetworkPtr network) {
1957 1958
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
1959
    int ret = -1;
1960

1961
    testDriverLock(privconn);
1962 1963 1964 1965 1966
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
1967
        goto cleanup;
1968
    }
1969

1970
    if (virNetworkIsActive(privnet)) {
1971 1972
        testError(network->conn, VIR_ERR_INTERNAL_ERROR,
                  _("Network '%s' is still running"), network->name);
1973
        goto cleanup;
1974 1975
    }

1976 1977
    virNetworkRemoveInactive(&privconn->networks,
                             privnet);
1978
    privnet = NULL;
1979
    ret = 0;
1980

1981
cleanup:
1982 1983 1984
    if (privnet)
        virNetworkObjUnlock(privnet);
    testDriverUnlock(privconn);
1985
    return ret;
1986 1987 1988
}

static int testNetworkStart(virNetworkPtr network) {
1989 1990
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
1991
    int ret = -1;
1992

1993
    testDriverLock(privconn);
1994 1995
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
1996
    testDriverUnlock(privconn);
1997 1998 1999

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2000
        goto cleanup;
2001
    }
2002

2003
    if (virNetworkIsActive(privnet)) {
2004 2005
        testError(network->conn, VIR_ERR_INTERNAL_ERROR,
                  _("Network '%s' is already running"), network->name);
2006
        goto cleanup;
2007 2008
    }

2009
    privnet->active = 1;
2010
    ret = 0;
2011

2012
cleanup:
2013 2014
    if (privnet)
        virNetworkObjUnlock(privnet);
2015
    return ret;
2016 2017 2018
}

static int testNetworkDestroy(virNetworkPtr network) {
2019 2020
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
2021
    int ret = -1;
2022

2023
    testDriverLock(privconn);
2024 2025 2026 2027 2028
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2029
        goto cleanup;
2030
    }
2031

2032 2033 2034 2035
    privnet->active = 0;
    if (!privnet->persistent) {
        virNetworkRemoveInactive(&privconn->networks,
                                 privnet);
2036
        privnet = NULL;
2037
    }
2038 2039 2040
    ret = 0;

cleanup:
2041 2042 2043
    if (privnet)
        virNetworkObjUnlock(privnet);
    testDriverUnlock(privconn);
2044
    return ret;
2045 2046 2047
}

static char *testNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
2048 2049
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
2050
    char *ret = NULL;
2051

2052
    testDriverLock(privconn);
2053 2054
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
2055
    testDriverUnlock(privconn);
2056 2057 2058

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2059
        goto cleanup;
2060
    }
2061

2062 2063 2064
    ret = virNetworkDefFormat(network->conn, privnet->def);

cleanup:
2065 2066
    if (privnet)
        virNetworkObjUnlock(privnet);
2067
    return ret;
2068 2069 2070
}

static char *testNetworkGetBridgeName(virNetworkPtr network) {
2071
    testConnPtr privconn = network->conn->privateData;
2072
    char *bridge = NULL;
2073 2074
    virNetworkObjPtr privnet;

2075
    testDriverLock(privconn);
2076 2077
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
2078
    testDriverUnlock(privconn);
2079 2080 2081

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2082
        goto cleanup;
2083 2084
    }

2085 2086
    if (privnet->def->bridge &&
        !(bridge = strdup(privnet->def->bridge))) {
2087
        testError(network->conn, VIR_ERR_NO_MEMORY, "network");
2088
        goto cleanup;
2089
    }
2090 2091

cleanup:
2092 2093
    if (privnet)
        virNetworkObjUnlock(privnet);
2094 2095 2096 2097 2098
    return bridge;
}

static int testNetworkGetAutostart(virNetworkPtr network,
                                   int *autostart) {
2099 2100
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
2101
    int ret = -1;
2102

2103
    testDriverLock(privconn);
2104 2105
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
2106
    testDriverUnlock(privconn);
2107 2108 2109

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2110
        goto cleanup;
2111 2112
    }

2113
    *autostart = privnet->autostart;
2114 2115 2116
    ret = 0;

cleanup:
2117 2118
    if (privnet)
        virNetworkObjUnlock(privnet);
2119
    return ret;
2120 2121 2122 2123
}

static int testNetworkSetAutostart(virNetworkPtr network,
                                   int autostart) {
2124 2125
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
2126
    int ret = -1;
2127

2128
    testDriverLock(privconn);
2129 2130
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
2131
    testDriverUnlock(privconn);
2132 2133 2134

    if (privnet == NULL) {
        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2135
        goto cleanup;
2136 2137
    }

2138
    privnet->autostart = autostart ? 1 : 0;
2139 2140 2141
    ret = 0;

cleanup:
2142 2143
    if (privnet)
        virNetworkObjUnlock(privnet);
2144
    return ret;
2145
}
2146

C
Cole Robinson 已提交
2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166

/*
 * Storage Driver routines
 */

static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool) {

    pool->def->capacity = defaultPoolCap;
    pool->def->allocation = defaultPoolAlloc;
    pool->def->available = defaultPoolCap - defaultPoolAlloc;

    pool->configFile = strdup("\0");
    if (!pool->configFile) {
        testError(NULL, VIR_ERR_NO_MEMORY, "configFile");
        return -1;
    }

    return 0;
}

2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181
static virDrvOpenStatus testStorageOpen(virConnectPtr conn,
                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
                                        int flags ATTRIBUTE_UNUSED) {
    if (STRNEQ(conn->driver->name, "Test"))
        return VIR_DRV_OPEN_DECLINED;

    conn->storagePrivateData = conn->privateData;
    return VIR_DRV_OPEN_SUCCESS;
}

static int testStorageClose(virConnectPtr conn) {
    conn->storagePrivateData = NULL;
    return 0;
}

C
Cole Robinson 已提交
2182 2183 2184
static virStoragePoolPtr
testStoragePoolLookupByUUID(virConnectPtr conn,
                            const unsigned char *uuid) {
2185
    testConnPtr privconn = conn->privateData;
2186 2187
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
2188

2189
    testDriverLock(privconn);
2190
    pool = virStoragePoolObjFindByUUID(&privconn->pools, uuid);
2191
    testDriverUnlock(privconn);
2192 2193

    if (pool == NULL) {
C
Cole Robinson 已提交
2194
        testError (conn, VIR_ERR_NO_STORAGE_POOL, NULL);
2195
        goto cleanup;
C
Cole Robinson 已提交
2196 2197
    }

2198 2199 2200
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);

cleanup:
2201 2202
    if (pool)
        virStoragePoolObjUnlock(pool);
2203
    return ret;
C
Cole Robinson 已提交
2204 2205 2206 2207 2208
}

static virStoragePoolPtr
testStoragePoolLookupByName(virConnectPtr conn,
                            const char *name) {
2209
    testConnPtr privconn = conn->privateData;
2210 2211
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
2212

2213
    testDriverLock(privconn);
2214
    pool = virStoragePoolObjFindByName(&privconn->pools, name);
2215
    testDriverUnlock(privconn);
2216 2217

    if (pool == NULL) {
C
Cole Robinson 已提交
2218
        testError (conn, VIR_ERR_NO_STORAGE_POOL, NULL);
2219
        goto cleanup;
C
Cole Robinson 已提交
2220 2221
    }

2222 2223 2224
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);

cleanup:
2225 2226
    if (pool)
        virStoragePoolObjUnlock(pool);
2227
    return ret;
C
Cole Robinson 已提交
2228 2229 2230 2231 2232 2233 2234 2235 2236
}

static virStoragePoolPtr
testStoragePoolLookupByVolume(virStorageVolPtr vol) {
    return testStoragePoolLookupByName(vol->conn, vol->pool);
}

static int
testStorageNumPools(virConnectPtr conn) {
2237
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2238 2239
    int numActive = 0, i;

2240
    testDriverLock(privconn);
C
Cole Robinson 已提交
2241 2242 2243
    for (i = 0 ; i < privconn->pools.count ; i++)
        if (virStoragePoolObjIsActive(privconn->pools.objs[i]))
            numActive++;
2244
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2245 2246 2247 2248 2249 2250 2251 2252

    return numActive;
}

static int
testStorageListPools(virConnectPtr conn,
                     char **const names,
                     int nnames) {
2253
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2254 2255
    int n = 0, i;

2256
    testDriverLock(privconn);
C
Cole Robinson 已提交
2257
    memset(names, 0, sizeof(*names)*nnames);
2258 2259
    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2260
        if (virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
2261 2262
            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
            virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2263
            goto no_memory;
2264 2265 2266 2267
        }
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
    }
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2268 2269 2270 2271 2272 2273 2274

    return n;

no_memory:
    testError(conn, VIR_ERR_NO_MEMORY, NULL);
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
2275
    testDriverUnlock(privconn);
2276
    return -1;
C
Cole Robinson 已提交
2277 2278 2279 2280
}

static int
testStorageNumDefinedPools(virConnectPtr conn) {
2281
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2282 2283
    int numInactive = 0, i;

2284 2285 2286
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->pools.count ; i++) {
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2287 2288
        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]))
            numInactive++;
2289 2290 2291
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
    }
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2292 2293 2294 2295 2296 2297 2298 2299

    return numInactive;
}

static int
testStorageListDefinedPools(virConnectPtr conn,
                            char **const names,
                            int nnames) {
2300
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2301 2302
    int n = 0, i;

2303
    testDriverLock(privconn);
C
Cole Robinson 已提交
2304
    memset(names, 0, sizeof(*names)*nnames);
2305 2306
    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2307
        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
2308 2309
            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
            virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2310
            goto no_memory;
2311 2312 2313 2314
        }
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
    }
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2315 2316 2317 2318 2319 2320 2321

    return n;

no_memory:
    testError(conn, VIR_ERR_NO_MEMORY, NULL);
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
2322
    testDriverUnlock(privconn);
2323
    return -1;
C
Cole Robinson 已提交
2324 2325 2326 2327 2328 2329 2330
}

static int
testStoragePoolRefresh(virStoragePoolPtr obj,
                       unsigned int flags ATTRIBUTE_UNUSED);

static int
2331
testStoragePoolStart(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2332
                     unsigned int flags ATTRIBUTE_UNUSED) {
2333 2334
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2335
    int ret = -1;
2336

2337
    testDriverLock(privconn);
2338 2339
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2340
    testDriverUnlock(privconn);
2341 2342 2343

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2344
        goto cleanup;
2345 2346
    }

2347 2348 2349 2350 2351
    if (virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is already active"), pool->name);
        goto cleanup;
    }
C
Cole Robinson 已提交
2352

2353
    if (testStoragePoolRefresh(pool, 0) == 0)
2354
        goto cleanup;
C
Cole Robinson 已提交
2355
    privpool->active = 1;
2356
    ret = 0;
C
Cole Robinson 已提交
2357

2358
cleanup:
2359 2360
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2361
    return ret;
C
Cole Robinson 已提交
2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377
}

static char *
testStorageFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
                           const char *type ATTRIBUTE_UNUSED,
                           const char *srcSpec ATTRIBUTE_UNUSED,
                           unsigned int flags ATTRIBUTE_UNUSED)
{
    return NULL;
}


static virStoragePoolPtr
testStoragePoolCreate(virConnectPtr conn,
                      const char *xml,
                      unsigned int flags ATTRIBUTE_UNUSED) {
2378
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2379
    virStoragePoolDefPtr def;
2380
    virStoragePoolObjPtr pool = NULL;
2381
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
2382

2383
    testDriverLock(privconn);
C
Cole Robinson 已提交
2384
    if (!(def = virStoragePoolDefParse(conn, xml, NULL)))
2385
        goto cleanup;
C
Cole Robinson 已提交
2386

2387 2388 2389 2390
    pool = virStoragePoolObjFindByUUID(&privconn->pools, def->uuid);
    if (!pool)
        pool = virStoragePoolObjFindByName(&privconn->pools, def->name);
    if (pool) {
C
Cole Robinson 已提交
2391 2392
        testError(conn, VIR_ERR_INTERNAL_ERROR,
                  "%s", _("storage pool already exists"));
2393
        goto cleanup;
C
Cole Robinson 已提交
2394 2395 2396
    }

    if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools, def))) {
2397
        goto cleanup;
C
Cole Robinson 已提交
2398
    }
2399
    def = NULL;
C
Cole Robinson 已提交
2400 2401 2402

    if (testStoragePoolObjSetDefaults(pool) == -1) {
        virStoragePoolObjRemove(&privconn->pools, pool);
2403 2404
        pool = NULL;
        goto cleanup;
C
Cole Robinson 已提交
2405 2406 2407
    }
    pool->active = 1;

2408 2409 2410 2411
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);

cleanup:
    virStoragePoolDefFree(def);
2412 2413 2414
    if (pool)
        virStoragePoolObjUnlock(pool);
    testDriverUnlock(privconn);
2415
    return ret;
C
Cole Robinson 已提交
2416 2417 2418 2419 2420 2421
}

static virStoragePoolPtr
testStoragePoolDefine(virConnectPtr conn,
                      const char *xml,
                      unsigned int flags ATTRIBUTE_UNUSED) {
2422
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2423
    virStoragePoolDefPtr def;
2424
    virStoragePoolObjPtr pool = NULL;
2425
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
2426

2427
    testDriverLock(privconn);
C
Cole Robinson 已提交
2428
    if (!(def = virStoragePoolDefParse(conn, xml, NULL)))
2429
        goto cleanup;
C
Cole Robinson 已提交
2430 2431 2432 2433 2434 2435

    def->capacity = defaultPoolCap;
    def->allocation = defaultPoolAlloc;
    def->available = defaultPoolCap - defaultPoolAlloc;

    if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools, def))) {
2436
        goto cleanup;
C
Cole Robinson 已提交
2437
    }
2438
    def = NULL;
C
Cole Robinson 已提交
2439 2440 2441

    if (testStoragePoolObjSetDefaults(pool) == -1) {
        virStoragePoolObjRemove(&privconn->pools, pool);
2442 2443
        pool = NULL;
        goto cleanup;
C
Cole Robinson 已提交
2444 2445
    }

2446 2447 2448 2449
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);

cleanup:
    virStoragePoolDefFree(def);
2450 2451 2452
    if (pool)
        virStoragePoolObjUnlock(pool);
    testDriverUnlock(privconn);
2453
    return ret;
C
Cole Robinson 已提交
2454 2455 2456
}

static int
2457 2458 2459
testStoragePoolUndefine(virStoragePoolPtr pool) {
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2460
    int ret = -1;
2461

2462
    testDriverLock(privconn);
2463 2464 2465 2466 2467
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2468
        goto cleanup;
2469 2470
    }

2471 2472 2473 2474 2475
    if (virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is already active"), pool->name);
        goto cleanup;
    }
C
Cole Robinson 已提交
2476 2477

    virStoragePoolObjRemove(&privconn->pools, privpool);
2478
    ret = 0;
C
Cole Robinson 已提交
2479

2480
cleanup:
2481 2482 2483
    if (privpool)
        virStoragePoolObjUnlock(privpool);
    testDriverUnlock(privconn);
2484
    return ret;
C
Cole Robinson 已提交
2485 2486 2487
}

static int
2488
testStoragePoolBuild(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2489
                     unsigned int flags ATTRIBUTE_UNUSED) {
2490 2491
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2492
    int ret = -1;
2493

2494
    testDriverLock(privconn);
2495 2496
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2497
    testDriverUnlock(privconn);
2498 2499 2500

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2501
        goto cleanup;
2502 2503
    }

2504 2505 2506 2507 2508
    if (virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is already active"), pool->name);
        goto cleanup;
    }
2509
    ret = 0;
C
Cole Robinson 已提交
2510

2511
cleanup:
2512 2513
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2514
    return ret;
C
Cole Robinson 已提交
2515 2516 2517 2518
}


static int
2519 2520 2521
testStoragePoolDestroy(virStoragePoolPtr pool) {
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2522
    int ret = -1;
2523

2524
    testDriverLock(privconn);
2525 2526 2527 2528 2529
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2530
        goto cleanup;
2531 2532 2533 2534 2535
    }

    if (!virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), pool->name);
2536
        goto cleanup;
2537
    }
C
Cole Robinson 已提交
2538 2539 2540

    privpool->active = 0;

2541
    if (privpool->configFile == NULL) {
C
Cole Robinson 已提交
2542
        virStoragePoolObjRemove(&privconn->pools, privpool);
2543 2544
        privpool = NULL;
    }
2545
    ret = 0;
C
Cole Robinson 已提交
2546

2547
cleanup:
2548 2549 2550
    if (privpool)
        virStoragePoolObjUnlock(privpool);
    testDriverUnlock(privconn);
2551
    return ret;
C
Cole Robinson 已提交
2552 2553 2554 2555
}


static int
2556
testStoragePoolDelete(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2557
                      unsigned int flags ATTRIBUTE_UNUSED) {
2558 2559
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2560
    int ret = -1;
2561

2562
    testDriverLock(privconn);
2563 2564
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2565
    testDriverUnlock(privconn);
2566 2567 2568

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2569 2570 2571 2572 2573 2574 2575
        goto cleanup;
    }

    if (virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is already active"), pool->name);
        goto cleanup;
2576 2577
    }

2578
    ret = 0;
C
Cole Robinson 已提交
2579

2580
cleanup:
2581 2582
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2583
    return ret;
C
Cole Robinson 已提交
2584 2585 2586 2587
}


static int
2588
testStoragePoolRefresh(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2589
                       unsigned int flags ATTRIBUTE_UNUSED) {
2590 2591
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2592
    int ret = -1;
2593

2594
    testDriverLock(privconn);
2595 2596
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2597
    testDriverUnlock(privconn);
2598 2599 2600

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2601
        goto cleanup;
2602 2603 2604 2605 2606
    }

    if (!virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), pool->name);
2607
        goto cleanup;
2608
    }
2609
    ret = 0;
C
Cole Robinson 已提交
2610

2611
cleanup:
2612 2613
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2614
    return ret;
C
Cole Robinson 已提交
2615 2616 2617 2618
}


static int
2619
testStoragePoolGetInfo(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2620
                       virStoragePoolInfoPtr info) {
2621 2622
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2623
    int ret = -1;
2624

2625
    testDriverLock(privconn);
2626 2627
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2628
    testDriverUnlock(privconn);
2629 2630 2631

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2632
        goto cleanup;
2633
    }
C
Cole Robinson 已提交
2634 2635 2636 2637 2638 2639 2640 2641 2642

    memset(info, 0, sizeof(virStoragePoolInfo));
    if (privpool->active)
        info->state = VIR_STORAGE_POOL_RUNNING;
    else
        info->state = VIR_STORAGE_POOL_INACTIVE;
    info->capacity = privpool->def->capacity;
    info->allocation = privpool->def->allocation;
    info->available = privpool->def->available;
2643
    ret = 0;
C
Cole Robinson 已提交
2644

2645
cleanup:
2646 2647
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2648
    return ret;
C
Cole Robinson 已提交
2649 2650 2651
}

static char *
2652
testStoragePoolDumpXML(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2653
                       unsigned int flags ATTRIBUTE_UNUSED) {
2654 2655
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2656
    char *ret = NULL;
2657

2658
    testDriverLock(privconn);
2659 2660
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2661
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2662

2663 2664
    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2665
        goto cleanup;
2666 2667
    }

2668 2669 2670
    ret = virStoragePoolDefFormat(pool->conn, privpool->def);

cleanup:
2671 2672
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2673
    return ret;
C
Cole Robinson 已提交
2674 2675 2676
}

static int
2677
testStoragePoolGetAutostart(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2678
                            int *autostart) {
2679 2680
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2681
    int ret = -1;
2682

2683
    testDriverLock(privconn);
2684 2685
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2686
    testDriverUnlock(privconn);
2687 2688 2689

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2690
        goto cleanup;
2691
    }
C
Cole Robinson 已提交
2692 2693 2694 2695 2696 2697

    if (!privpool->configFile) {
        *autostart = 0;
    } else {
        *autostart = privpool->autostart;
    }
2698
    ret = 0;
C
Cole Robinson 已提交
2699

2700
cleanup:
2701 2702
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2703
    return ret;
C
Cole Robinson 已提交
2704 2705 2706
}

static int
2707
testStoragePoolSetAutostart(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2708
                            int autostart) {
2709 2710
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2711
    int ret = -1;
2712

2713
    testDriverLock(privconn);
2714 2715
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2716
    testDriverUnlock(privconn);
2717 2718 2719

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2720
        goto cleanup;
2721
    }
C
Cole Robinson 已提交
2722 2723

    if (!privpool->configFile) {
2724
        testError(pool->conn, VIR_ERR_INVALID_ARG,
C
Cole Robinson 已提交
2725
                  "%s", _("pool has no config file"));
2726
        goto cleanup;
C
Cole Robinson 已提交
2727 2728 2729 2730
    }

    autostart = (autostart != 0);
    privpool->autostart = autostart;
2731 2732 2733
    ret = 0;

cleanup:
2734 2735
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2736
    return ret;
C
Cole Robinson 已提交
2737 2738 2739 2740
}


static int
2741 2742 2743
testStoragePoolNumVolumes(virStoragePoolPtr pool) {
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2744
    int ret = -1;
2745

2746
    testDriverLock(privconn);
2747 2748
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2749
    testDriverUnlock(privconn);
2750 2751 2752

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2753
        goto cleanup;
2754 2755 2756 2757 2758
    }

    if (!virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), pool->name);
2759
        goto cleanup;
2760
    }
C
Cole Robinson 已提交
2761

2762 2763 2764
    ret = privpool->volumes.count;

cleanup:
2765 2766
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2767
    return ret;
C
Cole Robinson 已提交
2768 2769 2770
}

static int
2771
testStoragePoolListVolumes(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2772 2773
                           char **const names,
                           int maxnames) {
2774 2775
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
C
Cole Robinson 已提交
2776 2777
    int i = 0, n = 0;

2778
    memset(names, 0, maxnames * sizeof(*names));
2779 2780

    testDriverLock(privconn);
2781 2782
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2783
    testDriverUnlock(privconn);
2784 2785 2786

    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2787
        goto cleanup;
2788 2789 2790 2791 2792 2793
    }


    if (!virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), pool->name);
2794
        goto cleanup;
2795 2796
    }

C
Cole Robinson 已提交
2797 2798
    for (i = 0 ; i < privpool->volumes.count && n < maxnames ; i++) {
        if ((names[n++] = strdup(privpool->volumes.objs[i]->name)) == NULL) {
2799
            testError(pool->conn, VIR_ERR_NO_MEMORY, "%s", _("name"));
C
Cole Robinson 已提交
2800 2801 2802 2803
            goto cleanup;
        }
    }

2804
    virStoragePoolObjUnlock(privpool);
C
Cole Robinson 已提交
2805 2806 2807 2808 2809 2810
    return n;

 cleanup:
    for (n = 0 ; n < maxnames ; n++)
        VIR_FREE(names[i]);

2811
    memset(names, 0, maxnames * sizeof(*names));
2812 2813
    if (privpool)
        virStoragePoolObjUnlock(privpool);
C
Cole Robinson 已提交
2814 2815 2816 2817 2818
    return -1;
}


static virStorageVolPtr
2819
testStorageVolumeLookupByName(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2820
                              const char *name ATTRIBUTE_UNUSED) {
2821 2822 2823
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
2824
    virStorageVolPtr ret = NULL;
2825

2826
    testDriverLock(privconn);
2827 2828
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2829
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2830

2831 2832
    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2833
        goto cleanup;
2834 2835 2836 2837 2838 2839
    }


    if (!virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), pool->name);
2840
        goto cleanup;
2841 2842 2843 2844 2845 2846
    }

    privvol = virStorageVolDefFindByName(privpool, name);

    if (!privvol) {
        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
C
Cole Robinson 已提交
2847
                  _("no storage vol with matching name '%s'"), name);
2848
        goto cleanup;
C
Cole Robinson 已提交
2849 2850
    }

2851 2852 2853 2854
    ret = virGetStorageVol(pool->conn, privpool->def->name,
                           privvol->name, privvol->key);

cleanup:
2855 2856
    if (privpool)
        virStoragePoolObjUnlock(privpool);
2857
    return ret;
C
Cole Robinson 已提交
2858 2859 2860 2861 2862 2863
}


static virStorageVolPtr
testStorageVolumeLookupByKey(virConnectPtr conn,
                             const char *key) {
2864
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2865
    unsigned int i;
2866
    virStorageVolPtr ret = NULL;
C
Cole Robinson 已提交
2867

2868
    testDriverLock(privconn);
C
Cole Robinson 已提交
2869
    for (i = 0 ; i < privconn->pools.count ; i++) {
2870
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2871
        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
2872
            virStorageVolDefPtr privvol =
C
Cole Robinson 已提交
2873 2874
                virStorageVolDefFindByKey(privconn->pools.objs[i], key);

2875 2876 2877 2878 2879
            if (privvol) {
                ret = virGetStorageVol(conn,
                                       privconn->pools.objs[i]->def->name,
                                       privvol->name,
                                       privvol->key);
2880
                virStoragePoolObjUnlock(privconn->pools.objs[i]);
2881 2882
                break;
            }
C
Cole Robinson 已提交
2883
        }
2884
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2885
    }
2886
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2887

2888 2889 2890 2891 2892
    if (!ret)
        testError(conn, VIR_ERR_INVALID_STORAGE_VOL,
                  _("no storage vol with matching key '%s'"), key);

    return ret;
C
Cole Robinson 已提交
2893 2894 2895 2896 2897
}

static virStorageVolPtr
testStorageVolumeLookupByPath(virConnectPtr conn,
                              const char *path) {
2898
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
2899
    unsigned int i;
2900
    virStorageVolPtr ret = NULL;
C
Cole Robinson 已提交
2901

2902
    testDriverLock(privconn);
C
Cole Robinson 已提交
2903
    for (i = 0 ; i < privconn->pools.count ; i++) {
2904
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2905
        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
2906
            virStorageVolDefPtr privvol =
C
Cole Robinson 已提交
2907 2908
                virStorageVolDefFindByPath(privconn->pools.objs[i], path);

2909 2910 2911 2912 2913
            if (privvol) {
                ret = virGetStorageVol(conn,
                                       privconn->pools.objs[i]->def->name,
                                       privvol->name,
                                       privvol->key);
2914
                virStoragePoolObjUnlock(privconn->pools.objs[i]);
2915 2916
                break;
            }
2917
            virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
2918 2919
        }
    }
2920
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2921

2922 2923 2924 2925 2926
    if (!ret)
        testError(conn, VIR_ERR_INVALID_STORAGE_VOL,
                  _("no storage vol with matching path '%s'"), path);

    return ret;
C
Cole Robinson 已提交
2927 2928 2929
}

static virStorageVolPtr
2930
testStorageVolumeCreateXML(virStoragePoolPtr pool,
C
Cole Robinson 已提交
2931 2932
                           const char *xmldesc,
                           unsigned int flags ATTRIBUTE_UNUSED) {
2933 2934
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
2935 2936
    virStorageVolDefPtr privvol = NULL;
    virStorageVolPtr ret = NULL;
2937

2938
    testDriverLock(privconn);
2939 2940
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
2941
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
2942

2943 2944
    if (privpool == NULL) {
        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
2945
        goto cleanup;
2946 2947 2948 2949 2950 2951
    }


    if (!virStoragePoolObjIsActive(privpool)) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), pool->name);
2952
        goto cleanup;
2953
    }
C
Cole Robinson 已提交
2954

2955 2956 2957

    privvol = virStorageVolDefParse(pool->conn, privpool->def, xmldesc, NULL);
    if (privvol == NULL)
2958
        goto cleanup;
2959 2960 2961

    if (virStorageVolDefFindByName(privpool, privvol->name)) {
        testError(pool->conn, VIR_ERR_INVALID_STORAGE_POOL,
C
Cole Robinson 已提交
2962
                  "%s", _("storage vol already exists"));
2963
        goto cleanup;
C
Cole Robinson 已提交
2964 2965 2966
    }

    /* Make sure enough space */
2967
    if ((privpool->def->allocation + privvol->allocation) >
C
Cole Robinson 已提交
2968
         privpool->def->capacity) {
2969
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
C
Cole Robinson 已提交
2970
                  _("Not enough free space in pool for volume '%s'"),
2971
                  privvol->name);
2972
        goto cleanup;
C
Cole Robinson 已提交
2973 2974 2975 2976 2977 2978
    }
    privpool->def->available = (privpool->def->capacity -
                                privpool->def->allocation);

    if (VIR_REALLOC_N(privpool->volumes.objs,
                      privpool->volumes.count+1) < 0) {
2979
        testError(pool->conn, VIR_ERR_NO_MEMORY, NULL);
2980
        goto cleanup;
C
Cole Robinson 已提交
2981 2982
    }

2983 2984 2985 2986
    if (VIR_ALLOC_N(privvol->target.path,
                    strlen(privpool->def->target.path) +
                    1 + strlen(privvol->name) + 1) < 0) {
        testError(pool->conn, VIR_ERR_NO_MEMORY, "%s", _("target"));
2987
        goto cleanup;
C
Cole Robinson 已提交
2988 2989
    }

2990 2991 2992 2993 2994 2995
    strcpy(privvol->target.path, privpool->def->target.path);
    strcat(privvol->target.path, "/");
    strcat(privvol->target.path, privvol->name);
    privvol->key = strdup(privvol->target.path);
    if (privvol->key == NULL) {
        testError(pool->conn, VIR_ERR_INTERNAL_ERROR, "%s",
C
Cole Robinson 已提交
2996
                  _("storage vol key"));
2997
        goto cleanup;
C
Cole Robinson 已提交
2998 2999
    }

3000
    privpool->def->allocation += privvol->allocation;
C
Cole Robinson 已提交
3001 3002 3003
    privpool->def->available = (privpool->def->capacity -
                                privpool->def->allocation);

3004
    privpool->volumes.objs[privpool->volumes.count++] = privvol;
3005
    privvol = NULL;
C
Cole Robinson 已提交
3006

3007 3008 3009 3010 3011
    ret = virGetStorageVol(pool->conn, privpool->def->name,
                           privvol->name, privvol->key);

cleanup:
    virStorageVolDefFree(privvol);
3012 3013
    if (privpool)
        virStoragePoolObjUnlock(privpool);
3014
    return ret;
C
Cole Robinson 已提交
3015 3016 3017
}

static int
3018
testStorageVolumeDelete(virStorageVolPtr vol,
C
Cole Robinson 已提交
3019
                        unsigned int flags ATTRIBUTE_UNUSED) {
3020 3021 3022
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
C
Cole Robinson 已提交
3023
    int i;
3024
    int ret = -1;
C
Cole Robinson 已提交
3025

3026
    testDriverLock(privconn);
3027 3028
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
3029
    testDriverUnlock(privconn);
3030 3031 3032

    if (privpool == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
3033
        goto cleanup;
3034 3035 3036 3037 3038 3039 3040 3041 3042
    }


    privvol = virStorageVolDefFindByName(privpool, vol->name);

    if (privvol == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
                  _("no storage vol with matching name '%s'"),
                  vol->name);
3043
        goto cleanup;
3044 3045 3046 3047 3048
    }

    if (!virStoragePoolObjIsActive(privpool)) {
        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), vol->pool);
3049
        goto cleanup;
3050 3051 3052
    }


C
Cole Robinson 已提交
3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075
    privpool->def->allocation -= privvol->allocation;
    privpool->def->available = (privpool->def->capacity -
                                privpool->def->allocation);

    for (i = 0 ; i < privpool->volumes.count ; i++) {
        if (privpool->volumes.objs[i] == privvol) {
            virStorageVolDefFree(privvol);

            if (i < (privpool->volumes.count - 1))
                memmove(privpool->volumes.objs + i,
                        privpool->volumes.objs + i + 1,
                        sizeof(*(privpool->volumes.objs)) *
                                (privpool->volumes.count - (i + 1)));

            if (VIR_REALLOC_N(privpool->volumes.objs,
                              privpool->volumes.count - 1) < 0) {
                ; /* Failure to reduce memory allocation isn't fatal */
            }
            privpool->volumes.count--;

            break;
        }
    }
3076
    ret = 0;
C
Cole Robinson 已提交
3077

3078
cleanup:
3079 3080
    if (privpool)
        virStoragePoolObjUnlock(privpool);
3081
    return ret;
C
Cole Robinson 已提交
3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097
}


static int testStorageVolumeTypeForPool(int pooltype) {

    switch(pooltype) {
        case VIR_STORAGE_POOL_DIR:
        case VIR_STORAGE_POOL_FS:
        case VIR_STORAGE_POOL_NETFS:
            return VIR_STORAGE_VOL_FILE;
        default:
            return VIR_STORAGE_VOL_BLOCK;
    }
}

static int
3098
testStorageVolumeGetInfo(virStorageVolPtr vol,
C
Cole Robinson 已提交
3099
                         virStorageVolInfoPtr info) {
3100 3101 3102
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
3103
    int ret = -1;
3104

3105
    testDriverLock(privconn);
3106 3107
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
3108
    testDriverUnlock(privconn);
3109 3110 3111

    if (privpool == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
3112
        goto cleanup;
3113 3114 3115 3116 3117 3118 3119 3120
    }

    privvol = virStorageVolDefFindByName(privpool, vol->name);

    if (privvol == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
                  _("no storage vol with matching name '%s'"),
                  vol->name);
3121
        goto cleanup;
3122 3123 3124 3125 3126
    }

    if (!virStoragePoolObjIsActive(privpool)) {
        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), vol->pool);
3127
        goto cleanup;
3128
    }
C
Cole Robinson 已提交
3129 3130 3131 3132 3133

    memset(info, 0, sizeof(*info));
    info->type = testStorageVolumeTypeForPool(privpool->def->type);
    info->capacity = privvol->capacity;
    info->allocation = privvol->allocation;
3134
    ret = 0;
C
Cole Robinson 已提交
3135

3136
cleanup:
3137 3138
    if (privpool)
        virStoragePoolObjUnlock(privpool);
3139
    return ret;
C
Cole Robinson 已提交
3140 3141 3142
}

static char *
3143
testStorageVolumeGetXMLDesc(virStorageVolPtr vol,
C
Cole Robinson 已提交
3144
                            unsigned int flags ATTRIBUTE_UNUSED) {
3145 3146 3147
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
3148
    char *ret = NULL;
3149

3150
    testDriverLock(privconn);
3151 3152
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
3153
    testDriverUnlock(privconn);
3154 3155 3156

    if (privpool == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
3157
        goto cleanup;
3158 3159 3160 3161 3162 3163 3164 3165
    }

    privvol = virStorageVolDefFindByName(privpool, vol->name);

    if (privvol == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
                  _("no storage vol with matching name '%s'"),
                  vol->name);
3166
        goto cleanup;
3167
    }
C
Cole Robinson 已提交
3168

3169 3170 3171
    if (!virStoragePoolObjIsActive(privpool)) {
        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), vol->pool);
3172
        goto cleanup;
3173 3174
    }

3175 3176 3177
    ret = virStorageVolDefFormat(vol->conn, privpool->def, privvol);

cleanup:
3178 3179
    if (privpool)
        virStoragePoolObjUnlock(privpool);
3180
    return ret;
C
Cole Robinson 已提交
3181 3182 3183
}

static char *
3184 3185 3186 3187
testStorageVolumeGetPath(virStorageVolPtr vol) {
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
3188
    char *ret = NULL;
3189

3190
    testDriverLock(privconn);
3191 3192
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
3193
    testDriverUnlock(privconn);
3194 3195 3196

    if (privpool == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
3197
        goto cleanup;
3198 3199 3200 3201 3202 3203 3204 3205
    }

    privvol = virStorageVolDefFindByName(privpool, vol->name);

    if (privvol == NULL) {
        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
                  _("no storage vol with matching name '%s'"),
                  vol->name);
3206
        goto cleanup;
3207 3208 3209 3210 3211
    }

    if (!virStoragePoolObjIsActive(privpool)) {
        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
                  _("storage pool '%s' is not active"), vol->pool);
3212
        goto cleanup;
3213 3214
    }

C
Cole Robinson 已提交
3215
    ret = strdup(privvol->target.path);
3216
    if (ret == NULL)
3217
        testError(vol->conn, VIR_ERR_NO_MEMORY, "%s", _("path"));
3218 3219

cleanup:
3220 3221
    if (privpool)
        virStoragePoolObjUnlock(privpool);
C
Cole Robinson 已提交
3222 3223 3224
    return ret;
}

3225

3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241
static virDrvOpenStatus testDevMonOpen(virConnectPtr conn,
                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
                                       int flags ATTRIBUTE_UNUSED) {
    if (STRNEQ(conn->driver->name, "Test"))
        return VIR_DRV_OPEN_DECLINED;

    conn->devMonPrivateData = conn->privateData;
    return VIR_DRV_OPEN_SUCCESS;
}

static int testDevMonClose(virConnectPtr conn) {
    conn->devMonPrivateData = NULL;
    return 0;
}


3242 3243 3244 3245 3246
static virDriver testDriver = {
    VIR_DRV_TEST,
    "Test",
    testOpen, /* open */
    testClose, /* close */
3247
    NULL, /* supports_feature */
3248 3249 3250
    NULL, /* type */
    testGetVersion, /* version */
    testGetHostname, /* hostname */
3251
    NULL, /* URI */
3252 3253 3254 3255 3256
    testGetMaxVCPUs, /* getMaxVcpus */
    testNodeGetInfo, /* nodeGetInfo */
    testGetCapabilities, /* getCapabilities */
    testListDomains, /* listDomains */
    testNumOfDomains, /* numOfDomains */
3257
    testDomainCreateXML, /* domainCreateXML */
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
    testLookupDomainByID, /* domainLookupByID */
    testLookupDomainByUUID, /* domainLookupByUUID */
    testLookupDomainByName, /* domainLookupByName */
    testPauseDomain, /* domainSuspend */
    testResumeDomain, /* domainResume */
    testShutdownDomain, /* domainShutdown */
    testRebootDomain, /* domainReboot */
    testDestroyDomain, /* domainDestroy */
    testGetOSType, /* domainGetOSType */
    testGetMaxMemory, /* domainGetMaxMemory */
    testSetMaxMemory, /* domainSetMaxMemory */
    testSetMemory, /* domainSetMemory */
    testGetDomainInfo, /* domainGetInfo */
    testDomainSave, /* domainSave */
    testDomainRestore, /* domainRestore */
    testDomainCoreDump, /* domainCoreDump */
    testSetVcpus, /* domainSetVcpus */
    NULL, /* domainPinVcpu */
    NULL, /* domainGetVcpus */
    NULL, /* domainGetMaxVcpus */
    testDomainDumpXML, /* domainDumpXML */
    testListDefinedDomains, /* listDefinedDomains */
    testNumOfDefinedDomains, /* numOfDefinedDomains */
    testDomainCreate, /* domainCreate */
    testDomainDefineXML, /* domainDefineXML */
    testDomainUndefine, /* domainUndefine */
    NULL, /* domainAttachDevice */
    NULL, /* domainDetachDevice */
    testDomainGetAutostart, /* domainGetAutostart */
    testDomainSetAutostart, /* domainSetAutostart */
    testDomainGetSchedulerType, /* domainGetSchedulerType */
    testDomainGetSchedulerParams, /* domainGetSchedulerParameters */
    testDomainSetSchedulerParams, /* domainSetSchedulerParameters */
3291 3292 3293
    NULL, /* domainMigratePrepare */
    NULL, /* domainMigratePerform */
    NULL, /* domainMigrateFinish */
3294 3295
    NULL, /* domainBlockStats */
    NULL, /* domainInterfaceStats */
R
Richard W.M. Jones 已提交
3296
    NULL, /* domainBlockPeek */
R
Richard W.M. Jones 已提交
3297
    NULL, /* domainMemoryPeek */
3298
    testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
3299
    NULL, /* getFreeMemory */
3300 3301
    NULL, /* domainEventRegister */
    NULL, /* domainEventDeregister */
D
Daniel Veillard 已提交
3302 3303
    NULL, /* domainMigratePrepare2 */
    NULL, /* domainMigrateFinish2 */
3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326
};

static virNetworkDriver testNetworkDriver = {
    "Test",
    testOpenNetwork, /* open */
    testCloseNetwork, /* close */
    testNumNetworks, /* numOfNetworks */
    testListNetworks, /* listNetworks */
    testNumDefinedNetworks, /* numOfDefinedNetworks */
    testListDefinedNetworks, /* listDefinedNetworks */
    testLookupNetworkByUUID, /* networkLookupByUUID */
    testLookupNetworkByName, /* networkLookupByName */
    testNetworkCreate, /* networkCreateXML */
    testNetworkDefine, /* networkDefineXML */
    testNetworkUndefine, /* networkUndefine */
    testNetworkStart, /* networkCreate */
    testNetworkDestroy, /* networkDestroy */
    testNetworkDumpXML, /* networkDumpXML */
    testNetworkGetBridgeName, /* networkGetBridgeName */
    testNetworkGetAutostart, /* networkGetAutostart */
    testNetworkSetAutostart, /* networkSetAutostart */
};

3327 3328 3329 3330
static virStorageDriver testStorageDriver = {
    .name = "Test",
    .open = testStorageOpen,
    .close = testStorageClose,
C
Cole Robinson 已提交
3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362

    .numOfPools = testStorageNumPools,
    .listPools = testStorageListPools,
    .numOfDefinedPools = testStorageNumDefinedPools,
    .listDefinedPools = testStorageListDefinedPools,
    .findPoolSources = testStorageFindPoolSources,
    .poolLookupByName = testStoragePoolLookupByName,
    .poolLookupByUUID = testStoragePoolLookupByUUID,
    .poolLookupByVolume = testStoragePoolLookupByVolume,
    .poolCreateXML = testStoragePoolCreate,
    .poolDefineXML = testStoragePoolDefine,
    .poolBuild = testStoragePoolBuild,
    .poolUndefine = testStoragePoolUndefine,
    .poolCreate = testStoragePoolStart,
    .poolDestroy = testStoragePoolDestroy,
    .poolDelete = testStoragePoolDelete,
    .poolRefresh = testStoragePoolRefresh,
    .poolGetInfo = testStoragePoolGetInfo,
    .poolGetXMLDesc = testStoragePoolDumpXML,
    .poolGetAutostart = testStoragePoolGetAutostart,
    .poolSetAutostart = testStoragePoolSetAutostart,
    .poolNumOfVolumes = testStoragePoolNumVolumes,
    .poolListVolumes = testStoragePoolListVolumes,

    .volLookupByName = testStorageVolumeLookupByName,
    .volLookupByKey = testStorageVolumeLookupByKey,
    .volLookupByPath = testStorageVolumeLookupByPath,
    .volCreateXML = testStorageVolumeCreateXML,
    .volDelete = testStorageVolumeDelete,
    .volGetInfo = testStorageVolumeGetInfo,
    .volGetXMLDesc = testStorageVolumeGetXMLDesc,
    .volGetPath = testStorageVolumeGetPath,
3363 3364
};

3365 3366 3367 3368 3369 3370 3371 3372
static virDeviceMonitor testDevMonitor = {
    .name = "Test",
    .open = testDevMonOpen,
    .close = testDevMonClose,
};



3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384
/**
 * testRegister:
 *
 * Registers the test driver
 */
int
testRegister(void)
{
    if (virRegisterDriver(&testDriver) < 0)
        return -1;
    if (virRegisterNetworkDriver(&testNetworkDriver) < 0)
        return -1;
3385 3386
    if (virRegisterStorageDriver(&testStorageDriver) < 0)
        return -1;
3387 3388 3389
    if (virRegisterDeviceMonitor(&testDevMonitor) < 0)
        return -1;

3390 3391
    return 0;
}