xen_unified.c 22.9 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
        return VIR_DRV_OPEN_DECLINED;

    /* Allocate per-connection private data. */
    priv = malloc (sizeof *priv);
    if (!priv) {
98
        xenUnifiedError (NULL, VIR_ERR_NO_MEMORY, "allocating private data");
99 100 101 102 103 104 105 106 107 108 109 110
        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
        /* Only use XM driver for Xen <= 3.0.3 (ie xendConfigVersion <= 2) */
        if (drivers[i] == &xenXMDriver &&
            priv->xendConfigVersion > 2)
            continue;

119 120 121 122 123 124
        /* 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)
125
            priv->opened[i] = 1;
126 127 128

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

136
    return VIR_DRV_OPEN_SUCCESS;
137 138
}

139 140 141
#define GET_PRIVATE(conn) \
    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) (conn)->privateData

142 143 144
static int
xenUnifiedClose (virConnectPtr conn)
{
145
    GET_PRIVATE(conn);
146
    int i;
147

148 149
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->close)
150
            (void) drivers[i]->close (conn);
151

152 153
    free (conn->privateData);
    conn->privateData = NULL;
154

155
    return 0;
156 157 158 159 160
}

static const char *
xenUnifiedType (virConnectPtr conn)
{
161
    GET_PRIVATE(conn);
162 163
    int i;
    const char *ret;
164

165 166
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->type) {
167 168 169
            ret = drivers[i]->type (conn);
            if (ret) return ret;
        }
170

171
    return NULL;
172 173 174 175 176
}

static int
xenUnifiedVersion (virConnectPtr conn, unsigned long *hvVer)
{
177
    GET_PRIVATE(conn);
178
    int i;
179

180 181 182
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->version &&
183 184
            drivers[i]->version (conn, hvVer) == 0)
            return 0;
185

186
    return -1;
187 188 189 190 191
}

static int
xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
{
192
    GET_PRIVATE(conn);
193
    int i;
194

195 196
    if (!type)
        type = "Xen";
197

198 199
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && strcmp (drivers[i]->name, type) == 0)
200
            return drivers[i]->getMaxVcpus (conn, type);
201

202
    return -1;
203 204 205 206 207
}

static int
xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info)
{
208
    GET_PRIVATE(conn);
209
    int i;
210

211 212 213
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->nodeGetInfo &&
214 215
            drivers[i]->nodeGetInfo (conn, info) == 0)
            return 0;
216

217
    return -1;
218 219 220 221 222
}

static char *
xenUnifiedGetCapabilities (virConnectPtr conn)
{
223
    GET_PRIVATE(conn);
224 225
    int i;
    char *ret;
226

227 228
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->getCapabilities) {
229 230 231
            ret = drivers[i]->getCapabilities (conn);
            if (ret) return ret;
        }
232

233
    return NULL;
234 235 236 237 238
}

static int
xenUnifiedListDomains (virConnectPtr conn, int *ids, int maxids)
{
239
    GET_PRIVATE(conn);
240
    int i, ret;
241

242 243
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->listDomains) {
244 245 246
            ret = drivers[i]->listDomains (conn, ids, maxids);
            if (ret >= 0) return ret;
        }
247

248
    return -1;
249 250 251 252 253
}

static int
xenUnifiedNumOfDomains (virConnectPtr conn)
{
254
    GET_PRIVATE(conn);
255
    int i, ret;
256

257 258
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->numOfDomains) {
259 260 261
            ret = drivers[i]->numOfDomains (conn);
            if (ret >= 0) return ret;
        }
262

263
    return -1;
264 265 266 267
}

static virDomainPtr
xenUnifiedDomainCreateLinux (virConnectPtr conn,
268
                             const char *xmlDesc, unsigned int flags)
269
{
270
    GET_PRIVATE(conn);
271 272
    int i;
    virDomainPtr ret;
273

274 275
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainCreateLinux) {
276 277 278
            ret = drivers[i]->domainCreateLinux (conn, xmlDesc, flags);
            if (ret) return ret;
        }
279

280
    return NULL;
281 282 283 284 285
}

static virDomainPtr
xenUnifiedDomainLookupByID (virConnectPtr conn, int id)
{
286
    GET_PRIVATE(conn);
287 288
    int i;
    virDomainPtr ret;
289

290 291
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainLookupByID) {
292 293 294
            ret = drivers[i]->domainLookupByID (conn, id);
            if (ret) return ret;
        }
295

296
    return NULL;
297 298 299 300
}

static virDomainPtr
xenUnifiedDomainLookupByUUID (virConnectPtr conn,
301
                              const unsigned char *uuid)
302
{
303
    GET_PRIVATE(conn);
304 305
    int i;
    virDomainPtr ret;
306

307 308
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainLookupByUUID) {
309 310 311
            ret = drivers[i]->domainLookupByUUID (conn, uuid);
            if (ret) return ret;
        }
312

313
    return NULL;
314 315 316 317
}

static virDomainPtr
xenUnifiedDomainLookupByName (virConnectPtr conn,
318
                              const char *name)
319
{
320
    GET_PRIVATE(conn);
321 322
    int i;
    virDomainPtr ret;
323

324 325
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainLookupByName) {
326 327 328
            ret = drivers[i]->domainLookupByName (conn, name);
            if (ret) return ret;
        }
329

330
    return NULL;
331 332 333 334 335
}

static int
xenUnifiedDomainSuspend (virDomainPtr dom)
{
336
    GET_PRIVATE(dom->conn);
337
    int i;
338

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

349 350
    if (priv->opened[hypervisor_offset] &&
        drivers[hypervisor_offset]->domainSuspend &&
351 352
        drivers[hypervisor_offset]->domainSuspend (dom) == 0)
        return 0;
353

354
    return -1;
355 356 357 358 359
}

static int
xenUnifiedDomainResume (virDomainPtr dom)
{
360
    GET_PRIVATE(dom->conn);
361
    int i;
362

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

373 374
    if (priv->opened[hypervisor_offset] &&
        drivers[hypervisor_offset]->domainResume &&
375 376
        drivers[hypervisor_offset]->domainResume (dom) == 0)
        return 0;
377

378
    return -1;
379 380 381 382 383
}

static int
xenUnifiedDomainShutdown (virDomainPtr dom)
{
384
    GET_PRIVATE(dom->conn);
385
    int i;
386

387 388 389
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainShutdown &&
390 391
            drivers[i]->domainShutdown (dom) == 0)
            return 0;
392

393
    return -1;
394 395 396 397 398
}

static int
xenUnifiedDomainReboot (virDomainPtr dom, unsigned int flags)
{
399
    GET_PRIVATE(dom->conn);
400
    int i;
401

402 403 404
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainReboot &&
405 406
            drivers[i]->domainReboot (dom, flags) == 0)
            return 0;
407

408
    return -1;
409 410 411 412 413
}

static int
xenUnifiedDomainDestroy (virDomainPtr dom)
{
414
    GET_PRIVATE(dom->conn);
415
    int i;
416

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

427 428
    if (priv->opened[i] &&
        drivers[hypervisor_offset]->domainDestroy &&
429 430
        drivers[hypervisor_offset]->domainDestroy (dom) == 0)
        return 0;
431

432
    return -1;
433 434 435 436 437
}

static char *
xenUnifiedDomainGetOSType (virDomainPtr dom)
{
438
    GET_PRIVATE(dom->conn);
439 440
    int i;
    char *ret;
441

442 443
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetOSType) {
444 445 446
            ret = drivers[i]->domainGetOSType (dom);
            if (ret) return ret;
        }
447

448
    return NULL;
449 450 451 452 453
}

static unsigned long
xenUnifiedDomainGetMaxMemory (virDomainPtr dom)
{
454
    GET_PRIVATE(dom->conn);
455 456
    int i;
    unsigned long ret;
457

458 459
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetMaxMemory) {
460 461 462
            ret = drivers[i]->domainGetMaxMemory (dom);
            if (ret != 0) return ret;
        }
463

464
    return 0;
465 466 467 468 469
}

static int
xenUnifiedDomainSetMaxMemory (virDomainPtr dom, unsigned long memory)
{
470
    GET_PRIVATE(dom->conn);
471
    int i;
472

473 474 475
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainSetMaxMemory &&
476 477
            drivers[i]->domainSetMaxMemory (dom, memory) == 0)
            return 0;
478

479
    return -1;
480 481 482 483 484
}

static int
xenUnifiedDomainSetMemory (virDomainPtr dom, unsigned long memory)
{
485
    GET_PRIVATE(dom->conn);
486
    int i;
487

488 489 490
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainSetMemory &&
491 492
            drivers[i]->domainSetMemory (dom, memory) == 0)
            return 0;
493

494
    return -1;
495 496 497 498 499
}

static int
xenUnifiedDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
{
500
    GET_PRIVATE(dom->conn);
501
    int i;
502

503 504 505
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainGetInfo &&
506 507
            drivers[i]->domainGetInfo (dom, info) == 0)
            return 0;
508

509
    return -1;
510 511 512 513 514
}

static int
xenUnifiedDomainSave (virDomainPtr dom, const char *to)
{
515
    GET_PRIVATE(dom->conn);
516
    int i;
517

518 519 520
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainSave &&
521 522
            drivers[i]->domainSave (dom, to) == 0)
            return 0;
523

524
    return -1;
525 526 527 528 529
}

static int
xenUnifiedDomainRestore (virConnectPtr conn, const char *from)
{
530
    GET_PRIVATE(conn);
531
    int i;
532

533 534 535
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainRestore &&
536 537
            drivers[i]->domainRestore (conn, from) == 0)
            return 0;
538

539
    return -1;
540 541 542 543 544
}

static int
xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
{
545
    GET_PRIVATE(dom->conn);
546
    int i;
547

548 549 550
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainCoreDump &&
551 552
            drivers[i]->domainCoreDump (dom, to, flags) == 0)
            return 0;
553

554
    return -1;
555 556 557 558 559
}

static int
xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
{
560
    GET_PRIVATE(dom->conn);
561
    int i;
562

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

573 574
    if (priv->opened[hypervisor_offset] &&
        drivers[hypervisor_offset]->domainSetVcpus &&
575 576
        drivers[hypervisor_offset]->domainSetVcpus (dom, nvcpus) == 0)
        return 0;
577

578
    return -1;
579 580 581 582
}

static int
xenUnifiedDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
583
                         unsigned char *cpumap, int maplen)
584
{
585
    GET_PRIVATE(dom->conn);
586
    int i;
587

588 589 590
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] &&
            drivers[i]->domainPinVcpu &&
591 592
            drivers[i]->domainPinVcpu (dom, vcpu, cpumap, maplen) == 0)
            return 0;
593

594
    return -1;
595 596 597 598
}

static int
xenUnifiedDomainGetVcpus (virDomainPtr dom,
599 600
                          virVcpuInfoPtr info, int maxinfo,
                          unsigned char *cpumaps, int maplen)
601
{
602
    GET_PRIVATE(dom->conn);
603
    int i, ret;
604

605 606
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetVcpus) {
607 608 609 610
            ret = drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen);
            if (ret > 0)
                return ret;
        }
611
    return -1;
612 613 614 615 616
}

static int
xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
{
617
    GET_PRIVATE(dom->conn);
618
    int i, ret;
619

620 621
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
622 623 624
            ret = drivers[i]->domainGetMaxVcpus (dom);
            if (ret != 0) return ret;
        }
625

626
    return -1;
627 628 629 630 631
}

static char *
xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
{
632
    GET_PRIVATE(dom->conn);
633 634
    int i;
    char *ret;
635

636 637
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainDumpXML) {
638 639 640
            ret = drivers[i]->domainDumpXML (dom, flags);
            if (ret) return ret;
        }
641

642
    return NULL;
643 644 645 646
}

static int
xenUnifiedListDefinedDomains (virConnectPtr conn, char **const names,
647
                              int maxnames)
648
{
649
    GET_PRIVATE(conn);
650 651
    int i;
    int ret;
652

653 654
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->listDefinedDomains) {
655 656 657
            ret = drivers[i]->listDefinedDomains (conn, names, maxnames);
            if (ret >= 0) return ret;
        }
658

659
    return -1;
660 661 662 663 664
}

static int
xenUnifiedNumOfDefinedDomains (virConnectPtr conn)
{
665
    GET_PRIVATE(conn);
666 667
    int i;
    int ret;
668

669 670
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->numOfDefinedDomains) {
671 672 673
            ret = drivers[i]->numOfDefinedDomains (conn);
            if (ret >= 0) return ret;
        }
674

675
    return -1;
676 677 678 679 680
}

static int
xenUnifiedDomainCreate (virDomainPtr dom)
{
681
    GET_PRIVATE(dom->conn);
682
    int i;
683

684 685
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainCreate &&
686 687
            drivers[i]->domainCreate (dom) == 0)
            return 0;
688

689
    return -1;
690 691 692 693 694
}

static virDomainPtr
xenUnifiedDomainDefineXML (virConnectPtr conn, const char *xml)
{
695
    GET_PRIVATE(conn);
696 697
    int i;
    virDomainPtr ret;
698

699 700
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainDefineXML) {
701 702 703
            ret = drivers[i]->domainDefineXML (conn, xml);
            if (ret) return ret;
        }
704

705
    return NULL;
706 707 708 709 710
}

static int
xenUnifiedDomainUndefine (virDomainPtr dom)
{
711
    GET_PRIVATE(dom->conn);
712
    int i;
713

714 715
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainUndefine &&
716 717
            drivers[i]->domainUndefine (dom) == 0)
            return 0;
718

719
    return -1;
720 721 722 723 724
}

static int
xenUnifiedDomainAttachDevice (virDomainPtr dom, char *xml)
{
725
    GET_PRIVATE(dom->conn);
726
    int i;
727

728 729
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainAttachDevice &&
730 731
            drivers[i]->domainAttachDevice (dom, xml) == 0)
            return 0;
732

733
    return -1;
734 735 736 737 738
}

static int
xenUnifiedDomainDetachDevice (virDomainPtr dom, char *xml)
{
739
    GET_PRIVATE(dom->conn);
740
    int i;
741

742 743
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainDetachDevice &&
744 745
            drivers[i]->domainDetachDevice (dom, xml) == 0)
            return 0;
746

747
    return -1;
748 749 750 751 752
}

static int
xenUnifiedDomainGetAutostart (virDomainPtr dom, int *autostart)
{
753
    GET_PRIVATE(dom->conn);
754
    int i;
755

756 757
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainGetAutostart &&
758 759
            drivers[i]->domainGetAutostart (dom, autostart) == 0)
            return 0;
760

761
    return -1;
762 763 764 765 766
}

static int
xenUnifiedDomainSetAutostart (virDomainPtr dom, int autostart)
{
767
    GET_PRIVATE(dom->conn);
768
    int i;
769

770 771
    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
        if (priv->opened[i] && drivers[i]->domainSetAutostart &&
772 773
            drivers[i]->domainSetAutostart (dom, autostart) == 0)
            return 0;
774

775
    return -1;
776 777
}

778 779 780 781 782 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 824 825 826 827 828 829
static char *
xenUnifiedDomainGetSchedulerType (virDomainPtr dom, int *nparams)
{
    GET_PRIVATE(dom->conn);
    int i;
    char *schedulertype;

    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; i++) {
        if (priv->opened[i] && drivers[i]->domainGetSchedulerType) {
            schedulertype = drivers[i]->domainGetSchedulerType (dom, nparams);
	    if (schedulertype != NULL)
		return(schedulertype); 
        }
    }
    return(NULL);
}

static int
xenUnifiedDomainGetSchedulerParameters (virDomainPtr dom,
                    virSchedParameterPtr params, int *nparams)
{
    GET_PRIVATE(dom->conn);
    int i, ret;

    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) {
        if (priv->opened[i] && drivers[i]->domainGetSchedulerParameters) {
           ret = drivers[i]->domainGetSchedulerParameters(dom, params, nparams);
	   if (ret == 0)
	       return(0);
	}
    }
    return(-1);
}

static int
xenUnifiedDomainSetSchedulerParameters (virDomainPtr dom,
                    virSchedParameterPtr params, int nparams)
{
    GET_PRIVATE(dom->conn);
    int i, ret;

    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) {
        if (priv->opened[i] && drivers[i]->domainSetSchedulerParameters) {
           ret = drivers[i]->domainSetSchedulerParameters(dom, params, nparams);
	   if (ret == 0)
	       return 0;
	}
    }

    return(-1);
}

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

832 833 834
#define VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 +         \
                 ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +	\
                 (DOM0_INTERFACE_VERSION & 0xFFFF))
835 836 837

/* The interface which we export upwards to libvirt.c. */
static virDriver xenUnifiedDriver = {
838
    .no = VIR_DRV_XEN_UNIFIED,
839
    .name = "Xen",
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
    .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,
881 882 883
    .domainGetSchedulerType	= xenUnifiedDomainGetSchedulerType,
    .domainGetSchedulerParameters	= xenUnifiedDomainGetSchedulerParameters,
    .domainSetSchedulerParameters	= xenUnifiedDomainSetSchedulerParameters,
884 885
};

886 887 888 889 890 891 892
/**
 * xenUnifiedRegister:
 *
 * Register xen related drivers
 *
 * Returns the driver priority or -1 in case of error.
 */
893 894 895
int
xenUnifiedRegister (void)
{
896 897 898 899 900 901
    /* Ignore failures here. */
    (void) xenHypervisorInit ();
    (void) xenProxyInit ();
    (void) xenDaemonInit ();
    (void) xenStoreInit ();
    (void) xenXMInit ();
902

903
    return virRegisterDriver (&xenUnifiedDriver);
904 905 906
}

#endif /* WITH_XEN */
907 908 909 910 911 912 913 914 915 916 917 918 919 920

/*
 * 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:
 */