xen_unified.c 21.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/*
 * xen_unified.c: Unified Xen driver.
 *
 * Copyright (C) 2007 Red Hat, Inc.
 *
 * See COPYING.LIB for the License of this software
 *
 * Richard W.M. Jones <rjones@redhat.com>
 */

#ifdef WITH_XEN

/* Note:
 *
 * This driver provides a unified interface to the five
 * separate underlying Xen drivers (xen_internal, proxy_internal,
 * xend_internal, xs_internal and xm_internal).  Historically
 * the body of libvirt.c handled the five Xen drivers,
 * and contained Xen-specific code.
 *
 * The interface between Xen drivers and xen_unified is
 * the same as for "ordinary" libvirt drivers (ie. virDriverPtr),
 * however this is just for convenience and may be changed
 * in future.  Libvirt.c should no longer call directly
 * to the five underlying Xen drivers.
 */

#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <xen/dom0_ops.h>

#include "internal.h"

#include "xen_unified.h"

#include "xen_internal.h"
#include "proxy_internal.h"
#include "xend_internal.h"
#include "xs_internal.h"
#include "xm_internal.h"

/* The five Xen drivers below us. */
44
static virDriverPtr drivers[XEN_UNIFIED_NR_DRIVERS] = {
45 46 47 48 49
    &xenHypervisorDriver,
    &xenProxyDriver,
    &xenDaemonDriver,
    &xenStoreDriver,
    &xenXMDriver
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
};
static const int hypervisor_offset = 0;
static const int proxy_offset = 1;

/**
 * xenUnifiedError:
 * @conn: the connection
 * @error: the error number
 * @info: extra information string
 *
 * Handle an error at the xend daemon interface
 */
static void
xenUnifiedError (virConnectPtr conn, virErrorNumber error, const char *info)
{
    const char *errmsg;

    errmsg = __virErrorMsg (error, info);
    __virRaiseError (conn, NULL, NULL, VIR_FROM_XEN, error, VIR_ERR_ERROR,
69
                     errmsg, info, NULL, 0, 0, errmsg, info);
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
}

/*----- Dispatch functions. -----*/

/* These dispatch functions follow the model used historically
 * by libvirt.c -- trying each low-level Xen driver in turn
 * until one succeeds.  However since we know what low-level
 * drivers can perform which functions, it is probably better
 * in future to optimise these dispatch functions to just call
 * the single function (or small number of appropriate functions)
 * in the low level drivers directly.
 */

static int
xenUnifiedOpen (virConnectPtr conn, const char *name, int flags)
{
86 87 88 89 90
    int i, j;
    xenUnifiedPrivatePtr priv;

    /* If name == NULL, name == "", or begins with "xen", then it's for us. */
    if (!name || name[0] == '\0')
91 92
        name = "Xen";
    if (strncasecmp (name, "Xen", 3) != 0)
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
        return VIR_DRV_OPEN_DECLINED;

    /* Allocate per-connection private data. */
    priv = malloc (sizeof *priv);
    if (!priv) {
        xenUnifiedError (conn, VIR_ERR_NO_MEMORY, "allocating private data");
        return VIR_DRV_OPEN_ERROR;
    }
    conn->privateData = priv;

    priv->handle = -1;
    priv->xendConfigVersion = -1;
    priv->type = -1;
    priv->len = -1;
    priv->addr = NULL;
    priv->xshandle = NULL;
    priv->proxy = -1;

111 112
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) {
        priv->opened[i] = 0;
113 114 115 116 117 118 119

        /* Ignore proxy for root */
        if (i == proxy_offset && getuid() == 0)
            continue;

        if (drivers[i]->open &&
            drivers[i]->open (conn, name, flags) == VIR_DRV_OPEN_SUCCESS)
120
            priv->opened[i] = 1;
121 122 123

        /* If as root, then all drivers must succeed.
           If non-root, then only proxy must succeed */
124
        if (!priv->opened[i] && (getuid() == 0 || i == proxy_offset)) {
125
            for (j = 0; j < i; ++j)
126
                if (priv->opened[j]) drivers[j]->close (conn);
127 128
            return VIR_DRV_OPEN_ERROR;
        }
129 130
    }

131
    return VIR_DRV_OPEN_SUCCESS;
132 133
}

134 135 136
#define GET_PRIVATE(conn) \
    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) (conn)->privateData

137 138 139
static int
xenUnifiedClose (virConnectPtr conn)
{
140
    GET_PRIVATE(conn);
141
    int i;
142

143 144
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->close)
145
            (void) drivers[i]->close (conn);
146

147 148
    free (conn->privateData);
    conn->privateData = NULL;
149

150
    return 0;
151 152 153 154 155
}

static const char *
xenUnifiedType (virConnectPtr conn)
{
156
    GET_PRIVATE(conn);
157 158
    int i;
    const char *ret;
159

160 161
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->type) {
162 163 164
            ret = drivers[i]->type (conn);
            if (ret) return ret;
        }
165

166
    return NULL;
167 168 169 170 171
}

static int
xenUnifiedVersion (virConnectPtr conn, unsigned long *hvVer)
{
172
    GET_PRIVATE(conn);
173
    int i;
174

175 176 177
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->version &&
178 179
            drivers[i]->version (conn, hvVer) == 0)
            return 0;
180

181
    return -1;
182 183 184 185 186
}

static int
xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
{
187
    GET_PRIVATE(conn);
188
    int i;
189

190 191
    if (!type)
        type = "Xen";
192

193 194
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && strcmp (drivers[i]->name, type) == 0)
195
            return drivers[i]->getMaxVcpus (conn, type);
196

197
    return -1;
198 199 200 201 202
}

static int
xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info)
{
203
    GET_PRIVATE(conn);
204
    int i;
205

206 207 208
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->nodeGetInfo &&
209 210
            drivers[i]->nodeGetInfo (conn, info) == 0)
            return 0;
211

212
    return -1;
213 214 215 216 217
}

static char *
xenUnifiedGetCapabilities (virConnectPtr conn)
{
218
    GET_PRIVATE(conn);
219 220
    int i;
    char *ret;
221

222 223
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->getCapabilities) {
224 225 226
            ret = drivers[i]->getCapabilities (conn);
            if (ret) return ret;
        }
227

228
    return NULL;
229 230 231 232 233
}

static int
xenUnifiedListDomains (virConnectPtr conn, int *ids, int maxids)
{
234
    GET_PRIVATE(conn);
235
    int i, ret;
236

237 238
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->listDomains) {
239 240 241
            ret = drivers[i]->listDomains (conn, ids, maxids);
            if (ret >= 0) return ret;
        }
242

243
    return -1;
244 245 246 247 248
}

static int
xenUnifiedNumOfDomains (virConnectPtr conn)
{
249
    GET_PRIVATE(conn);
250
    int i, ret;
251

252 253
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->numOfDomains) {
254 255 256
            ret = drivers[i]->numOfDomains (conn);
            if (ret >= 0) return ret;
        }
257

258
    return -1;
259 260 261 262
}

static virDomainPtr
xenUnifiedDomainCreateLinux (virConnectPtr conn,
263
                             const char *xmlDesc, unsigned int flags)
264
{
265
    GET_PRIVATE(conn);
266 267
    int i;
    virDomainPtr ret;
268

269 270
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainCreateLinux) {
271 272 273
            ret = drivers[i]->domainCreateLinux (conn, xmlDesc, flags);
            if (ret) return ret;
        }
274

275
    return NULL;
276 277 278 279 280
}

static virDomainPtr
xenUnifiedDomainLookupByID (virConnectPtr conn, int id)
{
281
    GET_PRIVATE(conn);
282 283
    int i;
    virDomainPtr ret;
284

285 286
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainLookupByID) {
287 288 289
            ret = drivers[i]->domainLookupByID (conn, id);
            if (ret) return ret;
        }
290

291
    return NULL;
292 293 294 295
}

static virDomainPtr
xenUnifiedDomainLookupByUUID (virConnectPtr conn,
296
                              const unsigned char *uuid)
297
{
298
    GET_PRIVATE(conn);
299 300
    int i;
    virDomainPtr ret;
301

302 303
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainLookupByUUID) {
304 305 306
            ret = drivers[i]->domainLookupByUUID (conn, uuid);
            if (ret) return ret;
        }
307

308
    return NULL;
309 310 311 312
}

static virDomainPtr
xenUnifiedDomainLookupByName (virConnectPtr conn,
313
                              const char *name)
314
{
315
    GET_PRIVATE(conn);
316 317
    int i;
    virDomainPtr ret;
318

319 320
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainLookupByName) {
321 322 323
            ret = drivers[i]->domainLookupByName (conn, name);
            if (ret) return ret;
        }
324

325
    return NULL;
326 327 328 329 330
}

static int
xenUnifiedDomainSuspend (virDomainPtr dom)
{
331
    GET_PRIVATE(dom->conn);
332
    int i;
333

334 335 336
    /* Try non-hypervisor methods first, then hypervisor direct method
     * as a last resort.
     */
337
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
338
        if (i != hypervisor_offset &&
339
            priv->opened[i] &&
340 341 342
            drivers[i]->domainSuspend &&
            drivers[i]->domainSuspend (dom) == 0)
            return 0;
343

344 345
    if (priv->opened[hypervisor_offset] &&
        drivers[hypervisor_offset]->domainSuspend &&
346 347
        drivers[hypervisor_offset]->domainSuspend (dom) == 0)
        return 0;
348

349
    return -1;
350 351 352 353 354
}

static int
xenUnifiedDomainResume (virDomainPtr dom)
{
355
    GET_PRIVATE(dom->conn);
356
    int i;
357

358 359 360
    /* Try non-hypervisor methods first, then hypervisor direct method
     * as a last resort.
     */
361
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
362
        if (i != hypervisor_offset &&
363
            priv->opened[i] &&
364 365 366
            drivers[i]->domainResume &&
            drivers[i]->domainResume (dom) == 0)
            return 0;
367

368 369
    if (priv->opened[hypervisor_offset] &&
        drivers[hypervisor_offset]->domainResume &&
370 371
        drivers[hypervisor_offset]->domainResume (dom) == 0)
        return 0;
372

373
    return -1;
374 375 376 377 378
}

static int
xenUnifiedDomainShutdown (virDomainPtr dom)
{
379
    GET_PRIVATE(dom->conn);
380
    int i;
381

382 383 384
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainShutdown &&
385 386
            drivers[i]->domainShutdown (dom) == 0)
            return 0;
387

388
    return -1;
389 390 391 392 393
}

static int
xenUnifiedDomainReboot (virDomainPtr dom, unsigned int flags)
{
394
    GET_PRIVATE(dom->conn);
395
    int i;
396

397 398 399
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainReboot &&
400 401
            drivers[i]->domainReboot (dom, flags) == 0)
            return 0;
402

403
    return -1;
404 405 406 407 408
}

static int
xenUnifiedDomainDestroy (virDomainPtr dom)
{
409
    GET_PRIVATE(dom->conn);
410
    int i;
411

412 413 414
    /* Try non-hypervisor methods first, then hypervisor direct method
     * as a last resort.
     */
415
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
416
        if (i != hypervisor_offset &&
417
            priv->opened[i] &&
418 419 420
            drivers[i]->domainDestroy &&
            drivers[i]->domainDestroy (dom) == 0)
            return 0;
421

422 423
    if (priv->opened[i] &&
        drivers[hypervisor_offset]->domainDestroy &&
424 425
        drivers[hypervisor_offset]->domainDestroy (dom) == 0)
        return 0;
426

427
    return -1;
428 429 430 431 432
}

static char *
xenUnifiedDomainGetOSType (virDomainPtr dom)
{
433
    GET_PRIVATE(dom->conn);
434 435
    int i;
    char *ret;
436

437 438
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetOSType) {
439 440 441
            ret = drivers[i]->domainGetOSType (dom);
            if (ret) return ret;
        }
442

443
    return NULL;
444 445 446 447 448
}

static unsigned long
xenUnifiedDomainGetMaxMemory (virDomainPtr dom)
{
449
    GET_PRIVATE(dom->conn);
450 451
    int i;
    unsigned long ret;
452

453 454
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetMaxMemory) {
455 456 457
            ret = drivers[i]->domainGetMaxMemory (dom);
            if (ret != 0) return ret;
        }
458

459
    return 0;
460 461 462 463 464
}

static int
xenUnifiedDomainSetMaxMemory (virDomainPtr dom, unsigned long memory)
{
465
    GET_PRIVATE(dom->conn);
466
    int i;
467

468 469 470
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainSetMaxMemory &&
471 472
            drivers[i]->domainSetMaxMemory (dom, memory) == 0)
            return 0;
473

474
    return -1;
475 476 477 478 479
}

static int
xenUnifiedDomainSetMemory (virDomainPtr dom, unsigned long memory)
{
480
    GET_PRIVATE(dom->conn);
481
    int i;
482

483 484 485
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainSetMemory &&
486 487
            drivers[i]->domainSetMemory (dom, memory) == 0)
            return 0;
488

489
    return -1;
490 491 492 493 494
}

static int
xenUnifiedDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
{
495
    GET_PRIVATE(dom->conn);
496
    int i;
497

498 499 500
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainGetInfo &&
501 502
            drivers[i]->domainGetInfo (dom, info) == 0)
            return 0;
503

504
    return -1;
505 506 507 508 509
}

static int
xenUnifiedDomainSave (virDomainPtr dom, const char *to)
{
510
    GET_PRIVATE(dom->conn);
511
    int i;
512

513 514 515
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainSave &&
516 517
            drivers[i]->domainSave (dom, to) == 0)
            return 0;
518

519
    return -1;
520 521 522 523 524
}

static int
xenUnifiedDomainRestore (virConnectPtr conn, const char *from)
{
525
    GET_PRIVATE(conn);
526
    int i;
527

528 529 530
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainRestore &&
531 532
            drivers[i]->domainRestore (conn, from) == 0)
            return 0;
533

534
    return -1;
535 536 537 538 539
}

static int
xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
{
540
    GET_PRIVATE(dom->conn);
541
    int i;
542

543 544 545
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainCoreDump &&
546 547
            drivers[i]->domainCoreDump (dom, to, flags) == 0)
            return 0;
548

549
    return -1;
550 551 552 553 554
}

static int
xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
{
555
    GET_PRIVATE(dom->conn);
556
    int i;
557

558 559 560
    /* Try non-hypervisor methods first, then hypervisor direct method
     * as a last resort.
     */
561
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
562
        if (i != hypervisor_offset &&
563
            priv->opened[i] &&
564 565 566
            drivers[i]->domainSetVcpus &&
            drivers[i]->domainSetVcpus (dom, nvcpus) == 0)
            return 0;
567

568 569
    if (priv->opened[hypervisor_offset] &&
        drivers[hypervisor_offset]->domainSetVcpus &&
570 571
        drivers[hypervisor_offset]->domainSetVcpus (dom, nvcpus) == 0)
        return 0;
572

573
    return -1;
574 575 576 577
}

static int
xenUnifiedDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
578
                         unsigned char *cpumap, int maplen)
579
{
580
    GET_PRIVATE(dom->conn);
581
    int i;
582

583 584 585
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainPinVcpu &&
586 587
            drivers[i]->domainPinVcpu (dom, vcpu, cpumap, maplen) == 0)
            return 0;
588

589
    return -1;
590 591 592 593
}

static int
xenUnifiedDomainGetVcpus (virDomainPtr dom,
594 595
                          virVcpuInfoPtr info, int maxinfo,
                          unsigned char *cpumaps, int maplen)
596
{
597
    GET_PRIVATE(dom->conn);
598
    int i, ret;
599

600 601
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetVcpus) {
602 603 604 605
            ret = drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen);
            if (ret > 0)
                return ret;
        }
606
    return -1;
607 608 609 610 611
}

static int
xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
{
612
    GET_PRIVATE(dom->conn);
613
    int i, ret;
614

615 616
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
617 618 619
            ret = drivers[i]->domainGetMaxVcpus (dom);
            if (ret != 0) return ret;
        }
620

621
    return -1;
622 623 624 625 626
}

static char *
xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
{
627
    GET_PRIVATE(dom->conn);
628 629
    int i;
    char *ret;
630

631 632
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainDumpXML) {
633 634 635
            ret = drivers[i]->domainDumpXML (dom, flags);
            if (ret) return ret;
        }
636

637
    return NULL;
638 639 640 641
}

static int
xenUnifiedListDefinedDomains (virConnectPtr conn, char **const names,
642
                              int maxnames)
643
{
644
    GET_PRIVATE(conn);
645 646
    int i;
    int ret;
647

648 649
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->listDefinedDomains) {
650 651 652
            ret = drivers[i]->listDefinedDomains (conn, names, maxnames);
            if (ret >= 0) return ret;
        }
653

654
    return -1;
655 656 657 658 659
}

static int
xenUnifiedNumOfDefinedDomains (virConnectPtr conn)
{
660
    GET_PRIVATE(conn);
661 662
    int i;
    int ret;
663

664 665
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->numOfDefinedDomains) {
666 667 668
            ret = drivers[i]->numOfDefinedDomains (conn);
            if (ret >= 0) return ret;
        }
669

670
    return -1;
671 672 673 674 675
}

static int
xenUnifiedDomainCreate (virDomainPtr dom)
{
676
    GET_PRIVATE(dom->conn);
677
    int i;
678

679 680
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainCreate &&
681 682
            drivers[i]->domainCreate (dom) == 0)
            return 0;
683

684
    return -1;
685 686 687 688 689
}

static virDomainPtr
xenUnifiedDomainDefineXML (virConnectPtr conn, const char *xml)
{
690
    GET_PRIVATE(conn);
691 692
    int i;
    virDomainPtr ret;
693

694 695
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainDefineXML) {
696 697 698
            ret = drivers[i]->domainDefineXML (conn, xml);
            if (ret) return ret;
        }
699

700
    return NULL;
701 702 703 704 705
}

static int
xenUnifiedDomainUndefine (virDomainPtr dom)
{
706
    GET_PRIVATE(dom->conn);
707
    int i;
708

709 710
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainUndefine &&
711 712
            drivers[i]->domainUndefine (dom) == 0)
            return 0;
713

714
    return -1;
715 716 717 718 719
}

static int
xenUnifiedDomainAttachDevice (virDomainPtr dom, char *xml)
{
720
    GET_PRIVATE(dom->conn);
721
    int i;
722

723 724
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainAttachDevice &&
725 726
            drivers[i]->domainAttachDevice (dom, xml) == 0)
            return 0;
727

728
    return -1;
729 730 731 732 733
}

static int
xenUnifiedDomainDetachDevice (virDomainPtr dom, char *xml)
{
734
    GET_PRIVATE(dom->conn);
735
    int i;
736

737 738
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainDetachDevice &&
739 740
            drivers[i]->domainDetachDevice (dom, xml) == 0)
            return 0;
741

742
    return -1;
743 744 745 746 747
}

static int
xenUnifiedDomainGetAutostart (virDomainPtr dom, int *autostart)
{
748
    GET_PRIVATE(dom->conn);
749
    int i;
750

751 752
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetAutostart &&
753 754
            drivers[i]->domainGetAutostart (dom, autostart) == 0)
            return 0;
755

756
    return -1;
757 758 759 760 761
}

static int
xenUnifiedDomainSetAutostart (virDomainPtr dom, int autostart)
{
762
    GET_PRIVATE(dom->conn);
763
    int i;
764

765 766
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainSetAutostart &&
767 768
            drivers[i]->domainSetAutostart (dom, autostart) == 0)
            return 0;
769

770
    return -1;
771 772 773 774
}

/*----- Register with libvirt.c, and initialise Xen drivers. -----*/

775 776 777
#define VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 +         \
                 ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +	\
                 (DOM0_INTERFACE_VERSION & 0xFFFF))
778 779 780

/* The interface which we export upwards to libvirt.c. */
static virDriver xenUnifiedDriver = {
781
    .no = VIR_DRV_XEN_UNIFIED,
782
    .name = "Xen",
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
    .ver = VERSION,
    .open 			= xenUnifiedOpen,
    .close 			= xenUnifiedClose,
    .type 			= xenUnifiedType,
    .version 			= xenUnifiedVersion,
    .getMaxVcpus 			= xenUnifiedGetMaxVcpus,
    .nodeGetInfo 			= xenUnifiedNodeGetInfo,
    .getCapabilities 		= xenUnifiedGetCapabilities,
    .listDomains 			= xenUnifiedListDomains,
    .numOfDomains 		= xenUnifiedNumOfDomains,
    .domainCreateLinux 		= xenUnifiedDomainCreateLinux,
    .domainLookupByID 		= xenUnifiedDomainLookupByID,
    .domainLookupByUUID 		= xenUnifiedDomainLookupByUUID,
    .domainLookupByName 		= xenUnifiedDomainLookupByName,
    .domainSuspend 		= xenUnifiedDomainSuspend,
    .domainResume 		= xenUnifiedDomainResume,
    .domainShutdown 		= xenUnifiedDomainShutdown,
    .domainReboot 		= xenUnifiedDomainReboot,
    .domainDestroy 		= xenUnifiedDomainDestroy,
    .domainGetOSType 		= xenUnifiedDomainGetOSType,
    .domainGetMaxMemory 		= xenUnifiedDomainGetMaxMemory,
    .domainSetMaxMemory 		= xenUnifiedDomainSetMaxMemory,
    .domainSetMemory 		= xenUnifiedDomainSetMemory,
    .domainGetInfo 		= xenUnifiedDomainGetInfo,
    .domainSave 			= xenUnifiedDomainSave,
    .domainRestore 		= xenUnifiedDomainRestore,
    .domainCoreDump 		= xenUnifiedDomainCoreDump,
    .domainSetVcpus 		= xenUnifiedDomainSetVcpus,
    .domainPinVcpu 		= xenUnifiedDomainPinVcpu,
    .domainGetVcpus 		= xenUnifiedDomainGetVcpus,
    .domainGetMaxVcpus 		= xenUnifiedDomainGetMaxVcpus,
    .domainDumpXML 		= xenUnifiedDomainDumpXML,
    .listDefinedDomains 		= xenUnifiedListDefinedDomains,
    .numOfDefinedDomains 		= xenUnifiedNumOfDefinedDomains,
    .domainCreate 		= xenUnifiedDomainCreate,
    .domainDefineXML 		= xenUnifiedDomainDefineXML,
    .domainUndefine 		= xenUnifiedDomainUndefine,
    .domainAttachDevice 		= xenUnifiedDomainAttachDevice,
    .domainDetachDevice 		= xenUnifiedDomainDetachDevice,
    .domainGetAutostart 		= xenUnifiedDomainGetAutostart,
    .domainSetAutostart 		= xenUnifiedDomainSetAutostart,
824 825
};

826 827 828 829 830 831 832
/**
 * xenUnifiedRegister:
 *
 * Register xen related drivers
 *
 * Returns the driver priority or -1 in case of error.
 */
833 834 835
int
xenUnifiedRegister (void)
{
836 837 838 839 840 841
    /* Ignore failures here. */
    (void) xenHypervisorInit ();
    (void) xenProxyInit ();
    (void) xenDaemonInit ();
    (void) xenStoreInit ();
    (void) xenXMInit ();
842

843
    return virRegisterDriver (&xenUnifiedDriver);
844 845 846
}

#endif /* WITH_XEN */
847 848 849 850 851 852 853 854 855 856 857 858 859 860

/*
 * vim: set tabstop=4:
 * vim: set shiftwidth=4:
 * vim: set expandtab:
 */
/*
 * Local variables:
 *  indent-tabs-mode: nil
 *  c-indent-level: 4
 *  c-basic-offset: 4
 *  tab-width: 4
 * End:
 */