test_driver.c 164.9 KB
Newer Older
1 2 3
/*
 * test.c: A "mock" hypervisor for use by application unit tests
 *
4
 * Copyright (C) 2006-2012 Red Hat, Inc.
5
 * Copyright (C) 2006 Daniel P. Berrange
6
 *
7 8 9 10 11 12 13 14 15 16 17
 * 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
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
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 "virerror.h"
36
#include "datatypes.h"
37
#include "test_driver.h"
38
#include "virbuffer.h"
39
#include "virutil.h"
40
#include "viruuid.h"
41
#include "capabilities.h"
42
#include "viralloc.h"
43
#include "network_conf.h"
L
Laine Stump 已提交
44
#include "interface_conf.h"
45
#include "domain_conf.h"
46
#include "domain_event.h"
C
Cole Robinson 已提交
47
#include "storage_conf.h"
48
#include "node_device_conf.h"
49
#include "virxml.h"
50
#include "virthread.h"
51
#include "virlog.h"
E
Eric Blake 已提交
52
#include "virfile.h"
53
#include "virtypedparam.h"
54
#include "virrandom.h"
55

56 57
#define VIR_FROM_THIS VIR_FROM_TEST

58 59 60 61 62 63 64 65 66
/* Driver specific info to carry with a domain */
struct _testDomainObjPrivate {
    virVcpuInfoPtr vcpu_infos;

    unsigned char *cpumaps;
};
typedef struct _testDomainObjPrivate testDomainObjPrivate;
typedef struct _testDomainObjPrivate *testDomainObjPrivatePtr;

67 68 69 70 71
#define MAX_CPUS 128

struct _testCell {
    unsigned long mem;
    int numCpus;
72
    virCapsHostNUMACellCPU cpus[MAX_CPUS];
73 74 75 76 77
};
typedef struct _testCell testCell;
typedef struct _testCell *testCellPtr;

#define MAX_CELLS 128
78

79
struct _testConn {
80
    virMutex lock;
81

E
Eric Blake 已提交
82
    char *path;
83
    int nextDomID;
84
    virCapsPtr caps;
85
    virNodeInfo nodeInfo;
86
    virDomainObjListPtr domains;
87
    virNetworkObjList networks;
L
Laine Stump 已提交
88
    virInterfaceObjList ifaces;
89 90
    bool transaction_running;
    virInterfaceObjList backupIfaces;
C
Cole Robinson 已提交
91
    virStoragePoolObjList pools;
92
    virNodeDeviceObjList devs;
93 94
    int numCells;
    testCell cells[MAX_CELLS];
95

96
    virDomainEventStatePtr domainEventState;
97 98 99
};
typedef struct _testConn testConn;
typedef struct _testConn *testConnPtr;
100

101
#define TEST_MODEL "i686"
102
#define TEST_MODEL_WORDSIZE 32
103
#define TEST_EMULATOR "/usr/bin/test-hv"
104

105
static const virNodeInfo defaultNodeInfo = {
106
    TEST_MODEL,
107 108 109 110 111 112 113
    1024*1024*3, /* 3 GB */
    16,
    1400,
    2,
    2,
    2,
    2,
114 115
};

116

117 118 119 120 121
static int testClose(virConnectPtr conn);
static void testDomainEventQueue(testConnPtr driver,
                                 virDomainEventPtr event);


122 123
static void testDriverLock(testConnPtr driver)
{
124
    virMutexLock(&driver->lock);
125 126 127 128
}

static void testDriverUnlock(testConnPtr driver)
{
129
    virMutexUnlock(&driver->lock);
130 131
}

132 133 134 135 136 137 138 139 140 141 142 143 144 145
static void *testDomainObjPrivateAlloc(void)
{
    testDomainObjPrivatePtr priv;

    if (VIR_ALLOC(priv) < 0)
        return NULL;

    return priv;
}

static void testDomainObjPrivateFree(void *data)
{
    testDomainObjPrivatePtr priv = data;

D
Daniel P. Berrange 已提交
146
    VIR_FREE(priv->vcpu_infos);
147 148 149 150 151
    VIR_FREE(priv->cpumaps);
    VIR_FREE(priv);
}


152
static int testDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
153
                                  virArch arch ATTRIBUTE_UNUSED)
154 155 156 157
{
    return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
}

158 159
static virCapsPtr
testBuildCapabilities(virConnectPtr conn) {
160
    testConnPtr privconn = conn->privateData;
161 162 163 164
    virCapsPtr caps;
    virCapsGuestPtr guest;
    const char *const guest_types[] = { "hvm", "xen" };
    int i;
165

166
    if ((caps = virCapabilitiesNew(VIR_ARCH_I686, 0, 0)) == NULL)
167
        goto no_memory;
168

169 170
    caps->defaultConsoleTargetType = testDefaultConsoleType;

171 172 173 174
    if (virCapabilitiesAddHostFeature(caps, "pae") < 0)
        goto no_memory;
    if (virCapabilitiesAddHostFeature(caps ,"nonpae") < 0)
        goto no_memory;
175

176
    for (i = 0; i < privconn->numCells; i++) {
177 178 179 180 181 182 183 184 185
        virCapsHostNUMACellCPUPtr cpu_cells;

        if (VIR_ALLOC_N(cpu_cells, privconn->cells[i].numCpus) < 0)
            goto no_memory;

        memcpy(cpu_cells, privconn->cells[i].cpus,
               sizeof(*cpu_cells) * privconn->cells[i].numCpus);


186
        if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].numCpus,
187
                                           0, cpu_cells) < 0)
188
            goto no_memory;
189 190
    }

191 192 193
    for (i = 0; i < ARRAY_CARDINALITY(guest_types) ; i++) {
        if ((guest = virCapabilitiesAddGuest(caps,
                                             guest_types[i],
194
                                             VIR_ARCH_I686,
195 196 197 198 199
                                             TEST_EMULATOR,
                                             NULL,
                                             0,
                                             NULL)) == NULL)
            goto no_memory;
200

201 202 203 204 205 206 207
        if (virCapabilitiesAddGuestDomain(guest,
                                          "test",
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL)
            goto no_memory;
208

209 210 211 212
        if (virCapabilitiesAddGuestFeature(guest, "pae", 1, 1) == NULL)
            goto no_memory;
        if (virCapabilitiesAddGuestFeature(guest ,"nonpae", 1, 1) == NULL)
            goto no_memory;
213 214
    }

215 216 217
    caps->privateDataAllocFunc = testDomainObjPrivateAlloc;
    caps->privateDataFreeFunc = testDomainObjPrivateFree;

218 219 220 221 222
    caps->host.nsecModels = 1;
    if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0)
        goto no_memory;
    caps->host.secModels[0].model = strdup("testSecurity");
    if (!caps->host.secModels[0].model)
223 224
        goto no_memory;

225 226
    caps->host.secModels[0].doi = strdup("");
    if (!caps->host.secModels[0].doi)
227 228
        goto no_memory;

229
    return caps;
230

231
no_memory:
232
    virReportOOMError();
233
    virObjectUnref(caps);
234
    return NULL;
235 236
}

237

238 239 240
static const char *defaultDomainXML =
"<domain type='test'>"
"  <name>test</name>"
241
"  <uuid>6695eb01-f6a4-8304-79aa-97f2502e193f</uuid>"
242 243 244 245 246 247 248
"  <memory>8388608</memory>"
"  <currentMemory>2097152</currentMemory>"
"  <vcpu>2</vcpu>"
"  <os>"
"    <type>hvm</type>"
"  </os>"
"</domain>";
249 250


251 252 253
static const char *defaultNetworkXML =
"<network>"
"  <name>default</name>"
254
"  <uuid>dd8fe884-6c02-601e-7551-cca97df1c5df</uuid>"
255 256 257 258 259 260 261 262
"  <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>";
263

L
Laine Stump 已提交
264 265 266 267 268 269 270 271 272 273 274
static const char *defaultInterfaceXML =
"<interface type=\"ethernet\" name=\"eth1\">"
"  <start mode=\"onboot\"/>"
"  <mac address=\"aa:bb:cc:dd:ee:ff\"/>"
"  <mtu size=\"1492\"/>"
"  <protocol family=\"ipv4\">"
"    <ip address=\"192.168.0.5\" prefix=\"24\"/>"
"    <route gateway=\"192.168.0.1\"/>"
"  </protocol>"
"</interface>";

C
Cole Robinson 已提交
275 276 277
static const char *defaultPoolXML =
"<pool type='dir'>"
"  <name>default-pool</name>"
278
"  <uuid>dfe224cb-28fb-8dd0-c4b2-64eb3f0f4566</uuid>"
C
Cole Robinson 已提交
279 280 281 282 283
"  <target>"
"    <path>/default-pool</path>"
"  </target>"
"</pool>";

284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
static const char *defaultPoolSourcesLogicalXML =
"<sources>\n"
"  <source>\n"
"    <device path='/dev/sda20'/>\n"
"    <name>testvg1</name>\n"
"    <format type='lvm2'/>\n"
"  </source>\n"
"  <source>\n"
"    <device path='/dev/sda21'/>\n"
"    <name>testvg2</name>\n"
"    <format type='lvm2'/>\n"
"  </source>\n"
"</sources>\n";

static const char *defaultPoolSourcesNetFSXML =
"<sources>\n"
"  <source>\n"
"    <host name='%s'/>\n"
"    <dir path='/testshare'/>\n"
"    <format type='nfs'/>\n"
"  </source>\n"
"</sources>\n";

307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
static const char *defaultNodeXML =
"<device>"
"  <name>computer</name>"
"  <capability type='system'>"
"    <hardware>"
"      <vendor>Libvirt</vendor>"
"      <version>Test driver</version>"
"      <serial>123456</serial>"
"      <uuid>11111111-2222-3333-4444-555555555555</uuid>"
"    </hardware>"
"    <firmware>"
"      <vendor>Libvirt</vendor>"
"      <version>Test Driver</version>"
"      <release_date>01/22/2007</release_date>"
"    </firmware>"
"  </capability>"
"</device>";

325
static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull);
C
Cole Robinson 已提交
326 327
static const unsigned long long defaultPoolAlloc = 0;

328
static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool);
329
static int testNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
330

331
static char *
332
testDomainGenerateIfname(virDomainDefPtr domdef) {
333 334 335 336 337 338 339 340
    int maxif = 1024;
    int ifctr, i;

    for (ifctr = 0; ifctr < maxif; ++ifctr) {
        char *ifname;
        int found = 0;

        if (virAsprintf(&ifname, "testnet%d", ifctr) < 0) {
341
            virReportOOMError();
342 343 344 345 346 347
            return NULL;
        }

        /* Generate network interface names */
        for (i = 0 ; i < domdef->nnets ; i++) {
            if (domdef->nets[i]->ifname &&
348
                STREQ(domdef->nets[i]->ifname, ifname)) {
349 350 351 352 353 354 355 356 357
                found = 1;
                break;
            }
        }

        if (!found)
            return ifname;
    }

358 359
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("Exceeded max iface limit %d"), maxif);
360 361 362
    return NULL;
}

363
static int
364
testDomainGenerateIfnames(virDomainDefPtr domdef)
365 366 367 368 369 370 371 372
{
    int i = 0;

    for (i = 0; i < domdef->nnets; i++) {
        char *ifname;
        if (domdef->nets[i]->ifname)
            continue;

373
        ifname = testDomainGenerateIfname(domdef);
374
        if (!ifname)
375
            return -1;
376 377 378 379

        domdef->nets[i]->ifname = ifname;
    }

380
    return 0;
381 382
}

383 384 385 386 387 388 389 390 391 392 393 394
/* Helper to update info for a single VCPU */
static int
testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
                     virDomainObjPtr dom,
                     int vcpu,
                     int maplen,
                     int maxcpu)
{
    testDomainObjPrivatePtr privdata = dom->privateData;
    virVcpuInfoPtr info = &privdata->vcpu_infos[vcpu];
    unsigned char *cpumap = VIR_GET_CPUMAP(privdata->cpumaps, maplen, vcpu);
    int j;
H
Hu Tao 已提交
395
    bool cpu;
396 397 398 399 400 401 402 403 404 405 406

    memset(info, 0, sizeof(virVcpuInfo));
    memset(cpumap, 0, maplen);

    info->number    = vcpu;
    info->state     = VIR_VCPU_RUNNING;
    info->cpuTime   = 5000000;
    info->cpu       = 0;

    if (dom->def->cpumask) {
        for (j = 0; j < maxcpu && j < VIR_DOMAIN_CPUMASK_LEN; ++j) {
H
Hu Tao 已提交
407 408 409
            if (virBitmapGetBit(dom->def->cpumask, j, &cpu) < 0)
                return -1;
            if (cpu) {
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
                VIR_USE_CPU(cpumap, j);
                info->cpu = j;
            }
        }
    } else {
        for (j = 0; j < maxcpu; ++j) {
            if ((j % 3) == 0) {
                /* Mark of every third CPU as usable */
                VIR_USE_CPU(cpumap, j);
                info->cpu = j;
            }
        }
    }

    return 0;
}

/*
 * Update domain VCPU amount and info
 *
 * @conn: virConnectPtr
 * @dom : domain needing updates
 * @nvcpus: New amount of vcpus for the domain
 * @clear_all: If true, rebuild info for ALL vcpus, not just newly added vcpus
 */
static int
testDomainUpdateVCPUs(virConnectPtr conn,
                      virDomainObjPtr dom,
                      int nvcpus,
                      unsigned int clear_all)
{
    testConnPtr privconn = conn->privateData;
    testDomainObjPrivatePtr privdata = dom->privateData;
    int i, ret = -1;
    int cpumaplen, maxcpu;

    maxcpu  = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo);
    cpumaplen = VIR_CPU_MAPLEN(maxcpu);

    if (VIR_REALLOC_N(privdata->vcpu_infos, nvcpus) < 0) {
450
        virReportOOMError();
451 452 453 454
        goto cleanup;
    }

    if (VIR_REALLOC_N(privdata->cpumaps, nvcpus * cpumaplen) < 0) {
455
        virReportOOMError();
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
        goto cleanup;
    }

    /* Set running VCPU and cpumap state */
    if (clear_all) {
        for (i = 0; i < nvcpus; ++i)
            if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) < 0)
                goto cleanup;

    } else if (nvcpus > dom->def->vcpus) {
        /* VCPU amount has grown, populate info for the new vcpus */
        for (i = dom->def->vcpus; i < nvcpus; ++i)
            if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) < 0)
                goto cleanup;
    }

472
    dom->def->vcpus = nvcpus;
473 474 475 476 477
    ret = 0;
cleanup:
    return ret;
}

478 479
static void
testDomainShutdownState(virDomainPtr domain,
J
Jiri Denemark 已提交
480 481
                        virDomainObjPtr privdom,
                        virDomainShutoffReason reason)
482 483 484 485 486 487 488
{
    if (privdom->newDef) {
        virDomainDefFree(privdom->def);
        privdom->def = privdom->newDef;
        privdom->newDef = NULL;
    }

J
Jiri Denemark 已提交
489
    virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF, reason);
490 491 492 493 494
    privdom->def->id = -1;
    if (domain)
        domain->id = -1;
}

495
/* Set up domain runtime state */
496 497
static int
testDomainStartState(virConnectPtr conn,
J
Jiri Denemark 已提交
498 499
                     virDomainObjPtr dom,
                     virDomainRunningReason reason)
500 501
{
    testConnPtr privconn = conn->privateData;
502
    int ret = -1;
503

504 505 506
    if (testDomainUpdateVCPUs(conn, dom, dom->def->vcpus, 1) < 0)
        goto cleanup;

J
Jiri Denemark 已提交
507
    virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, reason);
508 509
    dom->def->id = privconn->nextDomID++;

510
    if (virDomainObjSetDefTransient(privconn->caps, dom, false) < 0) {
511 512 513
        goto cleanup;
    }

514 515
    ret = 0;
cleanup:
516
    if (ret < 0)
J
Jiri Denemark 已提交
517
        testDomainShutdownState(NULL, dom, VIR_DOMAIN_SHUTOFF_FAILED);
518
    return ret;
519
}
520

521
static int testOpenDefault(virConnectPtr conn) {
522
    int u;
523
    testConnPtr privconn;
524 525 526 527
    virDomainDefPtr domdef = NULL;
    virDomainObjPtr domobj = NULL;
    virNetworkDefPtr netdef = NULL;
    virNetworkObjPtr netobj = NULL;
L
Laine Stump 已提交
528 529
    virInterfaceDefPtr interfacedef = NULL;
    virInterfaceObjPtr interfaceobj = NULL;
C
Cole Robinson 已提交
530 531
    virStoragePoolDefPtr pooldef = NULL;
    virStoragePoolObjPtr poolobj = NULL;
532 533
    virNodeDeviceDefPtr nodedef = NULL;
    virNodeDeviceObjPtr nodeobj = NULL;
534

535
    if (VIR_ALLOC(privconn) < 0) {
536
        virReportOOMError();
537 538
        return VIR_DRV_OPEN_ERROR;
    }
539
    if (virMutexInit(&privconn->lock) < 0) {
540 541
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot initialize mutex"));
542 543 544 545
        VIR_FREE(privconn);
        return VIR_DRV_OPEN_ERROR;
    }

546
    testDriverLock(privconn);
547
    conn->privateData = privconn;
548

549
    if (!(privconn->domains = virDomainObjListNew()))
550 551
        goto error;

552
    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
553

554
    /* Numa setup */
555 556 557 558 559 560
    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++) {
561 562 563 564 565 566 567 568 569 570
        virBitmapPtr siblings = virBitmapNew(16);
        if (!siblings) {
            virReportOOMError();
            goto error;
        }
        ignore_value(virBitmapSetBit(siblings, u));
        privconn->cells[u / 8].cpus[(u % 8)].id = u;
        privconn->cells[u / 8].cpus[(u % 8)].socket_id = u / 8;
        privconn->cells[u / 8].cpus[(u % 8)].core_id = u % 8;
        privconn->cells[u / 8].cpus[(u % 8)].siblings = siblings;
571 572
    }

573 574 575 576 577
    if (!(privconn->caps = testBuildCapabilities(conn)))
        goto error;

    privconn->nextDomID = 1;

M
Matthias Bolte 已提交
578 579
    if (!(domdef = virDomainDefParseString(privconn->caps, defaultDomainXML,
                                           1 << VIR_DOMAIN_VIRT_TEST,
580
                                           VIR_DOMAIN_XML_INACTIVE)))
581
        goto error;
M
Matthias Bolte 已提交
582

583
    if (testDomainGenerateIfnames(domdef) < 0)
584
        goto error;
585 586
    if (!(domobj = virDomainObjListAdd(privconn->domains,
                                       privconn->caps,
587
                                       domdef, 0, NULL)))
588 589
        goto error;
    domdef = NULL;
590

591
    domobj->persistent = 1;
J
Jiri Denemark 已提交
592
    if (testDomainStartState(conn, domobj, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
593
        virObjectUnlock(domobj);
594 595 596
        goto error;
    }

597
    virObjectUnlock(domobj);
598

599
    if (!(netdef = virNetworkDefParseString(defaultNetworkXML)))
600
        goto error;
601
    if (!(netobj = virNetworkAssignDef(&privconn->networks, netdef, false))) {
602 603 604 605 606
        virNetworkDefFree(netdef);
        goto error;
    }
    netobj->active = 1;
    netobj->persistent = 1;
607
    virNetworkObjUnlock(netobj);
608

609
    if (!(interfacedef = virInterfaceDefParseString(defaultInterfaceXML)))
L
Laine Stump 已提交
610
        goto error;
611
    if (!(interfaceobj = virInterfaceAssignDef(&privconn->ifaces, interfacedef))) {
L
Laine Stump 已提交
612 613 614 615 616 617
        virInterfaceDefFree(interfacedef);
        goto error;
    }
    interfaceobj->active = 1;
    virInterfaceObjUnlock(interfaceobj);

618
    if (!(pooldef = virStoragePoolDefParseString(defaultPoolXML)))
C
Cole Robinson 已提交
619 620
        goto error;

621
    if (!(poolobj = virStoragePoolObjAssignDef(&privconn->pools,
C
Cole Robinson 已提交
622 623 624 625
                                               pooldef))) {
        virStoragePoolDefFree(pooldef);
        goto error;
    }
626

627
    if (testStoragePoolObjSetDefaults(poolobj) == -1) {
628
        virStoragePoolObjUnlock(poolobj);
C
Cole Robinson 已提交
629
        goto error;
630
    }
C
Cole Robinson 已提交
631
    poolobj->active = 1;
632
    virStoragePoolObjUnlock(poolobj);
C
Cole Robinson 已提交
633

634
    /* Init default node device */
635
    if (!(nodedef = virNodeDeviceDefParseString(defaultNodeXML, 0, NULL)))
636
        goto error;
637
    if (!(nodeobj = virNodeDeviceAssignDef(&privconn->devs,
638 639 640 641 642 643
                                           nodedef))) {
        virNodeDeviceDefFree(nodedef);
        goto error;
    }
    virNodeDeviceObjUnlock(nodeobj);

644
    testDriverUnlock(privconn);
645

646 647 648
    return VIR_DRV_OPEN_SUCCESS;

error:
649
    virObjectUnref(privconn->domains);
650
    virNetworkObjListFree(&privconn->networks);
L
Laine Stump 已提交
651
    virInterfaceObjListFree(&privconn->ifaces);
C
Cole Robinson 已提交
652
    virStoragePoolObjListFree(&privconn->pools);
653
    virNodeDeviceObjListFree(&privconn->devs);
654
    virObjectUnref(privconn->caps);
655
    testDriverUnlock(privconn);
656
    conn->privateData = NULL;
657
    VIR_FREE(privconn);
658
    virDomainDefFree(domdef);
659
    return VIR_DRV_OPEN_ERROR;
660 661 662 663
}


static char *testBuildFilename(const char *relativeTo,
664 665 666 667
                               const char *filename) {
    char *offset;
    int baseLen;
    if (!filename || filename[0] == '\0')
668
        return NULL;
669 670 671
    if (filename[0] == '/')
        return strdup(filename);

672
    offset = strrchr(relativeTo, '/');
673
    if ((baseLen = (offset-relativeTo+1))) {
674
        char *absFile;
C
Chris Lalancette 已提交
675 676
        int totalLen = baseLen + strlen(filename) + 1;
        if (VIR_ALLOC_N(absFile, totalLen) < 0)
677
            return NULL;
C
Chris Lalancette 已提交
678 679 680 681
        if (virStrncpy(absFile, relativeTo, baseLen, totalLen) == NULL) {
            VIR_FREE(absFile);
            return NULL;
        }
682 683 684 685 686
        strcat(absFile, filename);
        return absFile;
    } else {
        return strdup(filename);
    }
687 688
}

689
static int testOpenVolumesForPool(xmlDocPtr xml,
690 691 692 693 694 695 696
                                  xmlXPathContextPtr ctxt,
                                  const char *file,
                                  virStoragePoolObjPtr pool,
                                  int poolidx) {
    char *vol_xpath;
    int i, ret, func_ret = -1;
    xmlNodePtr *vols = NULL;
697
    virStorageVolDefPtr def = NULL;
698 699 700

    /* Find storage volumes */
    if (virAsprintf(&vol_xpath, "/node/pool[%d]/volume", poolidx) < 0) {
701
        virReportOOMError();
702 703 704
        goto error;
    }

705
    ret = virXPathNodeSet(vol_xpath, ctxt, &vols);
706 707 708 709 710 711 712 713 714 715 716
    VIR_FREE(vol_xpath);
    if (ret < 0) {
        goto error;
    }

    for (i = 0 ; i < ret ; i++) {
        char *relFile = virXMLPropString(vols[i], "file");
        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);
            if (!absFile) {
717 718
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("resolving volume filename"));
719 720 721
                goto error;
            }

722
            def = virStorageVolDefParseFile(pool->def, absFile);
723 724 725 726
            VIR_FREE(absFile);
            if (!def)
                goto error;
        } else {
727
            if ((def = virStorageVolDefParseNode(pool->def, xml,
728 729 730 731 732 733 734
                                                 vols[i])) == NULL) {
                goto error;
            }
        }

        if (VIR_REALLOC_N(pool->volumes.objs,
                          pool->volumes.count+1) < 0) {
735
            virReportOOMError();
736 737 738
            goto error;
        }

739 740 741 742 743 744 745
        if (def->target.path == NULL) {
            if (virAsprintf(&def->target.path, "%s/%s",
                            pool->def->target.path,
                            def->name) == -1) {
                virReportOOMError();
                goto error;
            }
746 747 748
        }

        if (def->key == NULL) {
749 750 751 752 753
            def->key = strdup(def->target.path);
            if (def->key == NULL) {
                virReportOOMError();
                goto error;
            }
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
        }

        pool->def->allocation += def->allocation;
        pool->def->available = (pool->def->capacity -
                                pool->def->allocation);

        pool->volumes.objs[pool->volumes.count++] = def;
        def = NULL;
    }

    func_ret = 0;
error:
    virStorageVolDefFree(def);
    VIR_FREE(vols);
    return func_ret;
}

771
static int testOpenFromFile(virConnectPtr conn,
772
                            const char *file) {
773
    int i, ret;
774 775
    long l;
    char *str;
776
    xmlDocPtr xml = NULL;
777 778
    xmlNodePtr *domains = NULL, *networks = NULL, *ifaces = NULL,
               *pools = NULL, *devs = NULL;
779 780
    xmlXPathContextPtr ctxt = NULL;
    virNodeInfoPtr nodeInfo;
781
    virNetworkObjPtr net;
L
Laine Stump 已提交
782
    virInterfaceObjPtr iface;
783
    virDomainObjPtr dom;
784 785
    testConnPtr privconn;
    if (VIR_ALLOC(privconn) < 0) {
786
        virReportOOMError();
787 788
        return VIR_DRV_OPEN_ERROR;
    }
789
    if (virMutexInit(&privconn->lock) < 0) {
790 791
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot initialize mutex"));
792 793 794 795
        VIR_FREE(privconn);
        return VIR_DRV_OPEN_ERROR;
    }

796
    testDriverLock(privconn);
797
    conn->privateData = privconn;
798

799
    if (!(privconn->domains = virDomainObjListNew()))
800 801
        goto error;

802 803
    if (!(privconn->caps = testBuildCapabilities(conn)))
        goto error;
804

805
    if (!(xml = virXMLParseFileCtxt(file, &ctxt))) {
806
        goto error;
807 808
    }

809
    if (!xmlStrEqual(ctxt->node->name, BAD_CAST "node")) {
810 811
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("Root element is not 'node'"));
812
        goto error;
813 814
    }

815
    privconn->nextDomID = 1;
816
    privconn->numCells = 0;
E
Eric Blake 已提交
817 818
    if ((privconn->path = strdup(file)) == NULL) {
        virReportOOMError();
C
Chris Lalancette 已提交
819 820
        goto error;
    }
821 822 823
    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));

    nodeInfo = &privconn->nodeInfo;
824
    ret = virXPathLong("string(/node/cpu/nodes[1])", ctxt, &l);
825 826 827
    if (ret == 0) {
        nodeInfo->nodes = l;
    } else if (ret == -2) {
828 829
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node cpu nodes value"));
830
        goto error;
831
    }
832

833
    ret = virXPathLong("string(/node/cpu/sockets[1])", ctxt, &l);
834 835 836
    if (ret == 0) {
        nodeInfo->sockets = l;
    } else if (ret == -2) {
837 838
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node cpu sockets value"));
839
        goto error;
840
    }
841

842
    ret = virXPathLong("string(/node/cpu/cores[1])", ctxt, &l);
843 844 845
    if (ret == 0) {
        nodeInfo->cores = l;
    } else if (ret == -2) {
846 847
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node cpu cores value"));
848
        goto error;
849 850
    }

851
    ret = virXPathLong("string(/node/cpu/threads[1])", ctxt, &l);
852 853 854
    if (ret == 0) {
        nodeInfo->threads = l;
    } else if (ret == -2) {
855 856
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node cpu threads value"));
857
        goto error;
858
    }
859

860
    nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
861
    ret = virXPathLong("string(/node/cpu/active[1])", ctxt, &l);
862 863
    if (ret == 0) {
        if (l < nodeInfo->cpus) {
864 865
            nodeInfo->cpus = l;
        }
866
    } else if (ret == -2) {
867 868
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node cpu active value"));
869
        goto error;
870
    }
871
    ret = virXPathLong("string(/node/cpu/mhz[1])", ctxt, &l);
872 873 874
    if (ret == 0) {
        nodeInfo->mhz = l;
    } else if (ret == -2) {
875 876
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node cpu mhz value"));
877
        goto error;
878 879
    }

880
    str = virXPathString("string(/node/cpu/model[1])", ctxt);
881
    if (str != NULL) {
C
Chris Lalancette 已提交
882
        if (virStrcpyStatic(nodeInfo->model, str) == NULL) {
883 884
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Model %s too big for destination"), str);
C
Chris Lalancette 已提交
885 886 887
            VIR_FREE(str);
            goto error;
        }
888
        VIR_FREE(str);
889 890
    }

891
    ret = virXPathLong("string(/node/memory[1])", ctxt, &l);
892 893 894
    if (ret == 0) {
        nodeInfo->memory = l;
    } else if (ret == -2) {
895 896
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("invalid node memory value"));
897
        goto error;
898
    }
899

900
    ret = virXPathNodeSet("/node/domain", ctxt, &domains);
901
    if (ret < 0) {
902
        goto error;
903
    }
904

905
    for (i = 0 ; i < ret ; i++) {
906 907 908 909 910 911
        virDomainDefPtr def;
        char *relFile = virXMLPropString(domains[i], "file");
        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);
            if (!absFile) {
912 913
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("resolving domain filename"));
914 915
                goto error;
            }
916
            def = virDomainDefParseFile(privconn->caps, absFile,
M
Matthias Bolte 已提交
917
                                        1 << VIR_DOMAIN_VIRT_TEST,
918
                                        VIR_DOMAIN_XML_INACTIVE);
919
            VIR_FREE(absFile);
920 921 922
            if (!def)
                goto error;
        } else {
923
            if ((def = virDomainDefParseNode(privconn->caps, xml, domains[i],
M
Matthias Bolte 已提交
924
                                             1 << VIR_DOMAIN_VIRT_TEST,
925
                                             VIR_DOMAIN_XML_INACTIVE)) == NULL)
926 927 928
                goto error;
        }

929
        if (testDomainGenerateIfnames(def) < 0 ||
930 931
            !(dom = virDomainObjListAdd(privconn->domains,
                                        privconn->caps,
932
                                        def, 0, NULL))) {
933
            virDomainDefFree(def);
934 935
            goto error;
        }
936

937
        dom->persistent = 1;
J
Jiri Denemark 已提交
938
        if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
939
            virObjectUnlock(dom);
940 941 942
            goto error;
        }

943
        virObjectUnlock(dom);
944
    }
945
    VIR_FREE(domains);
946

947
    ret = virXPathNodeSet("/node/network", ctxt, &networks);
948 949 950 951 952 953 954 955 956
    if (ret < 0) {
        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);
957
            if (!absFile) {
958 959
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("resolving network filename"));
960 961
                goto error;
            }
962

963
            def = virNetworkDefParseFile(absFile);
964
            VIR_FREE(absFile);
965 966 967
            if (!def)
                goto error;
        } else {
968
            if ((def = virNetworkDefParseNode(xml, networks[i])) == NULL)
969
                goto error;
970
        }
971
        if (!(net = virNetworkAssignDef(&privconn->networks, def, false))) {
972 973
            virNetworkDefFree(def);
            goto error;
974
        }
975
        net->persistent = 1;
976
        net->active = 1;
977
        virNetworkObjUnlock(net);
978
    }
979
    VIR_FREE(networks);
980

L
Laine Stump 已提交
981
    /* Parse interface definitions */
982
    ret = virXPathNodeSet("/node/interface", ctxt, &ifaces);
L
Laine Stump 已提交
983 984 985 986 987 988 989 990 991 992
    if (ret < 0) {
        goto error;
    }
    for (i = 0 ; i < ret ; i++) {
        virInterfaceDefPtr def;
        char *relFile = virXMLPropString(ifaces[i], "file");
        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);
            if (!absFile) {
993 994
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("resolving interface filename"));
L
Laine Stump 已提交
995 996 997
                goto error;
            }

998
            def = virInterfaceDefParseFile(absFile);
L
Laine Stump 已提交
999 1000 1001 1002
            VIR_FREE(absFile);
            if (!def)
                goto error;
        } else {
1003
            if ((def = virInterfaceDefParseNode(xml, ifaces[i])) == NULL)
L
Laine Stump 已提交
1004 1005
                goto error;
        }
1006

1007
        if (!(iface = virInterfaceAssignDef(&privconn->ifaces, def))) {
L
Laine Stump 已提交
1008 1009 1010
            virInterfaceDefFree(def);
            goto error;
        }
1011 1012

        iface->active = 1;
L
Laine Stump 已提交
1013 1014 1015 1016
        virInterfaceObjUnlock(iface);
    }
    VIR_FREE(ifaces);

C
Cole Robinson 已提交
1017
    /* Parse Storage Pool list */
1018
    ret = virXPathNodeSet("/node/pool", ctxt, &pools);
C
Cole Robinson 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
    if (ret < 0) {
        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) {
1030 1031
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("resolving pool filename"));
C
Cole Robinson 已提交
1032 1033 1034
                goto error;
            }

1035
            def = virStoragePoolDefParseFile(absFile);
C
Cole Robinson 已提交
1036 1037 1038 1039
            VIR_FREE(absFile);
            if (!def)
                goto error;
        } else {
1040
            if ((def = virStoragePoolDefParseNode(xml,
1041
                                                  pools[i])) == NULL) {
C
Cole Robinson 已提交
1042 1043 1044 1045
                goto error;
            }
        }

1046
        if (!(pool = virStoragePoolObjAssignDef(&privconn->pools,
C
Cole Robinson 已提交
1047 1048 1049 1050 1051
                                                def))) {
            virStoragePoolDefFree(def);
            goto error;
        }

1052
        if (testStoragePoolObjSetDefaults(pool) == -1) {
1053
            virStoragePoolObjUnlock(pool);
C
Cole Robinson 已提交
1054
            goto error;
1055
        }
C
Cole Robinson 已提交
1056
        pool->active = 1;
1057 1058

        /* Find storage volumes */
1059
        if (testOpenVolumesForPool(xml, ctxt, file, pool, i+1) < 0) {
1060 1061 1062 1063
            virStoragePoolObjUnlock(pool);
            goto error;
        }

1064
        virStoragePoolObjUnlock(pool);
C
Cole Robinson 已提交
1065
    }
1066
    VIR_FREE(pools);
C
Cole Robinson 已提交
1067

1068
    ret = virXPathNodeSet("/node/device", ctxt, &devs);
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
    if (ret < 0) {
        goto error;
    }
    for (i = 0 ; i < ret ; i++) {
        virNodeDeviceDefPtr def;
        virNodeDeviceObjPtr dev;
        char *relFile = virXMLPropString(devs[i], "file");

        if (relFile != NULL) {
            char *absFile = testBuildFilename(file, relFile);
            VIR_FREE(relFile);

            if (!absFile) {
1082 1083
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("resolving device filename"));
1084 1085 1086
                goto error;
            }

1087
            def = virNodeDeviceDefParseFile(absFile, 0, NULL);
1088 1089 1090 1091
            VIR_FREE(absFile);
            if (!def)
                goto error;
        } else {
1092
            if ((def = virNodeDeviceDefParseNode(xml, devs[i], 0, NULL)) == NULL)
1093 1094
                goto error;
        }
1095
        if (!(dev = virNodeDeviceAssignDef(&privconn->devs, def))) {
1096 1097 1098 1099 1100 1101 1102 1103
            virNodeDeviceDefFree(def);
            goto error;
        }
        virNodeDeviceObjUnlock(dev);
    }
    VIR_FREE(devs);


J
Jim Meyering 已提交
1104
    xmlXPathFreeContext(ctxt);
1105
    xmlFreeDoc(xml);
1106
    testDriverUnlock(privconn);
1107

1108
    return 0;
1109 1110

 error:
J
Jim Meyering 已提交
1111
    xmlXPathFreeContext(ctxt);
1112
    xmlFreeDoc(xml);
1113 1114
    VIR_FREE(domains);
    VIR_FREE(networks);
L
Laine Stump 已提交
1115
    VIR_FREE(ifaces);
C
Cole Robinson 已提交
1116
    VIR_FREE(pools);
1117
    VIR_FREE(devs);
1118
    virObjectUnref(privconn->domains);
1119
    virNetworkObjListFree(&privconn->networks);
L
Laine Stump 已提交
1120
    virInterfaceObjListFree(&privconn->ifaces);
C
Cole Robinson 已提交
1121
    virStoragePoolObjListFree(&privconn->pools);
E
Eric Blake 已提交
1122
    VIR_FREE(privconn->path);
1123
    testDriverUnlock(privconn);
1124
    VIR_FREE(privconn);
1125
    conn->privateData = NULL;
1126
    return VIR_DRV_OPEN_ERROR;
1127 1128
}

1129

1130
static virDrvOpenStatus testOpen(virConnectPtr conn,
1131
                                 virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
1132
                                 unsigned int flags)
1133
{
1134
    int ret;
1135
    testConnPtr privconn;
1136

E
Eric Blake 已提交
1137 1138
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

1139
    if (!conn->uri)
1140
        return VIR_DRV_OPEN_DECLINED;
1141

1142
    if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "test"))
1143
        return VIR_DRV_OPEN_DECLINED;
1144

1145
    /* Remote driver should handle these. */
1146
    if (conn->uri->server)
1147 1148
        return VIR_DRV_OPEN_DECLINED;

1149
    /* From this point on, the connection is for us. */
1150 1151 1152
    if (!conn->uri->path
        || conn->uri->path[0] == '\0'
        || (conn->uri->path[0] == '/' && conn->uri->path[1] == '\0')) {
1153 1154
        virReportError(VIR_ERR_INVALID_ARG,
                       "%s", _("testOpen: supply a path or use test:///default"));
1155 1156
        return VIR_DRV_OPEN_ERROR;
    }
1157

1158
    if (STREQ(conn->uri->path, "/default"))
1159 1160
        ret = testOpenDefault(conn);
    else
1161
        ret = testOpenFromFile(conn,
1162
                               conn->uri->path);
1163

1164 1165 1166 1167 1168
    if (ret != VIR_DRV_OPEN_SUCCESS)
        return ret;

    privconn = conn->privateData;
    testDriverLock(privconn);
1169

1170
    privconn->domainEventState = virDomainEventStateNew();
1171
    if (!privconn->domainEventState) {
1172
        testDriverUnlock(privconn);
1173 1174
        testClose(conn);
        return VIR_DRV_OPEN_ERROR;
1175 1176
    }

1177 1178 1179
    testDriverUnlock(privconn);

    return VIR_DRV_OPEN_SUCCESS;
1180 1181
}

1182
static int testClose(virConnectPtr conn)
1183
{
1184
    testConnPtr privconn = conn->privateData;
1185
    testDriverLock(privconn);
1186
    virObjectUnref(privconn->caps);
1187
    virObjectUnref(privconn->domains);
D
Daniel P. Berrange 已提交
1188
    virNodeDeviceObjListFree(&privconn->devs);
1189
    virNetworkObjListFree(&privconn->networks);
L
Laine Stump 已提交
1190
    virInterfaceObjListFree(&privconn->ifaces);
C
Cole Robinson 已提交
1191
    virStoragePoolObjListFree(&privconn->pools);
1192
    virDomainEventStateFree(privconn->domainEventState);
E
Eric Blake 已提交
1193
    VIR_FREE(privconn->path);
1194

1195
    testDriverUnlock(privconn);
1196
    virMutexDestroy(&privconn->lock);
1197

1198
    VIR_FREE(privconn);
1199
    conn->privateData = NULL;
1200
    return 0;
1201 1202
}

1203 1204
static int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
                          unsigned long *hvVer)
1205
{
1206
    *hvVer = 2;
1207
    return 0;
1208 1209
}

1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
static int testIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    return 1;
}

static int testIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    return 0;
}

1220 1221 1222 1223 1224
static int testIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    return 1;
}

1225 1226 1227 1228 1229 1230 1231 1232
static int testGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
                           const char *type ATTRIBUTE_UNUSED)
{
    return 32;
}

static int testNodeGetInfo(virConnectPtr conn,
                           virNodeInfoPtr info)
1233
{
1234
    testConnPtr privconn = conn->privateData;
1235
    testDriverLock(privconn);
1236
    memcpy(info, &privconn->nodeInfo, sizeof(virNodeInfo));
1237
    testDriverUnlock(privconn);
1238
    return 0;
1239 1240
}

1241
static char *testGetCapabilities(virConnectPtr conn)
1242
{
1243
    testConnPtr privconn = conn->privateData;
1244
    char *xml;
1245
    testDriverLock(privconn);
1246
    if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
1247
        virReportOOMError();
1248
    testDriverUnlock(privconn);
1249
    return xml;
1250 1251
}

1252
static int testNumOfDomains(virConnectPtr conn)
1253
{
1254
    testConnPtr privconn = conn->privateData;
1255
    int count;
1256

1257
    testDriverLock(privconn);
1258
    count = virDomainObjListNumOfDomains(privconn->domains, 1);
1259
    testDriverUnlock(privconn);
1260

1261
    return count;
1262 1263
}

1264 1265 1266 1267 1268 1269 1270
static int testDomainIsActive(virDomainPtr dom)
{
    testConnPtr privconn = dom->conn->privateData;
    virDomainObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
1271
    obj = virDomainObjListFindByUUID(privconn->domains, dom->uuid);
1272 1273
    testDriverUnlock(privconn);
    if (!obj) {
1274
        virReportError(VIR_ERR_NO_DOMAIN, NULL);
1275 1276 1277 1278 1279 1280
        goto cleanup;
    }
    ret = virDomainObjIsActive(obj);

cleanup:
    if (obj)
1281
        virObjectUnlock(obj);
1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
    return ret;
}

static int testDomainIsPersistent(virDomainPtr dom)
{
    testConnPtr privconn = dom->conn->privateData;
    virDomainObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
1292
    obj = virDomainObjListFindByUUID(privconn->domains, dom->uuid);
1293 1294
    testDriverUnlock(privconn);
    if (!obj) {
1295
        virReportError(VIR_ERR_NO_DOMAIN, NULL);
1296 1297 1298 1299 1300 1301
        goto cleanup;
    }
    ret = obj->persistent;

cleanup:
    if (obj)
1302
        virObjectUnlock(obj);
1303 1304 1305
    return ret;
}

1306 1307 1308 1309 1310
static int testDomainIsUpdated(virDomainPtr dom ATTRIBUTE_UNUSED)
{
    return 0;
}

1311
static virDomainPtr
1312
testDomainCreateXML(virConnectPtr conn, const char *xml,
1313
                      unsigned int flags)
1314
{
1315
    testConnPtr privconn = conn->privateData;
1316
    virDomainPtr ret = NULL;
1317
    virDomainDefPtr def;
1318
    virDomainObjPtr dom = NULL;
1319
    virDomainEventPtr event = NULL;
1320

1321 1322
    virCheckFlags(0, NULL);

1323
    testDriverLock(privconn);
1324
    if ((def = virDomainDefParseString(privconn->caps, xml,
M
Matthias Bolte 已提交
1325
                                       1 << VIR_DOMAIN_VIRT_TEST,
1326
                                       VIR_DOMAIN_XML_INACTIVE)) == NULL)
1327
        goto cleanup;
1328

1329
    if (testDomainGenerateIfnames(def) < 0)
1330
        goto cleanup;
1331 1332
    if (!(dom = virDomainObjListAdd(privconn->domains,
                                    privconn->caps,
1333 1334 1335
                                    def,
                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
                                    NULL)))
1336 1337
        goto cleanup;
    def = NULL;
1338

J
Jiri Denemark 已提交
1339
    if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0)
1340
        goto cleanup;
1341

1342 1343 1344 1345
    event = virDomainEventNewFromObj(dom,
                                     VIR_DOMAIN_EVENT_STARTED,
                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);

1346
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
1347
    if (ret)
1348
        ret->id = dom->def->id;
1349 1350

cleanup:
1351
    if (dom)
1352
        virObjectUnlock(dom);
1353 1354
    if (event)
        testDomainEventQueue(privconn, event);
1355
    virDomainDefFree(def);
1356
    testDriverUnlock(privconn);
1357
    return ret;
1358 1359 1360
}


1361 1362
static virDomainPtr testLookupDomainByID(virConnectPtr conn,
                                         int id)
1363
{
1364
    testConnPtr privconn = conn->privateData;
1365 1366
    virDomainPtr ret = NULL;
    virDomainObjPtr dom;
1367

1368
    testDriverLock(privconn);
1369
    dom = virDomainObjListFindByID(privconn->domains, id);
1370 1371 1372
    testDriverUnlock(privconn);

    if (dom == NULL) {
1373
        virReportError(VIR_ERR_NO_DOMAIN, NULL);
1374
        goto cleanup;
1375 1376
    }

1377
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
1378 1379 1380 1381
    if (ret)
        ret->id = dom->def->id;

cleanup:
1382
    if (dom)
1383
        virObjectUnlock(dom);
1384
    return ret;
1385 1386
}

1387 1388
static virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
                                           const unsigned char *uuid)
1389
{
1390
    testConnPtr privconn = conn->privateData;
1391 1392
    virDomainPtr ret = NULL;
    virDomainObjPtr dom ;
1393

1394
    testDriverLock(privconn);
1395
    dom = virDomainObjListFindByUUID(privconn->domains, uuid);
1396 1397 1398
    testDriverUnlock(privconn);

    if (dom == NULL) {
1399
        virReportError(VIR_ERR_NO_DOMAIN, NULL);
1400
        goto cleanup;
1401
    }
1402

1403
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
1404 1405 1406 1407
    if (ret)
        ret->id = dom->def->id;

cleanup:
1408
    if (dom)
1409
        virObjectUnlock(dom);
1410
    return ret;
1411 1412
}

1413 1414
static virDomainPtr testLookupDomainByName(virConnectPtr conn,
                                           const char *name)
1415
{
1416
    testConnPtr privconn = conn->privateData;
1417 1418
    virDomainPtr ret = NULL;
    virDomainObjPtr dom;
1419

1420
    testDriverLock(privconn);
1421
    dom = virDomainObjListFindByName(privconn->domains, name);
1422 1423 1424
    testDriverUnlock(privconn);

    if (dom == NULL) {
1425
        virReportError(VIR_ERR_NO_DOMAIN, NULL);
1426
        goto cleanup;
1427
    }
1428

1429
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
1430 1431 1432 1433
    if (ret)
        ret->id = dom->def->id;

cleanup:
1434
    if (dom)
1435
        virObjectUnlock(dom);
1436
    return ret;
1437 1438
}

1439 1440 1441
static int testListDomains(virConnectPtr conn,
                           int *ids,
                           int maxids)
1442
{
1443
    testConnPtr privconn = conn->privateData;
1444
    int n;
1445

1446
    testDriverLock(privconn);
1447
    n = virDomainObjListGetActiveIDs(privconn->domains, ids, maxids);
1448
    testDriverUnlock(privconn);
1449

1450
    return n;
1451 1452
}

1453
static int testDestroyDomain(virDomainPtr domain)
1454
{
1455 1456
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1457
    virDomainEventPtr event = NULL;
1458
    int ret = -1;
1459

1460
    testDriverLock(privconn);
1461 1462
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1463 1464

    if (privdom == NULL) {
1465
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1466
        goto cleanup;
1467
    }
1468

J
Jiri Denemark 已提交
1469
    testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_DESTROYED);
1470 1471 1472
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_STOPPED,
                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
1473

1474
    if (!privdom->persistent) {
1475 1476
        virDomainObjListRemove(privconn->domains,
                               privdom);
1477
        privdom = NULL;
1478
    }
1479 1480 1481

    ret = 0;
cleanup:
1482
    if (privdom)
1483
        virObjectUnlock(privdom);
1484 1485
    if (event)
        testDomainEventQueue(privconn, event);
1486
    testDriverUnlock(privconn);
1487
    return ret;
1488 1489
}

1490
static int testResumeDomain(virDomainPtr domain)
1491
{
1492 1493
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1494
    virDomainEventPtr event = NULL;
1495
    int ret = -1;
1496

1497
    testDriverLock(privconn);
1498 1499
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1500
    testDriverUnlock(privconn);
1501 1502

    if (privdom == NULL) {
1503
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1504
        goto cleanup;
1505
    }
1506

J
Jiri Denemark 已提交
1507
    if (virDomainObjGetState(privdom, NULL) != VIR_DOMAIN_PAUSED) {
1508 1509
        virReportError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not paused"),
                       domain->name);
1510
        goto cleanup;
1511
    }
1512

J
Jiri Denemark 已提交
1513 1514
    virDomainObjSetState(privdom, VIR_DOMAIN_RUNNING,
                         VIR_DOMAIN_RUNNING_UNPAUSED);
1515 1516 1517
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_RESUMED,
                                     VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
1518 1519 1520
    ret = 0;

cleanup:
1521
    if (privdom)
1522
        virObjectUnlock(privdom);
1523 1524 1525 1526 1527
    if (event) {
        testDriverLock(privconn);
        testDomainEventQueue(privconn, event);
        testDriverUnlock(privconn);
    }
1528
    return ret;
1529 1530
}

1531
static int testPauseDomain(virDomainPtr domain)
1532
{
1533 1534
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1535
    virDomainEventPtr event = NULL;
1536
    int ret = -1;
J
Jiri Denemark 已提交
1537
    int state;
1538

1539
    testDriverLock(privconn);
1540 1541
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1542
    testDriverUnlock(privconn);
1543 1544

    if (privdom == NULL) {
1545
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1546
        goto cleanup;
1547
    }
1548

J
Jiri Denemark 已提交
1549 1550
    state = virDomainObjGetState(privdom, NULL);
    if (state == VIR_DOMAIN_SHUTOFF || state == VIR_DOMAIN_PAUSED) {
1551 1552
        virReportError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not running"),
                       domain->name);
1553
        goto cleanup;
1554
    }
1555

J
Jiri Denemark 已提交
1556
    virDomainObjSetState(privdom, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
1557 1558 1559
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_SUSPENDED,
                                     VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
1560 1561 1562
    ret = 0;

cleanup:
1563
    if (privdom)
1564
        virObjectUnlock(privdom);
1565 1566 1567 1568 1569 1570

    if (event) {
        testDriverLock(privconn);
        testDomainEventQueue(privconn, event);
        testDriverUnlock(privconn);
    }
1571
    return ret;
1572 1573
}

1574 1575
static int testShutdownDomainFlags(virDomainPtr domain,
                                   unsigned int flags)
1576
{
1577 1578
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1579
    virDomainEventPtr event = NULL;
1580
    int ret = -1;
1581

1582 1583
    virCheckFlags(0, -1);

1584
    testDriverLock(privconn);
1585 1586
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1587 1588

    if (privdom == NULL) {
1589
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1590
        goto cleanup;
1591
    }
1592

J
Jiri Denemark 已提交
1593
    if (virDomainObjGetState(privdom, NULL) == VIR_DOMAIN_SHUTOFF) {
1594 1595
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("domain '%s' not running"), domain->name);
1596
        goto cleanup;
1597
    }
1598

J
Jiri Denemark 已提交
1599
    testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
1600 1601 1602
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_STOPPED,
                                     VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
1603

1604
    if (!privdom->persistent) {
1605 1606
        virDomainObjListRemove(privconn->domains,
                               privdom);
1607 1608
        privdom = NULL;
    }
1609

1610
    ret = 0;
1611
cleanup:
1612
    if (privdom)
1613
        virObjectUnlock(privdom);
1614 1615
    if (event)
        testDomainEventQueue(privconn, event);
1616
    testDriverUnlock(privconn);
1617
    return ret;
1618 1619
}

1620
static int testShutdownDomain(virDomainPtr domain)
1621 1622 1623 1624
{
    return testShutdownDomainFlags(domain, 0);
}

1625
/* Similar behaviour as shutdown */
1626 1627
static int testRebootDomain(virDomainPtr domain,
                            unsigned int action ATTRIBUTE_UNUSED)
1628
{
1629 1630
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
1631
    virDomainEventPtr event = NULL;
1632
    int ret = -1;
1633

1634
    testDriverLock(privconn);
1635 1636
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1637 1638

    if (privdom == NULL) {
1639
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1640
        goto cleanup;
1641
    }
1642

J
Jiri Denemark 已提交
1643 1644 1645
    virDomainObjSetState(privdom, VIR_DOMAIN_SHUTDOWN,
                         VIR_DOMAIN_SHUTDOWN_USER);

1646 1647
    switch (privdom->def->onReboot) {
    case VIR_DOMAIN_LIFECYCLE_DESTROY:
J
Jiri Denemark 已提交
1648 1649
        virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF,
                             VIR_DOMAIN_SHUTOFF_SHUTDOWN);
1650 1651
        break;

1652
    case VIR_DOMAIN_LIFECYCLE_RESTART:
J
Jiri Denemark 已提交
1653 1654
        virDomainObjSetState(privdom, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_BOOTED);
1655 1656
        break;

1657
    case VIR_DOMAIN_LIFECYCLE_PRESERVE:
J
Jiri Denemark 已提交
1658 1659
        virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF,
                             VIR_DOMAIN_SHUTOFF_SHUTDOWN);
1660 1661
        break;

1662
    case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME:
J
Jiri Denemark 已提交
1663 1664
        virDomainObjSetState(privdom, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_BOOTED);
1665
        break;
1666

1667
    default:
J
Jiri Denemark 已提交
1668 1669
        virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF,
                             VIR_DOMAIN_SHUTOFF_SHUTDOWN);
1670 1671
        break;
    }
1672

J
Jiri Denemark 已提交
1673 1674
    if (virDomainObjGetState(privdom, NULL) == VIR_DOMAIN_SHUTOFF) {
        testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
1675 1676 1677
        event = virDomainEventNewFromObj(privdom,
                                         VIR_DOMAIN_EVENT_STOPPED,
                                         VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
1678

1679
        if (!privdom->persistent) {
1680 1681
            virDomainObjListRemove(privconn->domains,
                                   privdom);
1682 1683
            privdom = NULL;
        }
1684 1685
    }

1686 1687
    ret = 0;
cleanup:
1688
    if (privdom)
1689
        virObjectUnlock(privdom);
1690 1691
    if (event)
        testDomainEventQueue(privconn, event);
1692
    testDriverUnlock(privconn);
1693
    return ret;
1694 1695
}

1696 1697
static int testGetDomainInfo(virDomainPtr domain,
                             virDomainInfoPtr info)
1698
{
1699
    testConnPtr privconn = domain->conn->privateData;
1700
    struct timeval tv;
1701
    virDomainObjPtr privdom;
1702
    int ret = -1;
1703

1704
    testDriverLock(privconn);
1705 1706
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1707
    testDriverUnlock(privconn);
1708 1709

    if (privdom == NULL) {
1710
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1711
        goto cleanup;
1712
    }
1713 1714

    if (gettimeofday(&tv, NULL) < 0) {
1715 1716
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("getting time of day"));
1717
        goto cleanup;
1718 1719
    }

J
Jiri Denemark 已提交
1720
    info->state = virDomainObjGetState(privdom, NULL);
1721 1722
    info->memory = privdom->def->mem.cur_balloon;
    info->maxMem = privdom->def->mem.max_balloon;
1723 1724
    info->nrVirtCpu = privdom->def->vcpus;
    info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll  * 1000ll) + (tv.tv_usec * 1000ll));
1725 1726 1727
    ret = 0;

cleanup:
1728
    if (privdom)
1729
        virObjectUnlock(privdom);
1730
    return ret;
1731 1732
}

1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745
static int
testDomainGetState(virDomainPtr domain,
                   int *state,
                   int *reason,
                   unsigned int flags)
{
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
    int ret = -1;

    virCheckFlags(0, -1);

    testDriverLock(privconn);
1746 1747
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1748 1749 1750
    testDriverUnlock(privconn);

    if (privdom == NULL) {
1751
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1752 1753 1754
        goto cleanup;
    }

J
Jiri Denemark 已提交
1755
    *state = virDomainObjGetState(privdom, reason);
1756 1757 1758 1759
    ret = 0;

cleanup:
    if (privdom)
1760
        virObjectUnlock(privdom);
1761 1762 1763
    return ret;
}

1764 1765
#define TEST_SAVE_MAGIC "TestGuestMagic"

1766 1767 1768
static int
testDomainSaveFlags(virDomainPtr domain, const char *path,
                    const char *dxml, unsigned int flags)
1769
{
1770
    testConnPtr privconn = domain->conn->privateData;
1771 1772 1773
    char *xml = NULL;
    int fd = -1;
    int len;
1774
    virDomainObjPtr privdom;
1775
    virDomainEventPtr event = NULL;
1776
    int ret = -1;
1777

1778 1779
    virCheckFlags(0, -1);
    if (dxml) {
1780 1781
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("xml modification unsupported"));
1782 1783 1784
        return -1;
    }

1785
    testDriverLock(privconn);
1786 1787
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1788 1789

    if (privdom == NULL) {
1790
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
1791
        goto cleanup;
1792
    }
1793

1794
    xml = virDomainDefFormat(privdom->def,
C
Cole Robinson 已提交
1795 1796
                             VIR_DOMAIN_XML_SECURE);

1797
    if (xml == NULL) {
1798
        virReportSystemError(errno,
1799 1800
                             _("saving domain '%s' failed to allocate space for metadata"),
                             domain->name);
1801
        goto cleanup;
1802
    }
1803 1804

    if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
1805
        virReportSystemError(errno,
1806 1807
                             _("saving domain '%s' to '%s': open failed"),
                             domain->name, path);
1808
        goto cleanup;
1809
    }
1810
    len = strlen(xml);
1811
    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
1812
        virReportSystemError(errno,
1813 1814
                             _("saving domain '%s' to '%s': write failed"),
                             domain->name, path);
1815
        goto cleanup;
1816
    }
1817
    if (safewrite(fd, (char*)&len, sizeof(len)) < 0) {
1818
        virReportSystemError(errno,
1819 1820
                             _("saving domain '%s' to '%s': write failed"),
                             domain->name, path);
1821
        goto cleanup;
1822
    }
1823
    if (safewrite(fd, xml, len) < 0) {
1824
        virReportSystemError(errno,
1825 1826
                             _("saving domain '%s' to '%s': write failed"),
                             domain->name, path);
1827
        goto cleanup;
1828
    }
1829

1830
    if (VIR_CLOSE(fd) < 0) {
1831
        virReportSystemError(errno,
1832 1833
                             _("saving domain '%s' to '%s': write failed"),
                             domain->name, path);
1834
        goto cleanup;
1835
    }
1836 1837
    fd = -1;

J
Jiri Denemark 已提交
1838
    testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SAVED);
1839 1840 1841
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_STOPPED,
                                     VIR_DOMAIN_EVENT_STOPPED_SAVED);
1842

1843
    if (!privdom->persistent) {
1844 1845
        virDomainObjListRemove(privconn->domains,
                               privdom);
1846
        privdom = NULL;
1847
    }
1848

1849
    ret = 0;
1850 1851 1852 1853 1854 1855 1856
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) {
1857
        VIR_FORCE_CLOSE(fd);
1858 1859
        unlink(path);
    }
1860
    if (privdom)
1861
        virObjectUnlock(privdom);
1862 1863
    if (event)
        testDomainEventQueue(privconn, event);
1864
    testDriverUnlock(privconn);
1865
    return ret;
1866 1867
}

1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879
static int
testDomainSave(virDomainPtr domain,
               const char *path)
{
    return testDomainSaveFlags(domain, path, NULL, 0);
}

static int
testDomainRestoreFlags(virConnectPtr conn,
                       const char *path,
                       const char *dxml,
                       unsigned int flags)
1880
{
1881
    testConnPtr privconn = conn->privateData;
1882
    char *xml = NULL;
1883
    char magic[15];
1884 1885 1886
    int fd = -1;
    int len;
    virDomainDefPtr def = NULL;
1887
    virDomainObjPtr dom = NULL;
1888
    virDomainEventPtr event = NULL;
1889
    int ret = -1;
1890

1891 1892
    virCheckFlags(0, -1);
    if (dxml) {
1893 1894
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("xml modification unsupported"));
1895 1896 1897
        return -1;
    }

1898 1899
    testDriverLock(privconn);

1900
    if ((fd = open(path, O_RDONLY)) < 0) {
1901
        virReportSystemError(errno,
1902 1903
                             _("cannot read domain image '%s'"),
                             path);
1904
        goto cleanup;
1905
    }
1906
    if (saferead(fd, magic, sizeof(magic)) != sizeof(magic)) {
1907
        virReportSystemError(errno,
1908 1909
                             _("incomplete save header in '%s'"),
                             path);
1910
        goto cleanup;
1911
    }
1912
    if (memcmp(magic, TEST_SAVE_MAGIC, sizeof(magic))) {
1913 1914
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("mismatched header magic"));
1915
        goto cleanup;
1916
    }
1917
    if (saferead(fd, (char*)&len, sizeof(len)) != sizeof(len)) {
1918
        virReportSystemError(errno,
1919 1920
                             _("failed to read metadata length in '%s'"),
                             path);
1921
        goto cleanup;
1922 1923
    }
    if (len < 1 || len > 8192) {
1924 1925
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("length of metadata out of range"));
1926
        goto cleanup;
1927
    }
1928
    if (VIR_ALLOC_N(xml, len+1) < 0) {
1929
        virReportOOMError();
1930
        goto cleanup;
1931
    }
1932
    if (saferead(fd, xml, len) != len) {
1933
        virReportSystemError(errno,
1934
                             _("incomplete metdata in '%s'"), path);
1935
        goto cleanup;
1936 1937
    }
    xml[len] = '\0';
1938

1939
    def = virDomainDefParseString(privconn->caps, xml,
M
Matthias Bolte 已提交
1940
                                  1 << VIR_DOMAIN_VIRT_TEST,
1941
                                  VIR_DOMAIN_XML_INACTIVE);
1942
    if (!def)
1943
        goto cleanup;
1944

1945
    if (testDomainGenerateIfnames(def) < 0)
1946
        goto cleanup;
1947 1948
    if (!(dom = virDomainObjListAdd(privconn->domains,
                                    privconn->caps,
1949 1950 1951 1952
                                    def,
                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
                                    NULL)))
1953 1954
        goto cleanup;
    def = NULL;
1955

J
Jiri Denemark 已提交
1956
    if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_RESTORED) < 0)
1957 1958
        goto cleanup;

1959 1960 1961
    event = virDomainEventNewFromObj(dom,
                                     VIR_DOMAIN_EVENT_STARTED,
                                     VIR_DOMAIN_EVENT_STARTED_RESTORED);
1962
    ret = 0;
1963 1964 1965 1966

cleanup:
    virDomainDefFree(def);
    VIR_FREE(xml);
1967
    VIR_FORCE_CLOSE(fd);
1968
    if (dom)
1969
        virObjectUnlock(dom);
1970 1971
    if (event)
        testDomainEventQueue(privconn, event);
1972
    testDriverUnlock(privconn);
1973
    return ret;
1974 1975
}

1976 1977 1978 1979 1980 1981 1982
static int
testDomainRestore(virConnectPtr conn,
                  const char *path)
{
    return testDomainRestoreFlags(conn, path, NULL, 0);
}

1983 1984
static int testDomainCoreDump(virDomainPtr domain,
                              const char *to,
E
Eric Blake 已提交
1985
                              unsigned int flags)
1986
{
1987
    testConnPtr privconn = domain->conn->privateData;
1988
    int fd = -1;
1989
    virDomainObjPtr privdom;
1990
    virDomainEventPtr event = NULL;
1991
    int ret = -1;
1992

E
Eric Blake 已提交
1993 1994
    virCheckFlags(VIR_DUMP_CRASH, -1);

1995
    testDriverLock(privconn);
1996 1997
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
1998 1999

    if (privdom == NULL) {
2000
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2001
        goto cleanup;
2002
    }
2003 2004

    if ((fd = open(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
2005
        virReportSystemError(errno,
2006 2007
                             _("domain '%s' coredump: failed to open %s"),
                             domain->name, to);
2008
        goto cleanup;
2009
    }
2010
    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
2011
        virReportSystemError(errno,
2012 2013
                             _("domain '%s' coredump: failed to write header to %s"),
                             domain->name, to);
2014
        goto cleanup;
2015
    }
2016
    if (VIR_CLOSE(fd) < 0) {
2017
        virReportSystemError(errno,
2018 2019
                             _("domain '%s' coredump: write failed: %s"),
                             domain->name, to);
2020
        goto cleanup;
2021
    }
2022

2023
    if (flags & VIR_DUMP_CRASH) {
J
Jiri Denemark 已提交
2024
        testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_CRASHED);
2025 2026 2027 2028
        event = virDomainEventNewFromObj(privdom,
                                         VIR_DOMAIN_EVENT_STOPPED,
                                         VIR_DOMAIN_EVENT_STOPPED_CRASHED);
        if (!privdom->persistent) {
2029 2030
            virDomainObjListRemove(privconn->domains,
                                   privdom);
2031 2032
            privdom = NULL;
        }
2033
    }
2034

2035
    ret = 0;
2036
cleanup:
2037
    VIR_FORCE_CLOSE(fd);
2038
    if (privdom)
2039
        virObjectUnlock(privdom);
2040 2041
    if (event)
        testDomainEventQueue(privconn, event);
2042
    testDriverUnlock(privconn);
2043
    return ret;
2044 2045
}

2046
static char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
2047 2048
    char *ret = strdup("linux");
    if (!ret)
2049
        virReportOOMError();
2050
    return ret;
2051 2052
}

2053
static unsigned long long testGetMaxMemory(virDomainPtr domain) {
2054 2055
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2056
    unsigned long long ret = 0;
2057

2058
    testDriverLock(privconn);
2059 2060
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2061
    testDriverUnlock(privconn);
2062 2063

    if (privdom == NULL) {
2064
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2065
        goto cleanup;
2066
    }
2067

2068
    ret = privdom->def->mem.max_balloon;
2069 2070

cleanup:
2071
    if (privdom)
2072
        virObjectUnlock(privdom);
2073
    return ret;
2074 2075 2076 2077 2078
}

static int testSetMaxMemory(virDomainPtr domain,
                            unsigned long memory)
{
2079 2080
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2081
    int ret = -1;
2082

2083
    testDriverLock(privconn);
2084 2085
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2086
    testDriverUnlock(privconn);
2087 2088

    if (privdom == NULL) {
2089
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2090
        goto cleanup;
2091
    }
2092 2093

    /* XXX validate not over host memory wrt to other domains */
2094
    privdom->def->mem.max_balloon = memory;
2095 2096 2097
    ret = 0;

cleanup:
2098
    if (privdom)
2099
        virObjectUnlock(privdom);
2100
    return ret;
2101 2102
}

2103 2104 2105
static int testSetMemory(virDomainPtr domain,
                         unsigned long memory)
{
2106 2107
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2108
    int ret = -1;
2109

2110
    testDriverLock(privconn);
2111 2112
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2113
    testDriverUnlock(privconn);
2114 2115

    if (privdom == NULL) {
2116
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2117
        goto cleanup;
2118
    }
2119

2120
    if (memory > privdom->def->mem.max_balloon) {
2121
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2122
        goto cleanup;
2123
    }
2124

2125
    privdom->def->mem.cur_balloon = memory;
2126 2127 2128
    ret = 0;

cleanup:
2129
    if (privdom)
2130
        virObjectUnlock(privdom);
2131
    return ret;
2132 2133
}

2134 2135
static int
testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
C
Cole Robinson 已提交
2136
{
2137 2138 2139 2140 2141
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr vm;
    virDomainDefPtr def;
    int ret = -1;

2142 2143
    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                  VIR_DOMAIN_AFFECT_CONFIG |
2144 2145 2146
                  VIR_DOMAIN_VCPU_MAXIMUM, -1);

    testDriverLock(privconn);
2147
    vm = virDomainObjListFindByUUID(privconn->domains, domain->uuid);
2148 2149 2150 2151 2152
    testDriverUnlock(privconn);

    if (!vm) {
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(domain->uuid, uuidstr);
2153 2154
        virReportError(VIR_ERR_NO_DOMAIN,
                       _("no domain with matching uuid '%s'"), uuidstr);
2155 2156 2157
        goto cleanup;
    }

2158 2159
    if (virDomainLiveConfigHelperMethod(privconn->caps, vm, &flags, &def) < 0)
        goto cleanup;
2160

2161
    if (flags & VIR_DOMAIN_AFFECT_LIVE)
2162 2163 2164 2165 2166 2167
        def = vm->def;

    ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;

cleanup:
    if (vm)
2168
        virObjectUnlock(vm);
2169
    return ret;
C
Cole Robinson 已提交
2170 2171
}

2172 2173 2174
static int
testDomainGetMaxVcpus(virDomainPtr domain)
{
2175
    return testDomainGetVcpusFlags(domain, (VIR_DOMAIN_AFFECT_LIVE |
2176 2177 2178 2179 2180 2181 2182
                                            VIR_DOMAIN_VCPU_MAXIMUM));
}

static int
testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
                        unsigned int flags)
{
2183
    testConnPtr privconn = domain->conn->privateData;
2184
    virDomainObjPtr privdom = NULL;
2185
    virDomainDefPtr persistentDef;
C
Cole Robinson 已提交
2186 2187
    int ret = -1, maxvcpus;

2188 2189
    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                  VIR_DOMAIN_AFFECT_CONFIG |
2190 2191 2192 2193
                  VIR_DOMAIN_VCPU_MAXIMUM, -1);

    /* At least one of LIVE or CONFIG must be set.  MAXIMUM cannot be
     * mixed with LIVE.  */
2194 2195 2196
    if ((flags & (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG)) == 0 ||
        (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_AFFECT_LIVE)) ==
         (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_AFFECT_LIVE)) {
2197 2198
        virReportError(VIR_ERR_INVALID_ARG,
                       _("invalid flag combination: (0x%x)"), flags);
2199 2200 2201
        return -1;
    }
    if (!nrCpus || (maxvcpus = testGetMaxVCPUs(domain->conn, NULL)) < nrCpus) {
2202 2203
        virReportError(VIR_ERR_INVALID_ARG,
                       _("argument out of range: %d"), nrCpus);
2204 2205
        return -1;
    }
2206

2207
    testDriverLock(privconn);
2208
    privdom = virDomainObjListFindByUUID(privconn->domains, domain->uuid);
2209 2210 2211
    testDriverUnlock(privconn);

    if (privdom == NULL) {
2212
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2213
        goto cleanup;
2214
    }
2215

2216
    if (!virDomainObjIsActive(privdom) && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
2217 2218
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("cannot hotplug vcpus for an inactive domain"));
C
Cole Robinson 已提交
2219 2220 2221
        goto cleanup;
    }

2222 2223
    /* We allow more cpus in guest than host, but not more than the
     * domain's starting limit.  */
C
Cole Robinson 已提交
2224 2225
    if (!(flags & (VIR_DOMAIN_VCPU_MAXIMUM)) &&
        privdom->def->maxvcpus < maxvcpus)
2226
        maxvcpus = privdom->def->maxvcpus;
C
Cole Robinson 已提交
2227

C
Cole Robinson 已提交
2228
    if (nrCpus > maxvcpus) {
2229 2230 2231
        virReportError(VIR_ERR_INVALID_ARG,
                       _("requested cpu amount exceeds maximum (%d > %d)"),
                       nrCpus, maxvcpus);
2232
        goto cleanup;
2233
    }
2234

2235 2236 2237 2238
    if (!(persistentDef = virDomainObjGetPersistentDef(privconn->caps,
                                                       privdom)))
        goto cleanup;

2239
    switch (flags) {
2240
    case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_AFFECT_CONFIG:
2241 2242 2243
        persistentDef->maxvcpus = nrCpus;
        if (nrCpus < persistentDef->vcpus)
            persistentDef->vcpus = nrCpus;
2244 2245
        ret = 0;
        break;
2246

2247
    case VIR_DOMAIN_AFFECT_CONFIG:
2248
        persistentDef->vcpus = nrCpus;
2249 2250 2251
        ret = 0;
        break;

2252
    case VIR_DOMAIN_AFFECT_LIVE:
2253 2254 2255
        ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
        break;

2256
    case VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG:
2257
        ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
2258 2259 2260
        if (ret == 0) {
            persistentDef->vcpus = nrCpus;
        }
2261 2262
        break;
    }
2263 2264

cleanup:
2265
    if (privdom)
2266
        virObjectUnlock(privdom);
2267
    return ret;
2268 2269
}

2270 2271 2272
static int
testSetVcpus(virDomainPtr domain, unsigned int nrCpus)
{
2273
    return testDomainSetVcpusFlags(domain, nrCpus, VIR_DOMAIN_AFFECT_LIVE);
2274 2275
}

C
Cole Robinson 已提交
2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290
static int testDomainGetVcpus(virDomainPtr domain,
                              virVcpuInfoPtr info,
                              int maxinfo,
                              unsigned char *cpumaps,
                              int maplen)
{
    testConnPtr privconn = domain->conn->privateData;
    testDomainObjPrivatePtr privdomdata;
    virDomainObjPtr privdom;
    int i, v, maxcpu, hostcpus;
    int ret = -1;
    struct timeval tv;
    unsigned long long statbase;

    testDriverLock(privconn);
2291
    privdom = virDomainObjListFindByName(privconn->domains, domain->name);
C
Cole Robinson 已提交
2292 2293 2294
    testDriverUnlock(privconn);

    if (privdom == NULL) {
2295
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
C
Cole Robinson 已提交
2296 2297 2298 2299
        goto cleanup;
    }

    if (!virDomainObjIsActive(privdom)) {
2300 2301
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s",_("cannot list vcpus for an inactive domain"));
C
Cole Robinson 已提交
2302 2303 2304 2305 2306 2307
        goto cleanup;
    }

    privdomdata = privdom->privateData;

    if (gettimeofday(&tv, NULL) < 0) {
2308
        virReportSystemError(errno,
C
Cole Robinson 已提交
2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359
                             "%s", _("getting time of day"));
        goto cleanup;
    }

    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;


    hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo);
    maxcpu = maplen * 8;
    if (maxcpu > hostcpus)
        maxcpu = hostcpus;

    /* Clamp to actual number of vcpus */
    if (maxinfo > privdom->def->vcpus)
        maxinfo = privdom->def->vcpus;

    /* Populate virVcpuInfo structures */
    if (info != NULL) {
        memset(info, 0, sizeof(*info) * maxinfo);

        for (i = 0 ; i < maxinfo ; i++) {
            virVcpuInfo privinfo = privdomdata->vcpu_infos[i];

            info[i].number = privinfo.number;
            info[i].state = privinfo.state;
            info[i].cpu = privinfo.cpu;

            /* Fake an increasing cpu time value */
            info[i].cpuTime = statbase / 10;
        }
    }

    /* Populate cpumaps */
    if (cpumaps != NULL) {
        int privmaplen = VIR_CPU_MAPLEN(hostcpus);
        memset(cpumaps, 0, maplen * maxinfo);

        for (v = 0 ; v < maxinfo ; v++) {
            unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);

            for (i = 0 ; i < maxcpu ; i++) {
                if (VIR_CPU_USABLE(privdomdata->cpumaps, privmaplen, v, i)) {
                    VIR_USE_CPU(cpumap, i);
                }
            }
        }
    }

    ret = maxinfo;
cleanup:
    if (privdom)
2360
        virObjectUnlock(privdom);
C
Cole Robinson 已提交
2361 2362 2363
    return ret;
}

C
Cole Robinson 已提交
2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
static int testDomainPinVcpu(virDomainPtr domain,
                             unsigned int vcpu,
                             unsigned char *cpumap,
                             int maplen)
{
    testConnPtr privconn = domain->conn->privateData;
    testDomainObjPrivatePtr privdomdata;
    virDomainObjPtr privdom;
    unsigned char *privcpumap;
    int i, maxcpu, hostcpus, privmaplen;
    int ret = -1;

    testDriverLock(privconn);
2377
    privdom = virDomainObjListFindByName(privconn->domains, domain->name);
C
Cole Robinson 已提交
2378 2379 2380
    testDriverUnlock(privconn);

    if (privdom == NULL) {
2381
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
C
Cole Robinson 已提交
2382 2383 2384 2385
        goto cleanup;
    }

    if (!virDomainObjIsActive(privdom)) {
2386 2387
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s",_("cannot pin vcpus on an inactive domain"));
C
Cole Robinson 已提交
2388 2389 2390 2391
        goto cleanup;
    }

    if (vcpu > privdom->def->vcpus) {
2392 2393
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("requested vcpu is higher than allocated vcpus"));
C
Cole Robinson 已提交
2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416
        goto cleanup;
    }

    privdomdata = privdom->privateData;
    hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo);
    privmaplen = VIR_CPU_MAPLEN(hostcpus);

    maxcpu = maplen * 8;
    if (maxcpu > hostcpus)
        maxcpu = hostcpus;

    privcpumap = VIR_GET_CPUMAP(privdomdata->cpumaps, privmaplen, vcpu);
    memset(privcpumap, 0, privmaplen);

    for (i = 0 ; i < maxcpu ; i++) {
        if (VIR_CPU_USABLE(cpumap, maplen, 0, i)) {
            VIR_USE_CPU(privcpumap, i);
        }
    }

    ret = 0;
cleanup:
    if (privdom)
2417
        virObjectUnlock(privdom);
C
Cole Robinson 已提交
2418 2419 2420
    return ret;
}

2421
static char *testDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
2422
{
2423
    testConnPtr privconn = domain->conn->privateData;
2424
    virDomainDefPtr def;
2425
    virDomainObjPtr privdom;
2426 2427
    char *ret = NULL;

2428 2429
    /* Flags checked by virDomainDefFormat */

2430
    testDriverLock(privconn);
2431 2432
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2433 2434 2435
    testDriverUnlock(privconn);

    if (privdom == NULL) {
2436
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2437
        goto cleanup;
2438
    }
2439

2440 2441
    def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
        privdom->newDef ? privdom->newDef : privdom->def;
2442

2443
    ret = virDomainDefFormat(def,
2444 2445 2446
                             flags);

cleanup:
2447
    if (privdom)
2448
        virObjectUnlock(privdom);
2449
    return ret;
2450
}
2451

2452
static int testNumOfDefinedDomains(virConnectPtr conn) {
2453
    testConnPtr privconn = conn->privateData;
2454
    int count;
2455

2456
    testDriverLock(privconn);
2457
    count = virDomainObjListNumOfDomains(privconn->domains, 0);
2458
    testDriverUnlock(privconn);
2459

2460
    return count;
2461 2462
}

2463 2464 2465
static int testListDefinedDomains(virConnectPtr conn,
                                  char **const names,
                                  int maxnames) {
2466

2467
    testConnPtr privconn = conn->privateData;
2468
    int n;
2469

2470
    testDriverLock(privconn);
2471
    memset(names, 0, sizeof(*names)*maxnames);
2472
    n = virDomainObjListGetInactiveNames(privconn->domains, names, maxnames);
2473
    testDriverUnlock(privconn);
2474

2475
    return n;
2476 2477
}

2478
static virDomainPtr testDomainDefineXML(virConnectPtr conn,
2479
                                        const char *xml) {
2480
    testConnPtr privconn = conn->privateData;
2481
    virDomainPtr ret = NULL;
2482
    virDomainDefPtr def;
2483
    virDomainObjPtr dom = NULL;
2484
    virDomainEventPtr event = NULL;
2485
    virDomainDefPtr oldDef = NULL;
2486

2487
    testDriverLock(privconn);
2488
    if ((def = virDomainDefParseString(privconn->caps, xml,
M
Matthias Bolte 已提交
2489
                                       1 << VIR_DOMAIN_VIRT_TEST,
2490
                                       VIR_DOMAIN_XML_INACTIVE)) == NULL)
2491
        goto cleanup;
2492

2493
    if (testDomainGenerateIfnames(def) < 0)
2494
        goto cleanup;
2495 2496
    if (!(dom = virDomainObjListAdd(privconn->domains,
                                    privconn->caps,
2497 2498 2499
                                    def,
                                    0,
                                    &oldDef)))
2500
        goto cleanup;
2501
    def = NULL;
2502
    dom->persistent = 1;
2503

2504 2505
    event = virDomainEventNewFromObj(dom,
                                     VIR_DOMAIN_EVENT_DEFINED,
2506
                                     !oldDef ?
2507 2508
                                     VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                     VIR_DOMAIN_EVENT_DEFINED_UPDATED);
2509

2510
    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
2511
    if (ret)
2512
        ret->id = dom->def->id;
2513 2514 2515

cleanup:
    virDomainDefFree(def);
2516
    virDomainDefFree(oldDef);
2517
    if (dom)
2518
        virObjectUnlock(dom);
2519 2520
    if (event)
        testDomainEventQueue(privconn, event);
2521
    testDriverUnlock(privconn);
2522
    return ret;
2523 2524
}

2525 2526 2527
static int testNodeGetCellsFreeMemory(virConnectPtr conn,
                                      unsigned long long *freemems,
                                      int startCell, int maxCells) {
2528
    testConnPtr privconn = conn->privateData;
2529
    int i, j;
2530
    int ret = -1;
2531

2532
    testDriverLock(privconn);
2533
    if (startCell > privconn->numCells) {
2534 2535
        virReportError(VIR_ERR_INVALID_ARG,
                       "%s", _("Range exceeds available cells"));
2536
        goto cleanup;
2537 2538 2539 2540 2541 2542 2543
    }

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

2546
cleanup:
2547
    testDriverUnlock(privconn);
2548
    return ret;
2549 2550 2551
}


2552
static int testDomainCreateWithFlags(virDomainPtr domain, unsigned int flags) {
2553 2554
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2555
    virDomainEventPtr event = NULL;
2556
    int ret = -1;
2557

2558 2559
    virCheckFlags(0, -1);

2560
    testDriverLock(privconn);
2561 2562
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2563 2564

    if (privdom == NULL) {
2565
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2566
        goto cleanup;
2567
    }
2568

J
Jiri Denemark 已提交
2569
    if (virDomainObjGetState(privdom, NULL) != VIR_DOMAIN_SHUTOFF) {
2570 2571
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Domain '%s' is already running"), domain->name);
2572
        goto cleanup;
2573 2574
    }

J
Jiri Denemark 已提交
2575 2576
    if (testDomainStartState(domain->conn, privdom,
                             VIR_DOMAIN_RUNNING_BOOTED) < 0)
2577 2578 2579
        goto cleanup;
    domain->id = privdom->def->id;

2580 2581 2582
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_STARTED,
                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);
2583
    ret = 0;
2584

2585
cleanup:
2586
    if (privdom)
2587
        virObjectUnlock(privdom);
2588 2589
    if (event)
        testDomainEventQueue(privconn, event);
2590
    testDriverUnlock(privconn);
2591
    return ret;
2592 2593
}

2594 2595 2596 2597
static int testDomainCreate(virDomainPtr domain) {
    return testDomainCreateWithFlags(domain, 0);
}

2598 2599 2600
static int testDomainUndefineFlags(virDomainPtr domain,
                                   unsigned int flags)
{
2601 2602
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2603
    virDomainEventPtr event = NULL;
2604
    int ret = -1;
2605

2606 2607
    virCheckFlags(0, -1);

2608
    testDriverLock(privconn);
2609 2610
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2611 2612

    if (privdom == NULL) {
2613
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2614
        goto cleanup;
2615
    }
2616

2617 2618 2619
    event = virDomainEventNewFromObj(privdom,
                                     VIR_DOMAIN_EVENT_UNDEFINED,
                                     VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
2620 2621
    if (virDomainObjIsActive(privdom)) {
        privdom->persistent = 0;
2622
    } else {
2623 2624
        virDomainObjListRemove(privconn->domains,
                               privdom);
2625 2626 2627
        privdom = NULL;
    }

2628
    ret = 0;
2629

2630
cleanup:
2631
    if (privdom)
2632
        virObjectUnlock(privdom);
2633 2634
    if (event)
        testDomainEventQueue(privconn, event);
2635
    testDriverUnlock(privconn);
2636
    return ret;
2637 2638
}

2639 2640 2641 2642 2643
static int testDomainUndefine(virDomainPtr domain)
{
    return testDomainUndefineFlags(domain, 0);
}

2644 2645 2646
static int testDomainGetAutostart(virDomainPtr domain,
                                  int *autostart)
{
2647 2648
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2649
    int ret = -1;
2650

2651
    testDriverLock(privconn);
2652 2653
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2654
    testDriverUnlock(privconn);
2655 2656

    if (privdom == NULL) {
2657
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2658
        goto cleanup;
2659 2660
    }

2661
    *autostart = privdom->autostart;
2662 2663 2664
    ret = 0;

cleanup:
2665
    if (privdom)
2666
        virObjectUnlock(privdom);
2667
    return ret;
2668 2669 2670 2671 2672 2673
}


static int testDomainSetAutostart(virDomainPtr domain,
                                  int autostart)
{
2674 2675
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2676
    int ret = -1;
2677

2678
    testDriverLock(privconn);
2679 2680
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2681
    testDriverUnlock(privconn);
2682 2683

    if (privdom == NULL) {
2684
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2685
        goto cleanup;
2686 2687
    }

2688
    privdom->autostart = autostart ? 1 : 0;
2689 2690 2691
    ret = 0;

cleanup:
2692
    if (privdom)
2693
        virObjectUnlock(privdom);
2694
    return ret;
2695
}
2696

2697
static char *testDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED,
2698 2699
                                        int *nparams)
{
2700 2701
    char *type = NULL;

2702 2703 2704
    if (nparams)
        *nparams = 1;

2705
    type = strdup("fair");
2706
    if (!type)
2707
        virReportOOMError();
2708

2709 2710 2711
    return type;
}

2712 2713 2714 2715 2716
static int
testDomainGetSchedulerParamsFlags(virDomainPtr domain,
                                  virTypedParameterPtr params,
                                  int *nparams,
                                  unsigned int flags)
2717
{
2718 2719
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2720
    int ret = -1;
2721

2722 2723
    virCheckFlags(0, -1);

2724
    testDriverLock(privconn);
2725 2726
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2727
    testDriverUnlock(privconn);
2728 2729

    if (privdom == NULL) {
2730
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2731
        goto cleanup;
2732 2733
    }

2734 2735
    if (virTypedParameterAssign(params, VIR_DOMAIN_SCHEDULER_WEIGHT,
                                VIR_TYPED_PARAM_UINT, 50) < 0)
2736
        goto cleanup;
2737 2738
    /* XXX */
    /*params[0].value.ui = privdom->weight;*/
2739 2740

    *nparams = 1;
2741 2742 2743
    ret = 0;

cleanup:
2744
    if (privdom)
2745
        virObjectUnlock(privdom);
2746
    return ret;
2747
}
2748

2749 2750 2751 2752 2753 2754 2755
static int
testDomainGetSchedulerParams(virDomainPtr domain,
                             virTypedParameterPtr params,
                             int *nparams)
{
    return testDomainGetSchedulerParamsFlags(domain, params, nparams, 0);
}
2756

2757 2758 2759 2760 2761
static int
testDomainSetSchedulerParamsFlags(virDomainPtr domain,
                                  virTypedParameterPtr params,
                                  int nparams,
                                  unsigned int flags)
2762
{
2763 2764
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
2765
    int ret = -1, i;
2766

2767
    virCheckFlags(0, -1);
2768 2769 2770 2771 2772
    if (virTypedParameterArrayValidate(params, nparams,
                                       VIR_DOMAIN_SCHEDULER_WEIGHT,
                                       VIR_TYPED_PARAM_UINT,
                                       NULL) < 0)
        return -1;
2773

2774
    testDriverLock(privconn);
2775 2776
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2777
    testDriverUnlock(privconn);
2778 2779

    if (privdom == NULL) {
2780
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2781
        goto cleanup;
2782 2783
    }

2784
    for (i = 0; i < nparams; i++) {
2785 2786 2787
        if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
            /* XXX */
            /*privdom->weight = params[i].value.ui;*/
2788
        }
2789
    }
2790

2791 2792 2793
    ret = 0;

cleanup:
2794
    if (privdom)
2795
        virObjectUnlock(privdom);
2796
    return ret;
2797 2798
}

2799 2800 2801 2802 2803 2804 2805 2806
static int
testDomainSetSchedulerParams(virDomainPtr domain,
                             virTypedParameterPtr params,
                             int nparams)
{
    return testDomainSetSchedulerParamsFlags(domain, params, nparams, 0);
}

2807 2808 2809 2810 2811 2812 2813 2814
static int testDomainBlockStats(virDomainPtr domain,
                                const char *path,
                                struct _virDomainBlockStats *stats)
{
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
    struct timeval tv;
    unsigned long long statbase;
2815
    int ret = -1;
2816 2817

    testDriverLock(privconn);
2818 2819
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2820 2821 2822
    testDriverUnlock(privconn);

    if (privdom == NULL) {
2823
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2824 2825 2826
        goto error;
    }

2827
    if (virDomainDiskIndexByName(privdom->def, path, false) < 0) {
2828 2829
        virReportError(VIR_ERR_INVALID_ARG,
                       _("invalid path: %s"), path);
2830 2831 2832 2833
        goto error;
    }

    if (gettimeofday(&tv, NULL) < 0) {
2834
        virReportSystemError(errno,
2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849
                             "%s", _("getting time of day"));
        goto error;
    }

    /* No significance to these numbers, just enough to mix it up*/
    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
    stats->rd_req = statbase / 10;
    stats->rd_bytes = statbase / 20;
    stats->wr_req = statbase / 30;
    stats->wr_bytes = statbase / 40;
    stats->errs = tv.tv_sec / 2;

    ret = 0;
error:
    if (privdom)
2850
        virObjectUnlock(privdom);
2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864
    return ret;
}

static int testDomainInterfaceStats(virDomainPtr domain,
                                    const char *path,
                                    struct _virDomainInterfaceStats *stats)
{
    testConnPtr privconn = domain->conn->privateData;
    virDomainObjPtr privdom;
    struct timeval tv;
    unsigned long long statbase;
    int i, found = 0, ret = -1;

    testDriverLock(privconn);
2865 2866
    privdom = virDomainObjListFindByName(privconn->domains,
                                         domain->name);
2867 2868 2869
    testDriverUnlock(privconn);

    if (privdom == NULL) {
2870
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2871 2872 2873 2874 2875
        goto error;
    }

    for (i = 0 ; i < privdom->def->nnets ; i++) {
        if (privdom->def->nets[i]->ifname &&
2876
            STREQ(privdom->def->nets[i]->ifname, path)) {
2877 2878 2879 2880 2881 2882
            found = 1;
            break;
        }
    }

    if (!found) {
2883 2884
        virReportError(VIR_ERR_INVALID_ARG,
                       _("invalid path, '%s' is not a known interface"), path);
2885 2886 2887 2888
        goto error;
    }

    if (gettimeofday(&tv, NULL) < 0) {
2889
        virReportSystemError(errno,
2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907
                             "%s", _("getting time of day"));
        goto error;
    }

    /* No significance to these numbers, just enough to mix it up*/
    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
    stats->rx_bytes = statbase / 10;
    stats->rx_packets = statbase / 100;
    stats->rx_errs = tv.tv_sec / 1;
    stats->rx_drop = tv.tv_sec / 2;
    stats->tx_bytes = statbase / 20;
    stats->tx_packets = statbase / 110;
    stats->tx_errs = tv.tv_sec / 3;
    stats->tx_drop = tv.tv_sec / 4;

    ret = 0;
error:
    if (privdom)
2908
        virObjectUnlock(privdom);
2909 2910 2911
    return ret;
}

2912
static virDrvOpenStatus testOpenNetwork(virConnectPtr conn,
2913
                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
2914 2915 2916 2917
                                        unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933
    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)
{
2934 2935
    testConnPtr privconn = conn->privateData;
    virNetworkObjPtr net;
2936
    virNetworkPtr ret = NULL;
2937

2938 2939 2940 2941 2942
    testDriverLock(privconn);
    net = virNetworkFindByUUID(&privconn->networks, uuid);
    testDriverUnlock(privconn);

    if (net == NULL) {
2943
        virReportError(VIR_ERR_NO_NETWORK, NULL);
2944
        goto cleanup;
2945 2946
    }

2947 2948 2949
    ret = virGetNetwork(conn, net->def->name, net->def->uuid);

cleanup:
2950 2951
    if (net)
        virNetworkObjUnlock(net);
2952
    return ret;
2953
}
2954

2955
static virNetworkPtr testLookupNetworkByName(virConnectPtr conn,
2956
                                             const char *name)
2957
{
2958
    testConnPtr privconn = conn->privateData;
2959 2960
    virNetworkObjPtr net;
    virNetworkPtr ret = NULL;
2961

2962 2963 2964 2965 2966
    testDriverLock(privconn);
    net = virNetworkFindByName(&privconn->networks, name);
    testDriverUnlock(privconn);

    if (net == NULL) {
2967
        virReportError(VIR_ERR_NO_NETWORK, NULL);
2968
        goto cleanup;
2969 2970
    }

2971 2972 2973
    ret = virGetNetwork(conn, net->def->name, net->def->uuid);

cleanup:
2974 2975
    if (net)
        virNetworkObjUnlock(net);
2976
    return ret;
2977 2978 2979 2980
}


static int testNumNetworks(virConnectPtr conn) {
2981
    testConnPtr privconn = conn->privateData;
2982
    int numActive = 0, i;
2983

2984 2985 2986
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->networks.count ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
D
Daniel P. Berrange 已提交
2987
        if (virNetworkObjIsActive(privconn->networks.objs[i]))
2988
            numActive++;
2989 2990 2991
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
2992

2993
    return numActive;
2994 2995 2996
}

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

3000
    testDriverLock(privconn);
3001
    memset(names, 0, sizeof(*names)*nnames);
3002 3003
    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
D
Daniel P. Berrange 已提交
3004
        if (virNetworkObjIsActive(privconn->networks.objs[i]) &&
3005 3006
            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
            virNetworkObjUnlock(privconn->networks.objs[i]);
3007
            goto no_memory;
3008 3009 3010 3011
        }
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
3012

3013 3014 3015
    return n;

no_memory:
3016
    virReportOOMError();
3017 3018
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
3019
    testDriverUnlock(privconn);
3020
    return -1;
3021 3022 3023
}

static int testNumDefinedNetworks(virConnectPtr conn) {
3024
    testConnPtr privconn = conn->privateData;
3025
    int numInactive = 0, i;
3026

3027 3028 3029
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->networks.count ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
D
Daniel P. Berrange 已提交
3030
        if (!virNetworkObjIsActive(privconn->networks.objs[i]))
3031
            numInactive++;
3032 3033 3034
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
3035

3036
    return numInactive;
3037 3038 3039
}

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

3043
    testDriverLock(privconn);
3044
    memset(names, 0, sizeof(*names)*nnames);
3045 3046
    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
        virNetworkObjLock(privconn->networks.objs[i]);
D
Daniel P. Berrange 已提交
3047
        if (!virNetworkObjIsActive(privconn->networks.objs[i]) &&
3048 3049
            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
            virNetworkObjUnlock(privconn->networks.objs[i]);
3050
            goto no_memory;
3051 3052 3053 3054
        }
        virNetworkObjUnlock(privconn->networks.objs[i]);
    }
    testDriverUnlock(privconn);
3055

3056 3057 3058
    return n;

no_memory:
3059
    virReportOOMError();
3060 3061
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
3062
    testDriverUnlock(privconn);
3063
    return -1;
3064 3065
}

3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081
static int
testNetworkListAllNetworks(virConnectPtr conn,
                           virNetworkPtr **nets,
                           unsigned int flags)
{
    testConnPtr privconn = conn->privateData;
    int ret = -1;

    virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1);

    testDriverLock(privconn);
    ret = virNetworkList(conn, privconn->networks, nets, flags);
    testDriverUnlock(privconn);

    return ret;
}
3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092

static int testNetworkIsActive(virNetworkPtr net)
{
    testConnPtr privconn = net->conn->privateData;
    virNetworkObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
    obj = virNetworkFindByUUID(&privconn->networks, net->uuid);
    testDriverUnlock(privconn);
    if (!obj) {
3093
        virReportError(VIR_ERR_NO_NETWORK, NULL);
3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113
        goto cleanup;
    }
    ret = virNetworkObjIsActive(obj);

cleanup:
    if (obj)
        virNetworkObjUnlock(obj);
    return ret;
}

static int testNetworkIsPersistent(virNetworkPtr net)
{
    testConnPtr privconn = net->conn->privateData;
    virNetworkObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
    obj = virNetworkFindByUUID(&privconn->networks, net->uuid);
    testDriverUnlock(privconn);
    if (!obj) {
3114
        virReportError(VIR_ERR_NO_NETWORK, NULL);
3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125
        goto cleanup;
    }
    ret = obj->persistent;

cleanup:
    if (obj)
        virNetworkObjUnlock(obj);
    return ret;
}


3126
static virNetworkPtr testNetworkCreate(virConnectPtr conn, const char *xml) {
3127
    testConnPtr privconn = conn->privateData;
3128
    virNetworkDefPtr def;
3129
    virNetworkObjPtr net = NULL;
3130
    virNetworkPtr ret = NULL;
3131

3132
    testDriverLock(privconn);
3133
    if ((def = virNetworkDefParseString(xml)) == NULL)
3134
        goto cleanup;
3135

3136
    if (!(net = virNetworkAssignDef(&privconn->networks, def, false)))
3137 3138
        goto cleanup;
    def = NULL;
3139
    net->active = 1;
3140

3141
    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
3142

3143 3144
cleanup:
    virNetworkDefFree(def);
3145 3146 3147
    if (net)
        virNetworkObjUnlock(net);
    testDriverUnlock(privconn);
3148
    return ret;
3149 3150
}

3151 3152 3153
static
virNetworkPtr testNetworkDefine(virConnectPtr conn, const char *xml)
{
3154
    testConnPtr privconn = conn->privateData;
3155
    virNetworkDefPtr def;
3156
    virNetworkObjPtr net = NULL;
3157
    virNetworkPtr ret = NULL;
3158

3159
    testDriverLock(privconn);
3160
    if ((def = virNetworkDefParseString(xml)) == NULL)
3161
        goto cleanup;
3162

3163
    if (!(net = virNetworkAssignDef(&privconn->networks, def, false)))
3164 3165
        goto cleanup;
    def = NULL;
3166
    net->persistent = 1;
3167

3168
    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
3169 3170 3171

cleanup:
    virNetworkDefFree(def);
3172 3173 3174
    if (net)
        virNetworkObjUnlock(net);
    testDriverUnlock(privconn);
3175
    return ret;
3176 3177 3178
}

static int testNetworkUndefine(virNetworkPtr network) {
3179 3180
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
3181
    int ret = -1;
3182

3183
    testDriverLock(privconn);
3184 3185 3186 3187
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);

    if (privnet == NULL) {
3188
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3189
        goto cleanup;
3190
    }
3191

D
Daniel P. Berrange 已提交
3192
    if (virNetworkObjIsActive(privnet)) {
3193 3194
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("Network '%s' is still running"), network->name);
3195
        goto cleanup;
3196 3197
    }

3198 3199
    virNetworkRemoveInactive(&privconn->networks,
                             privnet);
3200
    privnet = NULL;
3201
    ret = 0;
3202

3203
cleanup:
3204 3205 3206
    if (privnet)
        virNetworkObjUnlock(privnet);
    testDriverUnlock(privconn);
3207
    return ret;
3208 3209
}

3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257
static int
testNetworkUpdate(virNetworkPtr net,
                  unsigned int command,
                  unsigned int section,
                  int parentIndex,
                  const char *xml,
                  unsigned int flags)
{
    testConnPtr privconn = net->conn->privateData;
    virNetworkObjPtr network = NULL;
    int isActive, ret = -1;

    virCheckFlags(VIR_NETWORK_UPDATE_AFFECT_LIVE |
                  VIR_NETWORK_UPDATE_AFFECT_CONFIG,
                  -1);

    testDriverLock(privconn);

    network = virNetworkFindByUUID(&privconn->networks, net->uuid);
    if (!network) {
        virReportError(VIR_ERR_NO_NETWORK,
                       "%s", _("no network with matching uuid"));
        goto cleanup;
    }

    /* VIR_NETWORK_UPDATE_AFFECT_CURRENT means "change LIVE if network
     * is active, else change CONFIG
    */
    isActive = virNetworkObjIsActive(network);
    if ((flags & (VIR_NETWORK_UPDATE_AFFECT_LIVE
                   | VIR_NETWORK_UPDATE_AFFECT_CONFIG)) ==
        VIR_NETWORK_UPDATE_AFFECT_CURRENT) {
        if (isActive)
            flags |= VIR_NETWORK_UPDATE_AFFECT_LIVE;
        else
            flags |= VIR_NETWORK_UPDATE_AFFECT_CONFIG;
    }

    /* update the network config in memory/on disk */
    if (virNetworkObjUpdate(network, command, section, parentIndex, xml, flags) < 0)
       goto cleanup;

    ret = 0;
cleanup:
    testDriverUnlock(privconn);
    return ret;
}

3258
static int testNetworkStart(virNetworkPtr network) {
3259 3260
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
3261
    int ret = -1;
3262

3263
    testDriverLock(privconn);
3264 3265
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
3266
    testDriverUnlock(privconn);
3267 3268

    if (privnet == NULL) {
3269
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3270
        goto cleanup;
3271
    }
3272

D
Daniel P. Berrange 已提交
3273
    if (virNetworkObjIsActive(privnet)) {
3274 3275
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("Network '%s' is already running"), network->name);
3276
        goto cleanup;
3277 3278
    }

3279
    privnet->active = 1;
3280
    ret = 0;
3281

3282
cleanup:
3283 3284
    if (privnet)
        virNetworkObjUnlock(privnet);
3285
    return ret;
3286 3287 3288
}

static int testNetworkDestroy(virNetworkPtr network) {
3289 3290
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
3291
    int ret = -1;
3292

3293
    testDriverLock(privconn);
3294 3295 3296 3297
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);

    if (privnet == NULL) {
3298
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3299
        goto cleanup;
3300
    }
3301

3302 3303 3304 3305
    privnet->active = 0;
    if (!privnet->persistent) {
        virNetworkRemoveInactive(&privconn->networks,
                                 privnet);
3306
        privnet = NULL;
3307
    }
3308 3309 3310
    ret = 0;

cleanup:
3311 3312 3313
    if (privnet)
        virNetworkObjUnlock(privnet);
    testDriverUnlock(privconn);
3314
    return ret;
3315 3316
}

3317
static char *testNetworkGetXMLDesc(virNetworkPtr network,
E
Eric Blake 已提交
3318
                                   unsigned int flags)
3319
{
3320 3321
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
3322
    char *ret = NULL;
3323

E
Eric Blake 已提交
3324 3325
    virCheckFlags(0, NULL);

3326
    testDriverLock(privconn);
3327 3328
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
3329
    testDriverUnlock(privconn);
3330 3331

    if (privnet == NULL) {
3332
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3333
        goto cleanup;
3334
    }
3335

3336
    ret = virNetworkDefFormat(privnet->def, flags);
3337 3338

cleanup:
3339 3340
    if (privnet)
        virNetworkObjUnlock(privnet);
3341
    return ret;
3342 3343 3344
}

static char *testNetworkGetBridgeName(virNetworkPtr network) {
3345
    testConnPtr privconn = network->conn->privateData;
3346
    char *bridge = NULL;
3347 3348
    virNetworkObjPtr privnet;

3349
    testDriverLock(privconn);
3350 3351
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
3352
    testDriverUnlock(privconn);
3353 3354

    if (privnet == NULL) {
3355
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3356
        goto cleanup;
3357 3358
    }

3359
    if (!(privnet->def->bridge)) {
3360 3361 3362
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("network '%s' does not have a bridge name."),
                       privnet->def->name);
3363 3364 3365 3366
        goto cleanup;
    }

    if (!(bridge = strdup(privnet->def->bridge))) {
3367
        virReportOOMError();
3368
        goto cleanup;
3369
    }
3370 3371

cleanup:
3372 3373
    if (privnet)
        virNetworkObjUnlock(privnet);
3374 3375 3376 3377 3378
    return bridge;
}

static int testNetworkGetAutostart(virNetworkPtr network,
                                   int *autostart) {
3379 3380
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
3381
    int ret = -1;
3382

3383
    testDriverLock(privconn);
3384 3385
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
3386
    testDriverUnlock(privconn);
3387 3388

    if (privnet == NULL) {
3389
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3390
        goto cleanup;
3391 3392
    }

3393
    *autostart = privnet->autostart;
3394 3395 3396
    ret = 0;

cleanup:
3397 3398
    if (privnet)
        virNetworkObjUnlock(privnet);
3399
    return ret;
3400 3401 3402 3403
}

static int testNetworkSetAutostart(virNetworkPtr network,
                                   int autostart) {
3404 3405
    testConnPtr privconn = network->conn->privateData;
    virNetworkObjPtr privnet;
3406
    int ret = -1;
3407

3408
    testDriverLock(privconn);
3409 3410
    privnet = virNetworkFindByName(&privconn->networks,
                                   network->name);
3411
    testDriverUnlock(privconn);
3412 3413

    if (privnet == NULL) {
3414
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
3415
        goto cleanup;
3416 3417
    }

3418
    privnet->autostart = autostart ? 1 : 0;
3419 3420 3421
    ret = 0;

cleanup:
3422 3423
    if (privnet)
        virNetworkObjUnlock(privnet);
3424
    return ret;
3425
}
3426

C
Cole Robinson 已提交
3427

L
Laine Stump 已提交
3428 3429 3430 3431 3432 3433
/*
 * Physical host interface routines
 */

static virDrvOpenStatus testOpenInterface(virConnectPtr conn,
                                          virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
3434
                                          unsigned int flags)
L
Laine Stump 已提交
3435
{
E
Eric Blake 已提交
3436 3437
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

L
Laine Stump 已提交
3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459
    if (STRNEQ(conn->driver->name, "Test"))
        return VIR_DRV_OPEN_DECLINED;

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

static int testCloseInterface(virConnectPtr conn)
{
    conn->interfacePrivateData = NULL;
    return 0;
}


static int testNumOfInterfaces(virConnectPtr conn)
{
    testConnPtr privconn = conn->privateData;
    int i, count = 0;

    testDriverLock(privconn);
    for (i = 0 ; (i < privconn->ifaces.count); i++) {
        virInterfaceObjLock(privconn->ifaces.objs[i]);
D
Daniel P. Berrange 已提交
3460
        if (virInterfaceObjIsActive(privconn->ifaces.objs[i])) {
L
Laine Stump 已提交
3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477
            count++;
        }
        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
    }
    testDriverUnlock(privconn);
    return count;
}

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

    testDriverLock(privconn);
    memset(names, 0, sizeof(*names)*nnames);
    for (i = 0 ; (i < privconn->ifaces.count) && (n < nnames); i++) {
        virInterfaceObjLock(privconn->ifaces.objs[i]);
D
Daniel P. Berrange 已提交
3478
        if (virInterfaceObjIsActive(privconn->ifaces.objs[i])) {
L
Laine Stump 已提交
3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490
            if (!(names[n++] = strdup(privconn->ifaces.objs[i]->def->name))) {
                virInterfaceObjUnlock(privconn->ifaces.objs[i]);
                goto no_memory;
            }
        }
        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
    }
    testDriverUnlock(privconn);

    return n;

no_memory:
3491
    virReportOOMError();
L
Laine Stump 已提交
3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
    testDriverUnlock(privconn);
    return -1;
}

static int testNumOfDefinedInterfaces(virConnectPtr conn)
{
    testConnPtr privconn = conn->privateData;
    int i, count = 0;

    testDriverLock(privconn);
    for (i = 0 ; i < privconn->ifaces.count; i++) {
        virInterfaceObjLock(privconn->ifaces.objs[i]);
D
Daniel P. Berrange 已提交
3506
        if (!virInterfaceObjIsActive(privconn->ifaces.objs[i])) {
L
Laine Stump 已提交
3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523
            count++;
        }
        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
    }
    testDriverUnlock(privconn);
    return count;
}

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

    testDriverLock(privconn);
    memset(names, 0, sizeof(*names)*nnames);
    for (i = 0 ; (i < privconn->ifaces.count) && (n < nnames); i++) {
        virInterfaceObjLock(privconn->ifaces.objs[i]);
D
Daniel P. Berrange 已提交
3524
        if (!virInterfaceObjIsActive(privconn->ifaces.objs[i])) {
L
Laine Stump 已提交
3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536
            if (!(names[n++] = strdup(privconn->ifaces.objs[i]->def->name))) {
                virInterfaceObjUnlock(privconn->ifaces.objs[i]);
                goto no_memory;
            }
        }
        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
    }
    testDriverUnlock(privconn);

    return n;

no_memory:
3537
    virReportOOMError();
L
Laine Stump 已提交
3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
    testDriverUnlock(privconn);
    return -1;
}

static virInterfacePtr testLookupInterfaceByName(virConnectPtr conn,
                                                 const char *name)
{
    testConnPtr privconn = conn->privateData;
    virInterfaceObjPtr iface;
    virInterfacePtr ret = NULL;

    testDriverLock(privconn);
    iface = virInterfaceFindByName(&privconn->ifaces, name);
    testDriverUnlock(privconn);

    if (iface == NULL) {
3556
        virReportError(VIR_ERR_NO_INTERFACE, NULL);
L
Laine Stump 已提交
3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580
        goto cleanup;
    }

    ret = virGetInterface(conn, iface->def->name, iface->def->mac);

cleanup:
    if (iface)
        virInterfaceObjUnlock(iface);
    return ret;
}

static virInterfacePtr testLookupInterfaceByMACString(virConnectPtr conn,
                                                      const char *mac)
{
    testConnPtr privconn = conn->privateData;
    virInterfaceObjPtr iface;
    int ifacect;
    virInterfacePtr ret = NULL;

    testDriverLock(privconn);
    ifacect = virInterfaceFindByMACString(&privconn->ifaces, mac, &iface, 1);
    testDriverUnlock(privconn);

    if (ifacect == 0) {
3581
        virReportError(VIR_ERR_NO_INTERFACE, NULL);
L
Laine Stump 已提交
3582 3583 3584 3585
        goto cleanup;
    }

    if (ifacect > 1) {
3586
        virReportError(VIR_ERR_MULTIPLE_INTERFACES, NULL);
L
Laine Stump 已提交
3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597
        goto cleanup;
    }

    ret = virGetInterface(conn, iface->def->name, iface->def->mac);

cleanup:
    if (iface)
        virInterfaceObjUnlock(iface);
    return ret;
}

3598 3599 3600 3601 3602 3603 3604 3605 3606 3607
static int testInterfaceIsActive(virInterfacePtr iface)
{
    testConnPtr privconn = iface->conn->privateData;
    virInterfaceObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
    obj = virInterfaceFindByName(&privconn->ifaces, iface->name);
    testDriverUnlock(privconn);
    if (!obj) {
3608
        virReportError(VIR_ERR_NO_INTERFACE, NULL);
3609 3610 3611 3612 3613 3614 3615 3616 3617 3618
        goto cleanup;
    }
    ret = virInterfaceObjIsActive(obj);

cleanup:
    if (obj)
        virInterfaceObjUnlock(obj);
    return ret;
}

3619
static int testInterfaceChangeBegin(virConnectPtr conn,
E
Eric Blake 已提交
3620
                                    unsigned int flags)
3621 3622 3623 3624
{
    testConnPtr privconn = conn->privateData;
    int ret = -1;

E
Eric Blake 已提交
3625 3626
    virCheckFlags(0, -1);

3627 3628
    testDriverLock(privconn);
    if (privconn->transaction_running) {
3629
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3630
                       _("there is another transaction running."));
3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646
        goto cleanup;
    }

    privconn->transaction_running = true;

    if (virInterfaceObjListClone(&privconn->ifaces,
                                 &privconn->backupIfaces) < 0)
        goto cleanup;

    ret = 0;
cleanup:
    testDriverUnlock(privconn);
    return ret;
}

static int testInterfaceChangeCommit(virConnectPtr conn,
E
Eric Blake 已提交
3647
                                     unsigned int flags)
3648 3649 3650 3651
{
    testConnPtr privconn = conn->privateData;
    int ret = -1;

E
Eric Blake 已提交
3652 3653
    virCheckFlags(0, -1);

3654 3655 3656
    testDriverLock(privconn);

    if (!privconn->transaction_running) {
3657
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3658 3659
                       _("no transaction running, "
                         "nothing to be committed."));
3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674
        goto cleanup;
    }

    virInterfaceObjListFree(&privconn->backupIfaces);
    privconn->transaction_running = false;

    ret = 0;

cleanup:
    testDriverUnlock(privconn);

    return ret;
}

static int testInterfaceChangeRollback(virConnectPtr conn,
E
Eric Blake 已提交
3675
                                       unsigned int flags)
3676 3677 3678 3679
{
    testConnPtr privconn = conn->privateData;
    int ret = -1;

E
Eric Blake 已提交
3680 3681
    virCheckFlags(0, -1);

3682 3683 3684
    testDriverLock(privconn);

    if (!privconn->transaction_running) {
3685
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3686 3687
                       _("no transaction running, "
                         "nothing to rollback."));
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704
        goto cleanup;
    }

    virInterfaceObjListFree(&privconn->ifaces);
    privconn->ifaces.count = privconn->backupIfaces.count;
    privconn->ifaces.objs = privconn->backupIfaces.objs;
    privconn->backupIfaces.count = 0;
    privconn->backupIfaces.objs = NULL;

    privconn->transaction_running = false;

    ret = 0;

cleanup:
    testDriverUnlock(privconn);
    return ret;
}
3705

L
Laine Stump 已提交
3706
static char *testInterfaceGetXMLDesc(virInterfacePtr iface,
E
Eric Blake 已提交
3707
                                     unsigned int flags)
L
Laine Stump 已提交
3708 3709 3710 3711 3712
{
    testConnPtr privconn = iface->conn->privateData;
    virInterfaceObjPtr privinterface;
    char *ret = NULL;

E
Eric Blake 已提交
3713 3714
    virCheckFlags(0, NULL);

L
Laine Stump 已提交
3715 3716 3717 3718 3719 3720
    testDriverLock(privconn);
    privinterface = virInterfaceFindByName(&privconn->ifaces,
                                           iface->name);
    testDriverUnlock(privconn);

    if (privinterface == NULL) {
3721
        virReportError(VIR_ERR_NO_INTERFACE, __FUNCTION__);
L
Laine Stump 已提交
3722 3723 3724
        goto cleanup;
    }

3725
    ret = virInterfaceDefFormat(privinterface->def);
L
Laine Stump 已提交
3726 3727 3728 3729 3730 3731 3732 3733 3734

cleanup:
    if (privinterface)
        virInterfaceObjUnlock(privinterface);
    return ret;
}


static virInterfacePtr testInterfaceDefineXML(virConnectPtr conn, const char *xmlStr,
E
Eric Blake 已提交
3735
                                              unsigned int flags)
L
Laine Stump 已提交
3736 3737 3738 3739 3740 3741
{
    testConnPtr privconn = conn->privateData;
    virInterfaceDefPtr def;
    virInterfaceObjPtr iface = NULL;
    virInterfacePtr ret = NULL;

E
Eric Blake 已提交
3742 3743
    virCheckFlags(0, NULL);

L
Laine Stump 已提交
3744
    testDriverLock(privconn);
3745
    if ((def = virInterfaceDefParseString(xmlStr)) == NULL)
L
Laine Stump 已提交
3746 3747
        goto cleanup;

3748
    if ((iface = virInterfaceAssignDef(&privconn->ifaces, def)) == NULL)
L
Laine Stump 已提交
3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772
        goto cleanup;
    def = NULL;

    ret = virGetInterface(conn, iface->def->name, iface->def->mac);

cleanup:
    virInterfaceDefFree(def);
    if (iface)
        virInterfaceObjUnlock(iface);
    testDriverUnlock(privconn);
    return ret;
}

static int testInterfaceUndefine(virInterfacePtr iface)
{
    testConnPtr privconn = iface->conn->privateData;
    virInterfaceObjPtr privinterface;
    int ret = -1;

    testDriverLock(privconn);
    privinterface = virInterfaceFindByName(&privconn->ifaces,
                                           iface->name);

    if (privinterface == NULL) {
3773
        virReportError(VIR_ERR_NO_INTERFACE, NULL);
L
Laine Stump 已提交
3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786
        goto cleanup;
    }

    virInterfaceRemove(&privconn->ifaces,
                       privinterface);
    ret = 0;

cleanup:
    testDriverUnlock(privconn);
    return ret;
}

static int testInterfaceCreate(virInterfacePtr iface,
E
Eric Blake 已提交
3787
                               unsigned int flags)
L
Laine Stump 已提交
3788 3789 3790 3791 3792
{
    testConnPtr privconn = iface->conn->privateData;
    virInterfaceObjPtr privinterface;
    int ret = -1;

E
Eric Blake 已提交
3793 3794
    virCheckFlags(0, -1);

L
Laine Stump 已提交
3795 3796 3797 3798 3799
    testDriverLock(privconn);
    privinterface = virInterfaceFindByName(&privconn->ifaces,
                                           iface->name);

    if (privinterface == NULL) {
3800
        virReportError(VIR_ERR_NO_INTERFACE, NULL);
L
Laine Stump 已提交
3801 3802 3803 3804
        goto cleanup;
    }

    if (privinterface->active != 0) {
3805
        virReportError(VIR_ERR_OPERATION_INVALID, NULL);
L
Laine Stump 已提交
3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819
        goto cleanup;
    }

    privinterface->active = 1;
    ret = 0;

cleanup:
    if (privinterface)
        virInterfaceObjUnlock(privinterface);
    testDriverUnlock(privconn);
    return ret;
}

static int testInterfaceDestroy(virInterfacePtr iface,
E
Eric Blake 已提交
3820
                                unsigned int flags)
L
Laine Stump 已提交
3821 3822 3823 3824 3825
{
    testConnPtr privconn = iface->conn->privateData;
    virInterfaceObjPtr privinterface;
    int ret = -1;

E
Eric Blake 已提交
3826 3827
    virCheckFlags(0, -1);

L
Laine Stump 已提交
3828 3829 3830 3831 3832
    testDriverLock(privconn);
    privinterface = virInterfaceFindByName(&privconn->ifaces,
                                           iface->name);

    if (privinterface == NULL) {
3833
        virReportError(VIR_ERR_NO_INTERFACE, NULL);
L
Laine Stump 已提交
3834 3835 3836 3837
        goto cleanup;
    }

    if (privinterface->active == 0) {
3838
        virReportError(VIR_ERR_OPERATION_INVALID, NULL);
L
Laine Stump 已提交
3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853
        goto cleanup;
    }

    privinterface->active = 0;
    ret = 0;

cleanup:
    if (privinterface)
        virInterfaceObjUnlock(privinterface);
    testDriverUnlock(privconn);
    return ret;
}



C
Cole Robinson 已提交
3854 3855 3856 3857
/*
 * Storage Driver routines
 */

3858

3859
static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool) {
C
Cole Robinson 已提交
3860 3861 3862 3863 3864 3865 3866

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

    pool->configFile = strdup("\0");
    if (!pool->configFile) {
3867
        virReportOOMError();
C
Cole Robinson 已提交
3868 3869 3870 3871 3872 3873
        return -1;
    }

    return 0;
}

3874 3875
static virDrvOpenStatus testStorageOpen(virConnectPtr conn,
                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
3876 3877 3878 3879
                                        unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891
    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;
}

3892

C
Cole Robinson 已提交
3893 3894 3895
static virStoragePoolPtr
testStoragePoolLookupByUUID(virConnectPtr conn,
                            const unsigned char *uuid) {
3896
    testConnPtr privconn = conn->privateData;
3897 3898
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
3899

3900
    testDriverLock(privconn);
3901
    pool = virStoragePoolObjFindByUUID(&privconn->pools, uuid);
3902
    testDriverUnlock(privconn);
3903 3904

    if (pool == NULL) {
3905
        virReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
3906
        goto cleanup;
C
Cole Robinson 已提交
3907 3908
    }

3909 3910
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
3911 3912

cleanup:
3913 3914
    if (pool)
        virStoragePoolObjUnlock(pool);
3915
    return ret;
C
Cole Robinson 已提交
3916 3917 3918 3919 3920
}

static virStoragePoolPtr
testStoragePoolLookupByName(virConnectPtr conn,
                            const char *name) {
3921
    testConnPtr privconn = conn->privateData;
3922 3923
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
3924

3925
    testDriverLock(privconn);
3926
    pool = virStoragePoolObjFindByName(&privconn->pools, name);
3927
    testDriverUnlock(privconn);
3928 3929

    if (pool == NULL) {
3930
        virReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
3931
        goto cleanup;
C
Cole Robinson 已提交
3932 3933
    }

3934 3935
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
3936 3937

cleanup:
3938 3939
    if (pool)
        virStoragePoolObjUnlock(pool);
3940
    return ret;
C
Cole Robinson 已提交
3941 3942 3943 3944 3945 3946 3947 3948 3949
}

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

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

3953
    testDriverLock(privconn);
C
Cole Robinson 已提交
3954 3955 3956
    for (i = 0 ; i < privconn->pools.count ; i++)
        if (virStoragePoolObjIsActive(privconn->pools.objs[i]))
            numActive++;
3957
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
3958 3959 3960 3961 3962 3963 3964 3965

    return numActive;
}

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

3969
    testDriverLock(privconn);
C
Cole Robinson 已提交
3970
    memset(names, 0, sizeof(*names)*nnames);
3971 3972
    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
3973
        if (virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
3974 3975
            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
            virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
3976
            goto no_memory;
3977 3978 3979 3980
        }
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
    }
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
3981 3982 3983 3984

    return n;

no_memory:
3985
    virReportOOMError();
C
Cole Robinson 已提交
3986 3987
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
3988
    testDriverUnlock(privconn);
3989
    return -1;
C
Cole Robinson 已提交
3990 3991 3992 3993
}

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

3997 3998 3999
    testDriverLock(privconn);
    for (i = 0 ; i < privconn->pools.count ; i++) {
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4000 4001
        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]))
            numInactive++;
4002 4003 4004
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
    }
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4005 4006 4007 4008 4009 4010 4011 4012

    return numInactive;
}

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

4016
    testDriverLock(privconn);
C
Cole Robinson 已提交
4017
    memset(names, 0, sizeof(*names)*nnames);
4018 4019
    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4020
        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
4021 4022
            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
            virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4023
            goto no_memory;
4024 4025 4026 4027
        }
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
    }
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4028 4029 4030 4031

    return n;

no_memory:
4032
    virReportOOMError();
C
Cole Robinson 已提交
4033 4034
    for (n = 0 ; n < nnames ; n++)
        VIR_FREE(names[n]);
4035
    testDriverUnlock(privconn);
4036
    return -1;
C
Cole Robinson 已提交
4037 4038
}

4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054
static int
testStorageListAllPools(virConnectPtr conn,
                        virStoragePoolPtr **pools,
                        unsigned int flags)
{
    testConnPtr privconn = conn->privateData;
    int ret = -1;

    virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1);

    testDriverLock(privconn);
    ret = virStoragePoolList(conn, privconn->pools, pools, flags);
    testDriverUnlock(privconn);

    return ret;
}
C
Cole Robinson 已提交
4055

4056 4057 4058 4059 4060 4061 4062 4063 4064 4065
static int testStoragePoolIsActive(virStoragePoolPtr pool)
{
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
    obj = virStoragePoolObjFindByUUID(&privconn->pools, pool->uuid);
    testDriverUnlock(privconn);
    if (!obj) {
4066
        virReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086
        goto cleanup;
    }
    ret = virStoragePoolObjIsActive(obj);

cleanup:
    if (obj)
        virStoragePoolObjUnlock(obj);
    return ret;
}

static int testStoragePoolIsPersistent(virStoragePoolPtr pool)
{
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr obj;
    int ret = -1;

    testDriverLock(privconn);
    obj = virStoragePoolObjFindByUUID(&privconn->pools, pool->uuid);
    testDriverUnlock(privconn);
    if (!obj) {
4087
        virReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099
        goto cleanup;
    }
    ret = obj->configFile ? 1 : 0;

cleanup:
    if (obj)
        virStoragePoolObjUnlock(obj);
    return ret;
}



C
Cole Robinson 已提交
4100
static int
4101
testStoragePoolStart(virStoragePoolPtr pool,
E
Eric Blake 已提交
4102 4103
                     unsigned int flags)
{
4104 4105
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4106
    int ret = -1;
4107

E
Eric Blake 已提交
4108 4109
    virCheckFlags(0, -1);

4110
    testDriverLock(privconn);
4111 4112
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4113
    testDriverUnlock(privconn);
4114 4115

    if (privpool == NULL) {
4116
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4117
        goto cleanup;
4118 4119
    }

4120
    if (virStoragePoolObjIsActive(privpool)) {
4121 4122
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is already active"), pool->name);
4123 4124
        goto cleanup;
    }
C
Cole Robinson 已提交
4125 4126

    privpool->active = 1;
4127
    ret = 0;
C
Cole Robinson 已提交
4128

4129
cleanup:
4130 4131
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4132
    return ret;
C
Cole Robinson 已提交
4133 4134 4135
}

static char *
4136
testStorageFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
4137 4138
                           const char *type,
                           const char *srcSpec,
E
Eric Blake 已提交
4139
                           unsigned int flags)
C
Cole Robinson 已提交
4140
{
4141 4142 4143 4144
    virStoragePoolSourcePtr source = NULL;
    int pool_type;
    char *ret = NULL;

E
Eric Blake 已提交
4145 4146
    virCheckFlags(0, NULL);

4147 4148
    pool_type = virStoragePoolTypeFromString(type);
    if (!pool_type) {
4149 4150
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown storage pool type %s"), type);
4151 4152 4153 4154
        goto cleanup;
    }

    if (srcSpec) {
4155
        source = virStoragePoolDefParseSourceString(srcSpec, pool_type);
4156 4157 4158 4159 4160 4161 4162 4163 4164
        if (!source)
            goto cleanup;
    }

    switch (pool_type) {

    case VIR_STORAGE_POOL_LOGICAL:
        ret = strdup(defaultPoolSourcesLogicalXML);
        if (!ret)
4165
            virReportOOMError();
4166 4167 4168
        break;

    case VIR_STORAGE_POOL_NETFS:
4169
        if (!source || !source->hosts[0].name) {
4170 4171
            virReportError(VIR_ERR_INVALID_ARG,
                           "%s", _("hostname must be specified for netfs sources"));
4172 4173 4174 4175
            goto cleanup;
        }

        if (virAsprintf(&ret, defaultPoolSourcesNetFSXML,
4176
                        source->hosts[0].name) < 0)
4177
            virReportOOMError();
4178 4179 4180
        break;

    default:
4181 4182
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("pool type '%s' does not support source discovery"), type);
4183 4184 4185 4186 4187
    }

cleanup:
    virStoragePoolSourceFree(source);
    return ret;
C
Cole Robinson 已提交
4188 4189 4190 4191 4192 4193
}


static virStoragePoolPtr
testStoragePoolCreate(virConnectPtr conn,
                      const char *xml,
E
Eric Blake 已提交
4194 4195
                      unsigned int flags)
{
4196
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
4197
    virStoragePoolDefPtr def;
4198
    virStoragePoolObjPtr pool = NULL;
4199
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
4200

E
Eric Blake 已提交
4201 4202
    virCheckFlags(0, NULL);

4203
    testDriverLock(privconn);
4204
    if (!(def = virStoragePoolDefParseString(xml)))
4205
        goto cleanup;
C
Cole Robinson 已提交
4206

4207 4208 4209 4210
    pool = virStoragePoolObjFindByUUID(&privconn->pools, def->uuid);
    if (!pool)
        pool = virStoragePoolObjFindByName(&privconn->pools, def->name);
    if (pool) {
4211 4212
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("storage pool already exists"));
4213
        goto cleanup;
C
Cole Robinson 已提交
4214 4215
    }

4216
    if (!(pool = virStoragePoolObjAssignDef(&privconn->pools, def)))
4217
        goto cleanup;
4218
    def = NULL;
C
Cole Robinson 已提交
4219

4220
    if (testStoragePoolObjSetDefaults(pool) == -1) {
C
Cole Robinson 已提交
4221
        virStoragePoolObjRemove(&privconn->pools, pool);
4222 4223
        pool = NULL;
        goto cleanup;
C
Cole Robinson 已提交
4224 4225 4226
    }
    pool->active = 1;

4227 4228
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
4229 4230 4231

cleanup:
    virStoragePoolDefFree(def);
4232 4233 4234
    if (pool)
        virStoragePoolObjUnlock(pool);
    testDriverUnlock(privconn);
4235
    return ret;
C
Cole Robinson 已提交
4236 4237 4238 4239 4240
}

static virStoragePoolPtr
testStoragePoolDefine(virConnectPtr conn,
                      const char *xml,
E
Eric Blake 已提交
4241 4242
                      unsigned int flags)
{
4243
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
4244
    virStoragePoolDefPtr def;
4245
    virStoragePoolObjPtr pool = NULL;
4246
    virStoragePoolPtr ret = NULL;
C
Cole Robinson 已提交
4247

E
Eric Blake 已提交
4248 4249
    virCheckFlags(0, NULL);

4250
    testDriverLock(privconn);
4251
    if (!(def = virStoragePoolDefParseString(xml)))
4252
        goto cleanup;
C
Cole Robinson 已提交
4253 4254 4255 4256 4257

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

4258
    if (!(pool = virStoragePoolObjAssignDef(&privconn->pools, def)))
4259 4260
        goto cleanup;
    def = NULL;
C
Cole Robinson 已提交
4261

4262
    if (testStoragePoolObjSetDefaults(pool) == -1) {
C
Cole Robinson 已提交
4263
        virStoragePoolObjRemove(&privconn->pools, pool);
4264 4265
        pool = NULL;
        goto cleanup;
C
Cole Robinson 已提交
4266 4267
    }

4268 4269
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
4270 4271 4272

cleanup:
    virStoragePoolDefFree(def);
4273 4274 4275
    if (pool)
        virStoragePoolObjUnlock(pool);
    testDriverUnlock(privconn);
4276
    return ret;
C
Cole Robinson 已提交
4277 4278 4279
}

static int
4280 4281 4282
testStoragePoolUndefine(virStoragePoolPtr pool) {
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4283
    int ret = -1;
4284

4285
    testDriverLock(privconn);
4286 4287 4288 4289
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);

    if (privpool == NULL) {
4290
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4291
        goto cleanup;
4292 4293
    }

4294
    if (virStoragePoolObjIsActive(privpool)) {
4295 4296
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is already active"), pool->name);
4297 4298
        goto cleanup;
    }
C
Cole Robinson 已提交
4299 4300

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

4303
cleanup:
4304 4305 4306
    if (privpool)
        virStoragePoolObjUnlock(privpool);
    testDriverUnlock(privconn);
4307
    return ret;
C
Cole Robinson 已提交
4308 4309 4310
}

static int
4311
testStoragePoolBuild(virStoragePoolPtr pool,
E
Eric Blake 已提交
4312 4313
                     unsigned int flags)
{
4314 4315
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4316
    int ret = -1;
4317

E
Eric Blake 已提交
4318 4319
    virCheckFlags(0, -1);

4320
    testDriverLock(privconn);
4321 4322
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4323
    testDriverUnlock(privconn);
4324 4325

    if (privpool == NULL) {
4326
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4327
        goto cleanup;
4328 4329
    }

4330
    if (virStoragePoolObjIsActive(privpool)) {
4331 4332
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is already active"), pool->name);
4333 4334
        goto cleanup;
    }
4335
    ret = 0;
C
Cole Robinson 已提交
4336

4337
cleanup:
4338 4339
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4340
    return ret;
C
Cole Robinson 已提交
4341 4342 4343 4344
}


static int
4345 4346 4347
testStoragePoolDestroy(virStoragePoolPtr pool) {
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4348
    int ret = -1;
4349

4350
    testDriverLock(privconn);
4351 4352 4353 4354
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);

    if (privpool == NULL) {
4355
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4356
        goto cleanup;
4357 4358 4359
    }

    if (!virStoragePoolObjIsActive(privpool)) {
4360 4361
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4362
        goto cleanup;
4363
    }
C
Cole Robinson 已提交
4364 4365 4366

    privpool->active = 0;

4367
    if (privpool->configFile == NULL) {
C
Cole Robinson 已提交
4368
        virStoragePoolObjRemove(&privconn->pools, privpool);
4369 4370
        privpool = NULL;
    }
4371
    ret = 0;
C
Cole Robinson 已提交
4372

4373
cleanup:
4374 4375 4376
    if (privpool)
        virStoragePoolObjUnlock(privpool);
    testDriverUnlock(privconn);
4377
    return ret;
C
Cole Robinson 已提交
4378 4379 4380 4381
}


static int
4382
testStoragePoolDelete(virStoragePoolPtr pool,
E
Eric Blake 已提交
4383 4384
                      unsigned int flags)
{
4385 4386
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4387
    int ret = -1;
4388

E
Eric Blake 已提交
4389 4390
    virCheckFlags(0, -1);

4391
    testDriverLock(privconn);
4392 4393
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4394
    testDriverUnlock(privconn);
4395 4396

    if (privpool == NULL) {
4397
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4398 4399 4400 4401
        goto cleanup;
    }

    if (virStoragePoolObjIsActive(privpool)) {
4402 4403
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is already active"), pool->name);
4404
        goto cleanup;
4405 4406
    }

4407
    ret = 0;
C
Cole Robinson 已提交
4408

4409
cleanup:
4410 4411
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4412
    return ret;
C
Cole Robinson 已提交
4413 4414 4415 4416
}


static int
4417
testStoragePoolRefresh(virStoragePoolPtr pool,
E
Eric Blake 已提交
4418 4419
                       unsigned int flags)
{
4420 4421
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4422
    int ret = -1;
4423

E
Eric Blake 已提交
4424 4425
    virCheckFlags(0, -1);

4426
    testDriverLock(privconn);
4427 4428
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4429
    testDriverUnlock(privconn);
4430 4431

    if (privpool == NULL) {
4432
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4433
        goto cleanup;
4434 4435 4436
    }

    if (!virStoragePoolObjIsActive(privpool)) {
4437 4438
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4439
        goto cleanup;
4440
    }
4441
    ret = 0;
C
Cole Robinson 已提交
4442

4443
cleanup:
4444 4445
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4446
    return ret;
C
Cole Robinson 已提交
4447 4448 4449 4450
}


static int
4451
testStoragePoolGetInfo(virStoragePoolPtr pool,
C
Cole Robinson 已提交
4452
                       virStoragePoolInfoPtr info) {
4453 4454
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4455
    int ret = -1;
4456

4457
    testDriverLock(privconn);
4458 4459
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4460
    testDriverUnlock(privconn);
4461 4462

    if (privpool == NULL) {
4463
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4464
        goto cleanup;
4465
    }
C
Cole Robinson 已提交
4466 4467 4468 4469 4470 4471 4472 4473 4474

    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;
4475
    ret = 0;
C
Cole Robinson 已提交
4476

4477
cleanup:
4478 4479
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4480
    return ret;
C
Cole Robinson 已提交
4481 4482 4483
}

static char *
4484
testStoragePoolGetXMLDesc(virStoragePoolPtr pool,
E
Eric Blake 已提交
4485 4486
                          unsigned int flags)
{
4487 4488
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4489
    char *ret = NULL;
4490

E
Eric Blake 已提交
4491 4492
    virCheckFlags(0, NULL);

4493
    testDriverLock(privconn);
4494 4495
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4496
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4497

4498
    if (privpool == NULL) {
4499
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4500
        goto cleanup;
4501 4502
    }

4503
    ret = virStoragePoolDefFormat(privpool->def);
4504 4505

cleanup:
4506 4507
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4508
    return ret;
C
Cole Robinson 已提交
4509 4510 4511
}

static int
4512
testStoragePoolGetAutostart(virStoragePoolPtr pool,
C
Cole Robinson 已提交
4513
                            int *autostart) {
4514 4515
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4516
    int ret = -1;
4517

4518
    testDriverLock(privconn);
4519 4520
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4521
    testDriverUnlock(privconn);
4522 4523

    if (privpool == NULL) {
4524
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4525
        goto cleanup;
4526
    }
C
Cole Robinson 已提交
4527 4528 4529 4530 4531 4532

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

4535
cleanup:
4536 4537
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4538
    return ret;
C
Cole Robinson 已提交
4539 4540 4541
}

static int
4542
testStoragePoolSetAutostart(virStoragePoolPtr pool,
C
Cole Robinson 已提交
4543
                            int autostart) {
4544 4545
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4546
    int ret = -1;
4547

4548
    testDriverLock(privconn);
4549 4550
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4551
    testDriverUnlock(privconn);
4552 4553

    if (privpool == NULL) {
4554
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4555
        goto cleanup;
4556
    }
C
Cole Robinson 已提交
4557 4558

    if (!privpool->configFile) {
4559 4560
        virReportError(VIR_ERR_INVALID_ARG,
                       "%s", _("pool has no config file"));
4561
        goto cleanup;
C
Cole Robinson 已提交
4562 4563 4564 4565
    }

    autostart = (autostart != 0);
    privpool->autostart = autostart;
4566 4567 4568
    ret = 0;

cleanup:
4569 4570
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4571
    return ret;
C
Cole Robinson 已提交
4572 4573 4574 4575
}


static int
4576 4577 4578
testStoragePoolNumVolumes(virStoragePoolPtr pool) {
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4579
    int ret = -1;
4580

4581
    testDriverLock(privconn);
4582 4583
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4584
    testDriverUnlock(privconn);
4585 4586

    if (privpool == NULL) {
4587
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4588
        goto cleanup;
4589 4590 4591
    }

    if (!virStoragePoolObjIsActive(privpool)) {
4592 4593
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4594
        goto cleanup;
4595
    }
C
Cole Robinson 已提交
4596

4597 4598 4599
    ret = privpool->volumes.count;

cleanup:
4600 4601
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4602
    return ret;
C
Cole Robinson 已提交
4603 4604 4605
}

static int
4606
testStoragePoolListVolumes(virStoragePoolPtr pool,
C
Cole Robinson 已提交
4607 4608
                           char **const names,
                           int maxnames) {
4609 4610
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
C
Cole Robinson 已提交
4611 4612
    int i = 0, n = 0;

4613
    memset(names, 0, maxnames * sizeof(*names));
4614 4615

    testDriverLock(privconn);
4616 4617
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4618
    testDriverUnlock(privconn);
4619 4620

    if (privpool == NULL) {
4621
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4622
        goto cleanup;
4623 4624 4625 4626
    }


    if (!virStoragePoolObjIsActive(privpool)) {
4627 4628
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4629
        goto cleanup;
4630 4631
    }

C
Cole Robinson 已提交
4632 4633
    for (i = 0 ; i < privpool->volumes.count && n < maxnames ; i++) {
        if ((names[n++] = strdup(privpool->volumes.objs[i]->name)) == NULL) {
4634
            virReportOOMError();
C
Cole Robinson 已提交
4635 4636 4637 4638
            goto cleanup;
        }
    }

4639
    virStoragePoolObjUnlock(privpool);
C
Cole Robinson 已提交
4640 4641 4642 4643 4644 4645
    return n;

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

4646
    memset(names, 0, maxnames * sizeof(*names));
4647 4648
    if (privpool)
        virStoragePoolObjUnlock(privpool);
C
Cole Robinson 已提交
4649 4650 4651
    return -1;
}

4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695
static int
testStoragePoolListAllVolumes(virStoragePoolPtr obj,
                              virStorageVolPtr **vols,
                              unsigned int flags) {
    testConnPtr privconn = obj->conn->privateData;
    virStoragePoolObjPtr pool;
    int i;
    virStorageVolPtr *tmp_vols = NULL;
    virStorageVolPtr vol = NULL;
    int nvols = 0;
    int ret = -1;

    virCheckFlags(0, -1);

    testDriverLock(privconn);
    pool = virStoragePoolObjFindByUUID(&privconn->pools, obj->uuid);
    testDriverUnlock(privconn);

    if (!pool) {
        virReportError(VIR_ERR_NO_STORAGE_POOL, "%s",
                       _("no storage pool with matching uuid"));
        goto cleanup;
    }

    if (!virStoragePoolObjIsActive(pool)) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("storage pool is not active"));
        goto cleanup;
    }

     /* Just returns the volumes count */
    if (!vols) {
        ret = pool->volumes.count;
        goto cleanup;
    }

    if (VIR_ALLOC_N(tmp_vols, pool->volumes.count + 1) < 0) {
         virReportOOMError();
         goto cleanup;
    }

    for (i = 0 ; i < pool->volumes.count; i++) {
        if (!(vol = virGetStorageVol(obj->conn, pool->def->name,
                                     pool->volumes.objs[i]->name,
4696 4697
                                     pool->volumes.objs[i]->key,
                                     NULL, NULL)))
4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711
            goto cleanup;
        tmp_vols[nvols++] = vol;
    }

    *vols = tmp_vols;
    tmp_vols = NULL;
    ret = nvols;

 cleanup:
    if (tmp_vols) {
        for (i = 0; i < nvols; i++) {
            if (tmp_vols[i])
                virStorageVolFree(tmp_vols[i]);
        }
4712
        VIR_FREE(tmp_vols);
4713 4714 4715 4716 4717 4718 4719
    }

    if (pool)
        virStoragePoolObjUnlock(pool);

    return ret;
}
C
Cole Robinson 已提交
4720 4721

static virStorageVolPtr
4722
testStorageVolumeLookupByName(virStoragePoolPtr pool,
C
Cole Robinson 已提交
4723
                              const char *name ATTRIBUTE_UNUSED) {
4724 4725 4726
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
4727
    virStorageVolPtr ret = NULL;
4728

4729
    testDriverLock(privconn);
4730 4731
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4732
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4733

4734
    if (privpool == NULL) {
4735
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4736
        goto cleanup;
4737 4738 4739 4740
    }


    if (!virStoragePoolObjIsActive(privpool)) {
4741 4742
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4743
        goto cleanup;
4744 4745 4746 4747 4748
    }

    privvol = virStorageVolDefFindByName(privpool, name);

    if (!privvol) {
4749 4750
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"), name);
4751
        goto cleanup;
C
Cole Robinson 已提交
4752 4753
    }

4754
    ret = virGetStorageVol(pool->conn, privpool->def->name,
4755 4756
                           privvol->name, privvol->key,
                           NULL, NULL);
4757 4758

cleanup:
4759 4760
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4761
    return ret;
C
Cole Robinson 已提交
4762 4763 4764 4765 4766 4767
}


static virStorageVolPtr
testStorageVolumeLookupByKey(virConnectPtr conn,
                             const char *key) {
4768
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
4769
    unsigned int i;
4770
    virStorageVolPtr ret = NULL;
C
Cole Robinson 已提交
4771

4772
    testDriverLock(privconn);
C
Cole Robinson 已提交
4773
    for (i = 0 ; i < privconn->pools.count ; i++) {
4774
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4775
        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
4776
            virStorageVolDefPtr privvol =
C
Cole Robinson 已提交
4777 4778
                virStorageVolDefFindByKey(privconn->pools.objs[i], key);

4779 4780 4781 4782
            if (privvol) {
                ret = virGetStorageVol(conn,
                                       privconn->pools.objs[i]->def->name,
                                       privvol->name,
4783 4784
                                       privvol->key,
                                       NULL, NULL);
4785
                virStoragePoolObjUnlock(privconn->pools.objs[i]);
4786 4787
                break;
            }
C
Cole Robinson 已提交
4788
        }
4789
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4790
    }
4791
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4792

4793
    if (!ret)
4794 4795
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching key '%s'"), key);
4796 4797

    return ret;
C
Cole Robinson 已提交
4798 4799 4800 4801 4802
}

static virStorageVolPtr
testStorageVolumeLookupByPath(virConnectPtr conn,
                              const char *path) {
4803
    testConnPtr privconn = conn->privateData;
C
Cole Robinson 已提交
4804
    unsigned int i;
4805
    virStorageVolPtr ret = NULL;
C
Cole Robinson 已提交
4806

4807
    testDriverLock(privconn);
C
Cole Robinson 已提交
4808
    for (i = 0 ; i < privconn->pools.count ; i++) {
4809
        virStoragePoolObjLock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4810
        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
4811
            virStorageVolDefPtr privvol =
C
Cole Robinson 已提交
4812 4813
                virStorageVolDefFindByPath(privconn->pools.objs[i], path);

4814 4815 4816 4817
            if (privvol) {
                ret = virGetStorageVol(conn,
                                       privconn->pools.objs[i]->def->name,
                                       privvol->name,
4818 4819
                                       privvol->key,
                                       NULL, NULL);
4820
                virStoragePoolObjUnlock(privconn->pools.objs[i]);
4821 4822
                break;
            }
C
Cole Robinson 已提交
4823
        }
4824
        virStoragePoolObjUnlock(privconn->pools.objs[i]);
C
Cole Robinson 已提交
4825
    }
4826
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4827

4828
    if (!ret)
4829 4830
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching path '%s'"), path);
4831 4832

    return ret;
C
Cole Robinson 已提交
4833 4834 4835
}

static virStorageVolPtr
4836
testStorageVolumeCreateXML(virStoragePoolPtr pool,
C
Cole Robinson 已提交
4837
                           const char *xmldesc,
E
Eric Blake 已提交
4838 4839
                           unsigned int flags)
{
4840 4841
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
4842 4843
    virStorageVolDefPtr privvol = NULL;
    virStorageVolPtr ret = NULL;
4844

E
Eric Blake 已提交
4845 4846
    virCheckFlags(0, NULL);

4847
    testDriverLock(privconn);
4848 4849
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
4850
    testDriverUnlock(privconn);
C
Cole Robinson 已提交
4851

4852
    if (privpool == NULL) {
4853
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4854
        goto cleanup;
4855 4856 4857
    }

    if (!virStoragePoolObjIsActive(privpool)) {
4858 4859
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4860
        goto cleanup;
4861
    }
C
Cole Robinson 已提交
4862

4863
    privvol = virStorageVolDefParseString(privpool->def, xmldesc);
4864
    if (privvol == NULL)
4865
        goto cleanup;
4866 4867

    if (virStorageVolDefFindByName(privpool, privvol->name)) {
4868 4869
        virReportError(VIR_ERR_OPERATION_FAILED,
                       "%s", _("storage vol already exists"));
4870
        goto cleanup;
C
Cole Robinson 已提交
4871 4872 4873
    }

    /* Make sure enough space */
4874
    if ((privpool->def->allocation + privvol->allocation) >
C
Cole Robinson 已提交
4875
         privpool->def->capacity) {
4876 4877 4878
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Not enough free space in pool for volume '%s'"),
                       privvol->name);
4879
        goto cleanup;
C
Cole Robinson 已提交
4880 4881 4882 4883
    }

    if (VIR_REALLOC_N(privpool->volumes.objs,
                      privpool->volumes.count+1) < 0) {
4884
        virReportOOMError();
4885
        goto cleanup;
C
Cole Robinson 已提交
4886 4887
    }

4888 4889 4890
    if (virAsprintf(&privvol->target.path, "%s/%s",
                    privpool->def->target.path,
                    privvol->name) == -1) {
4891
        virReportOOMError();
4892
        goto cleanup;
C
Cole Robinson 已提交
4893 4894
    }

4895 4896
    privvol->key = strdup(privvol->target.path);
    if (privvol->key == NULL) {
4897
        virReportOOMError();
4898
        goto cleanup;
C
Cole Robinson 已提交
4899 4900
    }

4901
    privpool->def->allocation += privvol->allocation;
C
Cole Robinson 已提交
4902 4903 4904
    privpool->def->available = (privpool->def->capacity -
                                privpool->def->allocation);

4905
    privpool->volumes.objs[privpool->volumes.count++] = privvol;
C
Cole Robinson 已提交
4906

4907
    ret = virGetStorageVol(pool->conn, privpool->def->name,
4908 4909
                           privvol->name, privvol->key,
                           NULL, NULL);
4910
    privvol = NULL;
4911 4912 4913

cleanup:
    virStorageVolDefFree(privvol);
4914 4915
    if (privpool)
        virStoragePoolObjUnlock(privpool);
4916
    return ret;
C
Cole Robinson 已提交
4917 4918
}

4919 4920 4921 4922
static virStorageVolPtr
testStorageVolumeCreateXMLFrom(virStoragePoolPtr pool,
                               const char *xmldesc,
                               virStorageVolPtr clonevol,
E
Eric Blake 已提交
4923 4924
                               unsigned int flags)
{
4925 4926 4927 4928 4929
    testConnPtr privconn = pool->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol = NULL, origvol = NULL;
    virStorageVolPtr ret = NULL;

E
Eric Blake 已提交
4930 4931
    virCheckFlags(0, NULL);

4932 4933 4934 4935 4936 4937
    testDriverLock(privconn);
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           pool->name);
    testDriverUnlock(privconn);

    if (privpool == NULL) {
4938
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
4939 4940 4941 4942
        goto cleanup;
    }

    if (!virStoragePoolObjIsActive(privpool)) {
4943 4944
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), pool->name);
4945 4946 4947
        goto cleanup;
    }

4948
    privvol = virStorageVolDefParseString(privpool->def, xmldesc);
4949 4950 4951 4952
    if (privvol == NULL)
        goto cleanup;

    if (virStorageVolDefFindByName(privpool, privvol->name)) {
4953 4954
        virReportError(VIR_ERR_OPERATION_FAILED,
                       "%s", _("storage vol already exists"));
4955 4956 4957 4958 4959
        goto cleanup;
    }

    origvol = virStorageVolDefFindByName(privpool, clonevol->name);
    if (!origvol) {
4960 4961 4962
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       clonevol->name);
4963 4964 4965 4966 4967 4968
        goto cleanup;
    }

    /* Make sure enough space */
    if ((privpool->def->allocation + privvol->allocation) >
         privpool->def->capacity) {
4969 4970 4971
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Not enough free space in pool for volume '%s'"),
                       privvol->name);
4972 4973 4974 4975 4976 4977 4978
        goto cleanup;
    }
    privpool->def->available = (privpool->def->capacity -
                                privpool->def->allocation);

    if (VIR_REALLOC_N(privpool->volumes.objs,
                      privpool->volumes.count+1) < 0) {
4979
        virReportOOMError();
4980 4981 4982
        goto cleanup;
    }

4983 4984 4985
    if (virAsprintf(&privvol->target.path, "%s/%s",
                    privpool->def->target.path,
                    privvol->name) == -1) {
4986
        virReportOOMError();
4987 4988 4989 4990 4991
        goto cleanup;
    }

    privvol->key = strdup(privvol->target.path);
    if (privvol->key == NULL) {
4992
        virReportOOMError();
4993 4994 4995 4996 4997 4998 4999 5000 5001 5002
        goto cleanup;
    }

    privpool->def->allocation += privvol->allocation;
    privpool->def->available = (privpool->def->capacity -
                                privpool->def->allocation);

    privpool->volumes.objs[privpool->volumes.count++] = privvol;

    ret = virGetStorageVol(pool->conn, privpool->def->name,
5003 5004
                           privvol->name, privvol->key,
                           NULL, NULL);
5005 5006 5007 5008 5009 5010 5011 5012 5013
    privvol = NULL;

cleanup:
    virStorageVolDefFree(privvol);
    if (privpool)
        virStoragePoolObjUnlock(privpool);
    return ret;
}

C
Cole Robinson 已提交
5014
static int
5015
testStorageVolumeDelete(virStorageVolPtr vol,
E
Eric Blake 已提交
5016 5017
                        unsigned int flags)
{
5018 5019 5020
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
C
Cole Robinson 已提交
5021
    int i;
5022
    int ret = -1;
C
Cole Robinson 已提交
5023

E
Eric Blake 已提交
5024 5025
    virCheckFlags(0, -1);

5026
    testDriverLock(privconn);
5027 5028
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
5029
    testDriverUnlock(privconn);
5030 5031

    if (privpool == NULL) {
5032
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
5033
        goto cleanup;
5034 5035 5036 5037 5038 5039
    }


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

    if (privvol == NULL) {
5040 5041 5042
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       vol->name);
5043
        goto cleanup;
5044 5045 5046
    }

    if (!virStoragePoolObjIsActive(privpool)) {
5047 5048
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), vol->pool);
5049
        goto cleanup;
5050 5051 5052
    }


C
Cole Robinson 已提交
5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075
    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;
        }
    }
5076
    ret = 0;
C
Cole Robinson 已提交
5077

5078
cleanup:
5079 5080
    if (privpool)
        virStoragePoolObjUnlock(privpool);
5081
    return ret;
C
Cole Robinson 已提交
5082 5083 5084 5085 5086
}


static int testStorageVolumeTypeForPool(int pooltype) {

5087
    switch (pooltype) {
C
Cole Robinson 已提交
5088 5089 5090 5091 5092 5093 5094 5095 5096 5097
        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
5098
testStorageVolumeGetInfo(virStorageVolPtr vol,
C
Cole Robinson 已提交
5099
                         virStorageVolInfoPtr info) {
5100 5101 5102
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
5103
    int ret = -1;
5104

5105
    testDriverLock(privconn);
5106 5107
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
5108
    testDriverUnlock(privconn);
5109 5110

    if (privpool == NULL) {
5111
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
5112
        goto cleanup;
5113 5114 5115 5116 5117
    }

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

    if (privvol == NULL) {
5118 5119 5120
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       vol->name);
5121
        goto cleanup;
5122 5123 5124
    }

    if (!virStoragePoolObjIsActive(privpool)) {
5125 5126
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), vol->pool);
5127
        goto cleanup;
5128
    }
C
Cole Robinson 已提交
5129 5130 5131 5132 5133

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

5136
cleanup:
5137 5138
    if (privpool)
        virStoragePoolObjUnlock(privpool);
5139
    return ret;
C
Cole Robinson 已提交
5140 5141 5142
}

static char *
5143
testStorageVolumeGetXMLDesc(virStorageVolPtr vol,
E
Eric Blake 已提交
5144 5145
                            unsigned int flags)
{
5146 5147 5148
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
5149
    char *ret = NULL;
5150

E
Eric Blake 已提交
5151 5152
    virCheckFlags(0, NULL);

5153
    testDriverLock(privconn);
5154 5155
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
5156
    testDriverUnlock(privconn);
5157 5158

    if (privpool == NULL) {
5159
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
5160
        goto cleanup;
5161 5162 5163 5164 5165
    }

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

    if (privvol == NULL) {
5166 5167 5168
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       vol->name);
5169
        goto cleanup;
5170
    }
C
Cole Robinson 已提交
5171

5172
    if (!virStoragePoolObjIsActive(privpool)) {
5173 5174
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), vol->pool);
5175
        goto cleanup;
5176 5177
    }

5178
    ret = virStorageVolDefFormat(privpool->def, privvol);
5179 5180

cleanup:
5181 5182
    if (privpool)
        virStoragePoolObjUnlock(privpool);
5183
    return ret;
C
Cole Robinson 已提交
5184 5185 5186
}

static char *
5187 5188 5189 5190
testStorageVolumeGetPath(virStorageVolPtr vol) {
    testConnPtr privconn = vol->conn->privateData;
    virStoragePoolObjPtr privpool;
    virStorageVolDefPtr privvol;
5191
    char *ret = NULL;
5192

5193
    testDriverLock(privconn);
5194 5195
    privpool = virStoragePoolObjFindByName(&privconn->pools,
                                           vol->pool);
5196
    testDriverUnlock(privconn);
5197 5198

    if (privpool == NULL) {
5199
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
5200
        goto cleanup;
5201 5202 5203 5204 5205
    }

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

    if (privvol == NULL) {
5206 5207 5208
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       vol->name);
5209
        goto cleanup;
5210 5211 5212
    }

    if (!virStoragePoolObjIsActive(privpool)) {
5213 5214
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), vol->pool);
5215
        goto cleanup;
5216 5217
    }

C
Cole Robinson 已提交
5218
    ret = strdup(privvol->target.path);
5219
    if (ret == NULL)
5220
        virReportOOMError();
5221 5222

cleanup:
5223 5224
    if (privpool)
        virStoragePoolObjUnlock(privpool);
C
Cole Robinson 已提交
5225 5226 5227
    return ret;
}

5228

5229
/* Node device implementations */
5230 5231
static virDrvOpenStatus testDevMonOpen(virConnectPtr conn,
                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
5232 5233 5234 5235
                                       unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247
    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;
}

5248 5249 5250
static int
testNodeNumOfDevices(virConnectPtr conn,
                     const char *cap,
E
Eric Blake 已提交
5251
                     unsigned int flags)
5252 5253 5254 5255 5256
{
    testConnPtr driver = conn->privateData;
    int ndevs = 0;
    unsigned int i;

E
Eric Blake 已提交
5257 5258
    virCheckFlags(0, -1);

5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273
    testDriverLock(driver);
    for (i = 0; i < driver->devs.count; i++)
        if ((cap == NULL) ||
            virNodeDeviceHasCap(driver->devs.objs[i], cap))
            ++ndevs;
    testDriverUnlock(driver);

    return ndevs;
}

static int
testNodeListDevices(virConnectPtr conn,
                    const char *cap,
                    char **const names,
                    int maxnames,
E
Eric Blake 已提交
5274
                    unsigned int flags)
5275 5276 5277 5278 5279
{
    testConnPtr driver = conn->privateData;
    int ndevs = 0;
    unsigned int i;

E
Eric Blake 已提交
5280 5281
    virCheckFlags(0, -1);

5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317
    testDriverLock(driver);
    for (i = 0; i < driver->devs.count && ndevs < maxnames; i++) {
        virNodeDeviceObjLock(driver->devs.objs[i]);
        if (cap == NULL ||
            virNodeDeviceHasCap(driver->devs.objs[i], cap)) {
            if ((names[ndevs++] = strdup(driver->devs.objs[i]->def->name)) == NULL) {
                virNodeDeviceObjUnlock(driver->devs.objs[i]);
                goto failure;
            }
        }
        virNodeDeviceObjUnlock(driver->devs.objs[i]);
    }
    testDriverUnlock(driver);

    return ndevs;

 failure:
    testDriverUnlock(driver);
    --ndevs;
    while (--ndevs >= 0)
        VIR_FREE(names[ndevs]);
    return -1;
}

static virNodeDevicePtr
testNodeDeviceLookupByName(virConnectPtr conn, const char *name)
{
    testConnPtr driver = conn->privateData;
    virNodeDeviceObjPtr obj;
    virNodeDevicePtr ret = NULL;

    testDriverLock(driver);
    obj = virNodeDeviceFindByName(&driver->devs, name);
    testDriverUnlock(driver);

    if (!obj) {
5318
        virReportError(VIR_ERR_NO_NODE_DEVICE, NULL);
5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330
        goto cleanup;
    }

    ret = virGetNodeDevice(conn, name);

cleanup:
    if (obj)
        virNodeDeviceObjUnlock(obj);
    return ret;
}

static char *
5331
testNodeDeviceGetXMLDesc(virNodeDevicePtr dev,
E
Eric Blake 已提交
5332
                         unsigned int flags)
5333 5334 5335 5336 5337
{
    testConnPtr driver = dev->conn->privateData;
    virNodeDeviceObjPtr obj;
    char *ret = NULL;

E
Eric Blake 已提交
5338 5339
    virCheckFlags(0, NULL);

5340 5341 5342 5343 5344
    testDriverLock(driver);
    obj = virNodeDeviceFindByName(&driver->devs, dev->name);
    testDriverUnlock(driver);

    if (!obj) {
5345 5346 5347
        virReportError(VIR_ERR_NO_NODE_DEVICE,
                       _("no node device with matching name '%s'"),
                       dev->name);
5348 5349 5350
        goto cleanup;
    }

5351
    ret = virNodeDeviceDefFormat(obj->def);
5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370

cleanup:
    if (obj)
        virNodeDeviceObjUnlock(obj);
    return ret;
}

static char *
testNodeDeviceGetParent(virNodeDevicePtr dev)
{
    testConnPtr driver = dev->conn->privateData;
    virNodeDeviceObjPtr obj;
    char *ret = NULL;

    testDriverLock(driver);
    obj = virNodeDeviceFindByName(&driver->devs, dev->name);
    testDriverUnlock(driver);

    if (!obj) {
5371 5372 5373
        virReportError(VIR_ERR_NO_NODE_DEVICE,
                       _("no node device with matching name '%s'"),
                       dev->name);
5374 5375 5376 5377 5378 5379
        goto cleanup;
    }

    if (obj->def->parent) {
        ret = strdup(obj->def->parent);
        if (!ret)
5380
            virReportOOMError();
5381
    } else {
5382 5383
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("no parent for this device"));
5384 5385 5386 5387 5388 5389 5390 5391
    }

cleanup:
    if (obj)
        virNodeDeviceObjUnlock(obj);
    return ret;
}

5392

5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406
static int
testNodeDeviceNumOfCaps(virNodeDevicePtr dev)
{
    testConnPtr driver = dev->conn->privateData;
    virNodeDeviceObjPtr obj;
    virNodeDevCapsDefPtr caps;
    int ncaps = 0;
    int ret = -1;

    testDriverLock(driver);
    obj = virNodeDeviceFindByName(&driver->devs, dev->name);
    testDriverUnlock(driver);

    if (!obj) {
5407 5408 5409
        virReportError(VIR_ERR_NO_NODE_DEVICE,
                       _("no node device with matching name '%s'"),
                       dev->name);
5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437
        goto cleanup;
    }

    for (caps = obj->def->caps; caps; caps = caps->next)
        ++ncaps;
    ret = ncaps;

cleanup:
    if (obj)
        virNodeDeviceObjUnlock(obj);
    return ret;
}


static int
testNodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames)
{
    testConnPtr driver = dev->conn->privateData;
    virNodeDeviceObjPtr obj;
    virNodeDevCapsDefPtr caps;
    int ncaps = 0;
    int ret = -1;

    testDriverLock(driver);
    obj = virNodeDeviceFindByName(&driver->devs, dev->name);
    testDriverUnlock(driver);

    if (!obj) {
5438 5439 5440
        virReportError(VIR_ERR_NO_NODE_DEVICE,
                       _("no node device with matching name '%s'"),
                       dev->name);
5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461
        goto cleanup;
    }

    for (caps = obj->def->caps; caps && ncaps < maxnames; caps = caps->next) {
        names[ncaps] = strdup(virNodeDevCapTypeToString(caps->type));
        if (names[ncaps++] == NULL)
            goto cleanup;
    }
    ret = ncaps;

cleanup:
    if (obj)
        virNodeDeviceObjUnlock(obj);
    if (ret == -1) {
        --ncaps;
        while (--ncaps >= 0)
            VIR_FREE(names[ncaps]);
    }
    return ret;
}

5462 5463 5464
static virNodeDevicePtr
testNodeDeviceCreateXML(virConnectPtr conn,
                        const char *xmlDesc,
E
Eric Blake 已提交
5465
                        unsigned int flags)
5466 5467 5468 5469 5470 5471 5472 5473 5474
{
    testConnPtr driver = conn->privateData;
    virNodeDeviceDefPtr def = NULL;
    virNodeDeviceObjPtr obj = NULL;
    char *wwnn = NULL, *wwpn = NULL;
    int parent_host = -1;
    virNodeDevicePtr dev = NULL;
    virNodeDevCapsDefPtr caps;

E
Eric Blake 已提交
5475 5476
    virCheckFlags(0, NULL);

5477 5478
    testDriverLock(driver);

5479
    def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, NULL);
5480 5481 5482 5483 5484
    if (def == NULL) {
        goto cleanup;
    }

    /* We run these next two simply for validation */
5485
    if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1) {
5486 5487 5488
        goto cleanup;
    }

5489
    if (virNodeDeviceGetParentHost(&driver->devs,
5490 5491 5492 5493 5494 5495 5496 5497 5498 5499
                                   def->name,
                                   def->parent,
                                   &parent_host) == -1) {
        goto cleanup;
    }

    /* 'name' is supposed to be filled in by the node device backend, which
     * we don't have. Use WWPN instead. */
    VIR_FREE(def->name);
    if (!(def->name = strdup(wwpn))) {
5500
        virReportOOMError();
5501 5502 5503 5504 5505 5506 5507 5508 5509 5510
        goto cleanup;
    }

    /* Fill in a random 'host' value, since this would also come from
     * the backend */
    caps = def->caps;
    while (caps) {
        if (caps->type != VIR_NODE_DEV_CAP_SCSI_HOST)
            continue;

5511
        caps->data.scsi_host.host = virRandomBits(10);
5512 5513 5514 5515
        caps = caps->next;
    }


5516
    if (!(obj = virNodeDeviceAssignDef(&driver->devs, def))) {
5517 5518 5519 5520 5521 5522 5523 5524
        goto cleanup;
    }
    virNodeDeviceObjUnlock(obj);

    dev = virGetNodeDevice(conn, def->name);
    def = NULL;
cleanup:
    testDriverUnlock(driver);
5525
    virNodeDeviceDefFree(def);
5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544
    VIR_FREE(wwnn);
    VIR_FREE(wwpn);
    return dev;
}

static int
testNodeDeviceDestroy(virNodeDevicePtr dev)
{
    int ret = 0;
    testConnPtr driver = dev->conn->privateData;
    virNodeDeviceObjPtr obj = NULL;
    char *parent_name = NULL, *wwnn = NULL, *wwpn = NULL;
    int parent_host = -1;

    testDriverLock(driver);
    obj = virNodeDeviceFindByName(&driver->devs, dev->name);
    testDriverUnlock(driver);

    if (!obj) {
5545
        virReportError(VIR_ERR_NO_NODE_DEVICE, NULL);
5546 5547 5548
        goto out;
    }

5549
    if (virNodeDeviceGetWWNs(obj->def, &wwnn, &wwpn) == -1) {
5550 5551 5552 5553 5554
        goto out;
    }

    parent_name = strdup(obj->def->parent);
    if (parent_name == NULL) {
5555
        virReportOOMError();
5556 5557 5558 5559 5560 5561 5562 5563 5564 5565
        goto out;
    }

    /* virNodeDeviceGetParentHost will cause the device object's lock to be
     * taken, so we have to dup the parent's name and drop the lock
     * before calling it.  We don't need the reference to the object
     * any more once we have the parent's name.  */
    virNodeDeviceObjUnlock(obj);

    /* We do this just for basic validation */
5566
    if (virNodeDeviceGetParentHost(&driver->devs,
5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585
                                   dev->name,
                                   parent_name,
                                   &parent_host) == -1) {
        obj = NULL;
        goto out;
    }

    virNodeDeviceObjLock(obj);
    virNodeDeviceObjRemove(&driver->devs, obj);

out:
    if (obj)
        virNodeDeviceObjUnlock(obj);
    VIR_FREE(parent_name);
    VIR_FREE(wwnn);
    VIR_FREE(wwpn);
    return ret;
}

5586 5587

/* Domain event implementations */
5588
static int
5589 5590 5591 5592
testDomainEventRegister(virConnectPtr conn,
                        virConnectDomainEventCallback callback,
                        void *opaque,
                        virFreeCallback freecb)
5593 5594 5595 5596 5597
{
    testConnPtr driver = conn->privateData;
    int ret;

    testDriverLock(driver);
5598 5599 5600
    ret = virDomainEventStateRegister(conn,
                                      driver->domainEventState,
                                      callback, opaque, freecb);
5601 5602 5603 5604 5605
    testDriverUnlock(driver);

    return ret;
}

5606

5607
static int
5608 5609
testDomainEventDeregister(virConnectPtr conn,
                          virConnectDomainEventCallback callback)
5610 5611 5612 5613 5614
{
    testConnPtr driver = conn->privateData;
    int ret;

    testDriverLock(driver);
5615 5616 5617
    ret = virDomainEventStateDeregister(conn,
                                        driver->domainEventState,
                                        callback);
5618 5619 5620 5621 5622
    testDriverUnlock(driver);

    return ret;
}

5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635

static int
testDomainEventRegisterAny(virConnectPtr conn,
                           virDomainPtr dom,
                           int eventID,
                           virConnectDomainEventGenericCallback callback,
                           void *opaque,
                           virFreeCallback freecb)
{
    testConnPtr driver = conn->privateData;
    int ret;

    testDriverLock(driver);
5636 5637 5638 5639
    if (virDomainEventStateRegisterID(conn,
                                      driver->domainEventState,
                                      dom, eventID,
                                      callback, opaque, freecb, &ret) < 0)
5640
        ret = -1;
5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653
    testDriverUnlock(driver);

    return ret;
}

static int
testDomainEventDeregisterAny(virConnectPtr conn,
                             int callbackID)
{
    testConnPtr driver = conn->privateData;
    int ret;

    testDriverLock(driver);
5654 5655 5656
    ret = virDomainEventStateDeregisterID(conn,
                                          driver->domainEventState,
                                          callbackID);
5657 5658 5659 5660 5661 5662
    testDriverUnlock(driver);

    return ret;
}


5663 5664 5665 5666
/* driver must be locked before calling */
static void testDomainEventQueue(testConnPtr driver,
                                 virDomainEventPtr event)
{
5667
    virDomainEventStateQueue(driver->domainEventState, event);
5668 5669
}

5670 5671
static virDrvOpenStatus testSecretOpen(virConnectPtr conn,
                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
5672 5673 5674 5675
                                       unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

5676 5677 5678
    if (STRNEQ(conn->driver->name, "Test"))
        return VIR_DRV_OPEN_DECLINED;

5679
    conn->secretPrivateData = conn->privateData;
5680 5681 5682 5683 5684 5685 5686
    return VIR_DRV_OPEN_SUCCESS;
}

static int testSecretClose(virConnectPtr conn) {
    conn->secretPrivateData = NULL;
    return 0;
}
5687

5688 5689 5690

static virDrvOpenStatus testNWFilterOpen(virConnectPtr conn,
                                         virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
5691 5692 5693 5694
                                         unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

5695 5696 5697
    if (STRNEQ(conn->driver->name, "Test"))
        return VIR_DRV_OPEN_DECLINED;

5698
    conn->nwfilterPrivateData = conn->privateData;
5699 5700 5701 5702 5703 5704 5705 5706
    return VIR_DRV_OPEN_SUCCESS;
}

static int testNWFilterClose(virConnectPtr conn) {
    conn->nwfilterPrivateData = NULL;
    return 0;
}

5707 5708 5709 5710 5711 5712 5713
static int testListAllDomains(virConnectPtr conn,
                              virDomainPtr **domains,
                              unsigned int flags)
{
    testConnPtr privconn = conn->privateData;
    int ret;

O
Osier Yang 已提交
5714
    virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
5715 5716

    testDriverLock(privconn);
5717
    ret = virDomainObjListExport(privconn->domains, conn, domains, flags);
5718 5719 5720 5721 5722
    testDriverUnlock(privconn);

    return ret;
}

5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752
static int
testNodeGetCPUMap(virConnectPtr conn,
                  unsigned char **cpumap,
                  unsigned int *online,
                  unsigned int flags)
{
    testConnPtr privconn = conn->privateData;
    int ret = -1;

    virCheckFlags(0, -1);

    testDriverLock(privconn);
    if (cpumap) {
        if (VIR_ALLOC_N(*cpumap, 1) < 0) {
            virReportOOMError();
            goto cleanup;
        }
        *cpumap[0] = 0x15;
    }

    if (online)
        *online = 3;

    ret = 8;

cleanup:
    testDriverUnlock(privconn);
    return ret;
}

5753

5754
static virDriver testDriver = {
5755 5756
    .no = VIR_DRV_TEST,
    .name = "Test",
5757 5758 5759 5760 5761 5762 5763 5764 5765
    .open = testOpen, /* 0.1.1 */
    .close = testClose, /* 0.1.1 */
    .version = testGetVersion, /* 0.1.1 */
    .getHostname = virGetHostname, /* 0.6.3 */
    .getMaxVcpus = testGetMaxVCPUs, /* 0.3.2 */
    .nodeGetInfo = testNodeGetInfo, /* 0.1.1 */
    .getCapabilities = testGetCapabilities, /* 0.2.1 */
    .listDomains = testListDomains, /* 0.1.1 */
    .numOfDomains = testNumOfDomains, /* 0.1.1 */
5766
    .listAllDomains = testListAllDomains, /* 0.9.13 */
5767 5768 5769 5770 5771 5772 5773
    .domainCreateXML = testDomainCreateXML, /* 0.1.4 */
    .domainLookupByID = testLookupDomainByID, /* 0.1.1 */
    .domainLookupByUUID = testLookupDomainByUUID, /* 0.1.1 */
    .domainLookupByName = testLookupDomainByName, /* 0.1.1 */
    .domainSuspend = testPauseDomain, /* 0.1.1 */
    .domainResume = testResumeDomain, /* 0.1.1 */
    .domainShutdown = testShutdownDomain, /* 0.1.1 */
5774
    .domainShutdownFlags = testShutdownDomainFlags, /* 0.9.10 */
5775 5776 5777 5778 5779 5780 5781 5782 5783
    .domainReboot = testRebootDomain, /* 0.1.1 */
    .domainDestroy = testDestroyDomain, /* 0.1.1 */
    .domainGetOSType = testGetOSType, /* 0.1.9 */
    .domainGetMaxMemory = testGetMaxMemory, /* 0.1.4 */
    .domainSetMaxMemory = testSetMaxMemory, /* 0.1.1 */
    .domainSetMemory = testSetMemory, /* 0.1.4 */
    .domainGetInfo = testGetDomainInfo, /* 0.1.1 */
    .domainGetState = testDomainGetState, /* 0.9.2 */
    .domainSave = testDomainSave, /* 0.3.2 */
5784
    .domainSaveFlags = testDomainSaveFlags, /* 0.9.4 */
5785
    .domainRestore = testDomainRestore, /* 0.3.2 */
5786
    .domainRestoreFlags = testDomainRestoreFlags, /* 0.9.4 */
5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800
    .domainCoreDump = testDomainCoreDump, /* 0.3.2 */
    .domainSetVcpus = testSetVcpus, /* 0.1.4 */
    .domainSetVcpusFlags = testDomainSetVcpusFlags, /* 0.8.5 */
    .domainGetVcpusFlags = testDomainGetVcpusFlags, /* 0.8.5 */
    .domainPinVcpu = testDomainPinVcpu, /* 0.7.3 */
    .domainGetVcpus = testDomainGetVcpus, /* 0.7.3 */
    .domainGetMaxVcpus = testDomainGetMaxVcpus, /* 0.7.3 */
    .domainGetXMLDesc = testDomainGetXMLDesc, /* 0.1.4 */
    .listDefinedDomains = testListDefinedDomains, /* 0.1.11 */
    .numOfDefinedDomains = testNumOfDefinedDomains, /* 0.1.11 */
    .domainCreate = testDomainCreate, /* 0.1.11 */
    .domainCreateWithFlags = testDomainCreateWithFlags, /* 0.8.2 */
    .domainDefineXML = testDomainDefineXML, /* 0.1.11 */
    .domainUndefine = testDomainUndefine, /* 0.1.11 */
5801
    .domainUndefineFlags = testDomainUndefineFlags, /* 0.9.4 */
5802 5803 5804 5805
    .domainGetAutostart = testDomainGetAutostart, /* 0.3.2 */
    .domainSetAutostart = testDomainSetAutostart, /* 0.3.2 */
    .domainGetSchedulerType = testDomainGetSchedulerType, /* 0.3.2 */
    .domainGetSchedulerParameters = testDomainGetSchedulerParams, /* 0.3.2 */
5806
    .domainGetSchedulerParametersFlags = testDomainGetSchedulerParamsFlags, /* 0.9.2 */
5807
    .domainSetSchedulerParameters = testDomainSetSchedulerParams, /* 0.3.2 */
5808
    .domainSetSchedulerParametersFlags = testDomainSetSchedulerParamsFlags, /* 0.9.2 */
5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820
    .domainBlockStats = testDomainBlockStats, /* 0.7.0 */
    .domainInterfaceStats = testDomainInterfaceStats, /* 0.7.0 */
    .nodeGetCellsFreeMemory = testNodeGetCellsFreeMemory, /* 0.4.2 */
    .domainEventRegister = testDomainEventRegister, /* 0.6.0 */
    .domainEventDeregister = testDomainEventDeregister, /* 0.6.0 */
    .isEncrypted = testIsEncrypted, /* 0.7.3 */
    .isSecure = testIsSecure, /* 0.7.3 */
    .domainIsActive = testDomainIsActive, /* 0.7.3 */
    .domainIsPersistent = testDomainIsPersistent, /* 0.7.3 */
    .domainIsUpdated = testDomainIsUpdated, /* 0.8.6 */
    .domainEventRegisterAny = testDomainEventRegisterAny, /* 0.8.0 */
    .domainEventDeregisterAny = testDomainEventDeregisterAny, /* 0.8.0 */
5821
    .isAlive = testIsAlive, /* 0.9.8 */
5822
    .nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */
5823 5824 5825 5826
};

static virNetworkDriver testNetworkDriver = {
    "Test",
5827 5828 5829 5830 5831 5832
    .open = testOpenNetwork, /* 0.3.2 */
    .close = testCloseNetwork, /* 0.3.2 */
    .numOfNetworks = testNumNetworks, /* 0.3.2 */
    .listNetworks = testListNetworks, /* 0.3.2 */
    .numOfDefinedNetworks = testNumDefinedNetworks, /* 0.3.2 */
    .listDefinedNetworks = testListDefinedNetworks, /* 0.3.2 */
5833
    .listAllNetworks = testNetworkListAllNetworks, /* 0.10.2 */
5834 5835 5836 5837 5838
    .networkLookupByUUID = testLookupNetworkByUUID, /* 0.3.2 */
    .networkLookupByName = testLookupNetworkByName, /* 0.3.2 */
    .networkCreateXML = testNetworkCreate, /* 0.3.2 */
    .networkDefineXML = testNetworkDefine, /* 0.3.2 */
    .networkUndefine = testNetworkUndefine, /* 0.3.2 */
5839
    .networkUpdate = testNetworkUpdate, /* 0.10.2 */
5840 5841 5842 5843 5844 5845 5846 5847
    .networkCreate = testNetworkStart, /* 0.3.2 */
    .networkDestroy = testNetworkDestroy, /* 0.3.2 */
    .networkGetXMLDesc = testNetworkGetXMLDesc, /* 0.3.2 */
    .networkGetBridgeName = testNetworkGetBridgeName, /* 0.3.2 */
    .networkGetAutostart = testNetworkGetAutostart, /* 0.3.2 */
    .networkSetAutostart = testNetworkSetAutostart, /* 0.3.2 */
    .networkIsActive = testNetworkIsActive, /* 0.7.3 */
    .networkIsPersistent = testNetworkIsPersistent, /* 0.7.3 */
5848 5849
};

L
Laine Stump 已提交
5850 5851
static virInterfaceDriver testInterfaceDriver = {
    "Test",                     /* name */
5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865
    .open = testOpenInterface, /* 0.7.0 */
    .close = testCloseInterface, /* 0.7.0 */
    .numOfInterfaces = testNumOfInterfaces, /* 0.7.0 */
    .listInterfaces = testListInterfaces, /* 0.7.0 */
    .numOfDefinedInterfaces = testNumOfDefinedInterfaces, /* 0.7.0 */
    .listDefinedInterfaces = testListDefinedInterfaces, /* 0.7.0 */
    .interfaceLookupByName = testLookupInterfaceByName, /* 0.7.0 */
    .interfaceLookupByMACString = testLookupInterfaceByMACString, /* 0.7.0 */
    .interfaceGetXMLDesc = testInterfaceGetXMLDesc, /* 0.7.0 */
    .interfaceDefineXML = testInterfaceDefineXML, /* 0.7.0 */
    .interfaceUndefine = testInterfaceUndefine, /* 0.7.0 */
    .interfaceCreate = testInterfaceCreate, /* 0.7.0 */
    .interfaceDestroy = testInterfaceDestroy, /* 0.7.0 */
    .interfaceIsActive = testInterfaceIsActive, /* 0.7.3 */
5866 5867 5868
    .interfaceChangeBegin = testInterfaceChangeBegin,   /* 0.9.2 */
    .interfaceChangeCommit = testInterfaceChangeCommit,  /* 0.9.2 */
    .interfaceChangeRollback = testInterfaceChangeRollback, /* 0.9.2 */
L
Laine Stump 已提交
5869 5870 5871
};


5872 5873
static virStorageDriver testStorageDriver = {
    .name = "Test",
5874 5875 5876 5877 5878 5879 5880
    .open = testStorageOpen, /* 0.4.1 */
    .close = testStorageClose, /* 0.4.1 */

    .numOfPools = testStorageNumPools, /* 0.5.0 */
    .listPools = testStorageListPools, /* 0.5.0 */
    .numOfDefinedPools = testStorageNumDefinedPools, /* 0.5.0 */
    .listDefinedPools = testStorageListDefinedPools, /* 0.5.0 */
5881
    .listAllPools = testStorageListAllPools, /* 0.10.2 */
5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899
    .findPoolSources = testStorageFindPoolSources, /* 0.5.0 */
    .poolLookupByName = testStoragePoolLookupByName, /* 0.5.0 */
    .poolLookupByUUID = testStoragePoolLookupByUUID, /* 0.5.0 */
    .poolLookupByVolume = testStoragePoolLookupByVolume, /* 0.5.0 */
    .poolCreateXML = testStoragePoolCreate, /* 0.5.0 */
    .poolDefineXML = testStoragePoolDefine, /* 0.5.0 */
    .poolBuild = testStoragePoolBuild, /* 0.5.0 */
    .poolUndefine = testStoragePoolUndefine, /* 0.5.0 */
    .poolCreate = testStoragePoolStart, /* 0.5.0 */
    .poolDestroy = testStoragePoolDestroy, /* 0.5.0 */
    .poolDelete = testStoragePoolDelete, /* 0.5.0 */
    .poolRefresh = testStoragePoolRefresh, /* 0.5.0 */
    .poolGetInfo = testStoragePoolGetInfo, /* 0.5.0 */
    .poolGetXMLDesc = testStoragePoolGetXMLDesc, /* 0.5.0 */
    .poolGetAutostart = testStoragePoolGetAutostart, /* 0.5.0 */
    .poolSetAutostart = testStoragePoolSetAutostart, /* 0.5.0 */
    .poolNumOfVolumes = testStoragePoolNumVolumes, /* 0.5.0 */
    .poolListVolumes = testStoragePoolListVolumes, /* 0.5.0 */
5900
    .poolListAllVolumes = testStoragePoolListAllVolumes, /* 0.10.2 */
5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912

    .volLookupByName = testStorageVolumeLookupByName, /* 0.5.0 */
    .volLookupByKey = testStorageVolumeLookupByKey, /* 0.5.0 */
    .volLookupByPath = testStorageVolumeLookupByPath, /* 0.5.0 */
    .volCreateXML = testStorageVolumeCreateXML, /* 0.5.0 */
    .volCreateXMLFrom = testStorageVolumeCreateXMLFrom, /* 0.6.4 */
    .volDelete = testStorageVolumeDelete, /* 0.5.0 */
    .volGetInfo = testStorageVolumeGetInfo, /* 0.5.0 */
    .volGetXMLDesc = testStorageVolumeGetXMLDesc, /* 0.5.0 */
    .volGetPath = testStorageVolumeGetPath, /* 0.5.0 */
    .poolIsActive = testStoragePoolIsActive, /* 0.7.3 */
    .poolIsPersistent = testStoragePoolIsPersistent, /* 0.7.3 */
5913 5914
};

5915 5916
static virDeviceMonitor testDevMonitor = {
    .name = "Test",
5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928
    .open = testDevMonOpen, /* 0.6.0 */
    .close = testDevMonClose, /* 0.6.0 */

    .numOfDevices = testNodeNumOfDevices, /* 0.7.2 */
    .listDevices = testNodeListDevices, /* 0.7.2 */
    .deviceLookupByName = testNodeDeviceLookupByName, /* 0.7.2 */
    .deviceGetXMLDesc = testNodeDeviceGetXMLDesc, /* 0.7.2 */
    .deviceGetParent = testNodeDeviceGetParent, /* 0.7.2 */
    .deviceNumOfCaps = testNodeDeviceNumOfCaps, /* 0.7.2 */
    .deviceListCaps = testNodeDeviceListCaps, /* 0.7.2 */
    .deviceCreateXML = testNodeDeviceCreateXML, /* 0.7.3 */
    .deviceDestroy = testNodeDeviceDestroy, /* 0.7.3 */
5929 5930
};

5931 5932
static virSecretDriver testSecretDriver = {
    .name = "Test",
5933 5934
    .open = testSecretOpen, /* 0.7.1 */
    .close = testSecretClose, /* 0.7.1 */
5935
};
5936 5937


5938 5939
static virNWFilterDriver testNWFilterDriver = {
    .name = "Test",
5940 5941
    .open = testNWFilterOpen, /* 0.8.0 */
    .close = testNWFilterClose, /* 0.8.0 */
5942 5943
};

5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955
/**
 * testRegister:
 *
 * Registers the test driver
 */
int
testRegister(void)
{
    if (virRegisterDriver(&testDriver) < 0)
        return -1;
    if (virRegisterNetworkDriver(&testNetworkDriver) < 0)
        return -1;
L
Laine Stump 已提交
5956 5957
    if (virRegisterInterfaceDriver(&testInterfaceDriver) < 0)
        return -1;
5958 5959
    if (virRegisterStorageDriver(&testStorageDriver) < 0)
        return -1;
5960 5961
    if (virRegisterDeviceMonitor(&testDevMonitor) < 0)
        return -1;
5962 5963
    if (virRegisterSecretDriver(&testSecretDriver) < 0)
        return -1;
5964 5965
    if (virRegisterNWFilterDriver(&testNWFilterDriver) < 0)
        return -1;
5966

5967 5968
    return 0;
}