xen_driver.c 74.5 KB
Newer Older
1
/*
2
 * xen_driver.c: Unified Xen driver.
3
 *
4
 * Copyright (C) 2007-2015 Red Hat, Inc.
5
 *
O
Osier Yang 已提交
6 7 8 9 10 11 12 13 14 15 16
 * 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
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22
 *
 * Richard W.M. Jones <rjones@redhat.com>
 */

23
#include <config.h>
24

25 26 27
/* Note:
 *
 * This driver provides a unified interface to the five
28
 * separate underlying Xen drivers (xen_internal,
29 30 31 32 33 34 35
 * xend_internal, xs_internal and xm_internal).  Historically
 * the body of libvirt.c handled the five Xen drivers,
 * and contained Xen-specific code.
 */

#include <stdint.h>
#include <unistd.h>
36
#include <string.h>
37
#include <errno.h>
38
#include <sys/types.h>
39
#include <fcntl.h>
40 41
#include <xen/dom0_ops.h>

42
#include "virerror.h"
43
#include "virlog.h"
44
#include "datatypes.h"
45
#include "xen_driver.h"
46

47
#include "xen_sxpr.h"
48
#include "xen_xm.h"
P
Pavel Hrdina 已提交
49
#include "xen_common.h"
50
#include "xen_hypervisor.h"
51 52 53
#include "xend_internal.h"
#include "xs_internal.h"
#include "xm_internal.h"
54
#if WITH_XEN_INOTIFY
55
# include "xen_inotify.h"
56
#endif
57
#include "virxml.h"
58
#include "viralloc.h"
59
#include "node_device_conf.h"
60
#include "virpci.h"
61
#include "viruuid.h"
62
#include "virfdstream.h"
E
Eric Blake 已提交
63
#include "virfile.h"
M
Martin Kletzander 已提交
64
#include "viruri.h"
65
#include "vircommand.h"
66
#include "virnodesuspend.h"
67
#include "virhostmem.h"
68
#include "configmake.h"
69
#include "virstring.h"
70
#include "viraccessapicheck.h"
71

72
#define VIR_FROM_THIS VIR_FROM_XEN
73 74 75

VIR_LOG_INIT("xen.xen_driver");

76
#define XEN_SAVE_DIR LOCALSTATEDIR "/lib/libvirt/xen/save"
77

78
static int
79
xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
80

81
static int
82 83 84 85
xenUnifiedDomainGetVcpusFlagsInternal(virDomainPtr dom,
                                      virDomainDefPtr def,
                                      unsigned int flags);

86
static int
87 88 89 90 91 92
xenUnifiedDomainGetVcpusInternal(virDomainPtr dom,
                                 virDomainDefPtr def,
                                 virVcpuInfoPtr info,
                                 int maxinfo,
                                 unsigned char *cpumaps,
                                 int maplen);
93

94

95 96
static bool is_privileged;
static virSysinfoDefPtr hostsysinfo;
J
John Levon 已提交
97

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
static virDomainDefPtr xenGetDomainDefForID(virConnectPtr conn, int id)
{
    virDomainDefPtr ret;

    ret = xenHypervisorLookupDomainByID(conn, id);

    if (!ret && virGetLastError() == NULL)
        virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__);

    return ret;
}


static virDomainDefPtr xenGetDomainDefForName(virConnectPtr conn, const char *name)
{
    virDomainDefPtr ret;

    ret = xenDaemonLookupByName(conn, name);

    if (!ret && virGetLastError() == NULL)
        virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__);

    return ret;
}


static virDomainDefPtr xenGetDomainDefForUUID(virConnectPtr conn, const unsigned char *uuid)
{
    virDomainDefPtr ret;

    ret = xenHypervisorLookupDomainByUUID(conn, uuid);

130 131 132
    /* Try xend for inactive domains. */
    if (!ret)
        ret = xenDaemonLookupByUUID(conn, uuid);
133 134 135 136 137 138 139 140

    if (!ret && virGetLastError() == NULL)
        virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__);

    return ret;
}


141 142 143 144 145 146 147
static virDomainDefPtr xenGetDomainDefForDom(virDomainPtr dom)
{
    /* UUID lookup is more efficient than name lookup */
    return xenGetDomainDefForUUID(dom->conn, dom->uuid);
}


148 149 150 151 152
/**
 * xenNumaInit:
 * @conn: pointer to the hypervisor connection
 *
 * Initializer for previous variables. We currently assume that
R
Richard W.M. Jones 已提交
153
 * the number of physical CPU and the number of NUMA cell is fixed
154 155 156
 * until reboot which might be false in future Xen implementations.
 */
static void
157 158
xenNumaInit(virConnectPtr conn)
{
159
    virNodeInfo nodeInfo;
D
Daniel P. Berrange 已提交
160
    xenUnifiedPrivatePtr priv;
161 162 163 164 165 166
    int ret;

    ret = xenUnifiedNodeGetInfo(conn, &nodeInfo);
    if (ret < 0)
        return;

D
Daniel P. Berrange 已提交
167
    priv = conn->privateData;
168

D
Daniel P. Berrange 已提交
169 170
    priv->nbNodeCells = nodeInfo.nodes;
    priv->nbNodeCpus = nodeInfo.cpus;
171 172
}

D
Daniel P. Berrange 已提交
173

174 175 176
/**
 * xenDomainUsedCpus:
 * @dom: the domain
177
 * @def: the domain definition
178 179 180 181 182 183 184 185
 *
 * Analyze which set of CPUs are used by the domain and
 * return a string providing the ranges.
 *
 * Returns the string which needs to be freed by the caller or
 *         NULL if the domain uses all CPU or in case of error.
 */
char *
186
xenDomainUsedCpus(virDomainPtr dom, virDomainDefPtr def)
187 188
{
    char *res = NULL;
D
Daniel P. Berrange 已提交
189
    int ncpus;
190
    int nb_vcpu;
191
    virBitmapPtr cpulist = NULL;
192 193 194 195 196 197
    unsigned char *cpumap = NULL;
    size_t cpumaplen;
    int nb = 0;
    int n, m;
    virVcpuInfoPtr cpuinfo = NULL;
    virNodeInfo nodeinfo;
D
Daniel P. Berrange 已提交
198
    xenUnifiedPrivatePtr priv;
199

D
Daniel P. Berrange 已提交
200 201 202
    priv = dom->conn->privateData;

    if (priv->nbNodeCpus <= 0)
203
        return NULL;
204 205 206
    nb_vcpu = xenUnifiedDomainGetVcpusFlagsInternal(dom, def,
                                                    (VIR_DOMAIN_VCPU_LIVE |
                                                     VIR_DOMAIN_VCPU_MAXIMUM));
207
    if (nb_vcpu <= 0)
208
        return NULL;
209
    if (xenUnifiedNodeGetInfo(dom->conn, &nodeinfo) < 0)
210
        return NULL;
211

212
    if (!(cpulist = virBitmapNew(priv->nbNodeCpus)))
213
        goto done;
214
    if (VIR_ALLOC_N(cpuinfo, nb_vcpu) < 0)
215 216
        goto done;
    cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
217
    if (xalloc_oversized(nb_vcpu, cpumaplen) ||
218
        VIR_ALLOC_N(cpumap, nb_vcpu * cpumaplen) < 0)
219 220
        goto done;

221 222
    if ((ncpus = xenUnifiedDomainGetVcpusInternal(dom, def, cpuinfo, nb_vcpu,
                                                  cpumap, cpumaplen)) >= 0) {
223 224
        for (n = 0; n < ncpus; n++) {
            for (m = 0; m < priv->nbNodeCpus; m++) {
J
Ján Tomko 已提交
225
                if (!virBitmapIsBitSet(cpulist, m) &&
226
                    (VIR_CPU_USABLE(cpumap, cpumaplen, n, m))) {
227
                    ignore_value(virBitmapSetBit(cpulist, m));
228 229
                    nb++;
                    /* if all CPU are used just return NULL */
D
Daniel P. Berrange 已提交
230
                    if (nb == priv->nbNodeCpus)
231 232 233 234 235
                        goto done;

                }
            }
        }
236
        res = virBitmapFormat(cpulist);
237 238
    }

239
 done:
240
    virBitmapFree(cpulist);
241 242
    VIR_FREE(cpumap);
    VIR_FREE(cpuinfo);
243
    return res;
244 245
}

J
John Levon 已提交
246
static int
247
xenUnifiedStateInitialize(bool privileged,
248 249
                          virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                          void *opaque ATTRIBUTE_UNUSED)
J
John Levon 已提交
250
{
251
    /* Don't allow driver to work in non-root libvirtd */
J
Jim Fehlig 已提交
252
    if (privileged) {
253
        is_privileged = true;
J
Jim Fehlig 已提交
254 255 256 257 258 259 260 261 262 263
        hostsysinfo = virSysinfoRead();
    }

    return 0;
}

static int
xenUnifiedStateCleanup(void)
{
    virSysinfoDefFree(hostsysinfo);
J
John Levon 已提交
264 265 266 267
    return 0;
}

static virStateDriver state_driver = {
268
    .name = "Xen",
269
    .stateInitialize = xenUnifiedStateInitialize,
J
Jim Fehlig 已提交
270
    .stateCleanup = xenUnifiedStateCleanup,
J
John Levon 已提交
271 272
};

273 274 275 276 277 278 279 280 281 282 283
/*----- 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.
 */

284
static int
285
xenUnifiedProbe(void)
286 287 288
{
#ifdef __linux__
    if (virFileExists("/proc/xen"))
289
        return 1;
290
#endif
291
#ifdef __sun
292
    int fd;
293

294 295
    if ((fd = open("/dev/xen/domcaps", O_RDONLY)) >= 0) {
        VIR_FORCE_CLOSE(fd);
296
        return 1;
297 298
    }
#endif
299
    return 0;
300 301
}

J
Jim Fehlig 已提交
302
#ifdef WITH_LIBXL
303
static bool
304
xenUnifiedXendProbe(void)
J
Jim Fehlig 已提交
305
{
306
    bool ret = false;
J
Jim Fehlig 已提交
307

308 309 310 311 312 313 314 315
    if (virFileExists("/usr/sbin/xend")) {
        virCommandPtr cmd;

        cmd = virCommandNewArgList("/usr/sbin/xend", "status", NULL);
        if (virCommandRun(cmd, NULL) == 0)
            ret = true;
        virCommandFree(cmd);
    }
J
Jim Fehlig 已提交
316 317 318 319 320

    return ret;
}
#endif

321

322 323
static int
xenDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
324
                            const virDomainDef *def,
325
                            virCapsPtr caps ATTRIBUTE_UNUSED,
326
                            unsigned int parseFlags ATTRIBUTE_UNUSED,
327 328
                            void *opaque ATTRIBUTE_UNUSED,
                            void *parseOpaque ATTRIBUTE_UNUSED)
329 330 331 332
{
    if (dev->type == VIR_DOMAIN_DEVICE_CHR &&
        dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
        dev->data.chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE &&
333
        def->os.type != VIR_DOMAIN_OSTYPE_HVM)
334 335
        dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;

336 337 338 339 340 341 342 343 344 345
    /* forbid capabilities mode hostdev in this kind of hypervisor */
    if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
        dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("hostdev mode 'capabilities' is not "
                         "supported in %s"),
                       virDomainVirtTypeToString(def->virtType));
        return -1;
    }

346 347 348 349 350
    if (dev->type == VIR_DOMAIN_DEVICE_VIDEO && dev->data.video->vram == 0) {
        switch (dev->data.video->type) {
        case VIR_DOMAIN_VIDEO_TYPE_VGA:
        case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
        case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
351
            dev->data.video->vram = 16 * 1024;
352 353 354 355 356 357 358 359 360 361 362 363 364
        break;

        case VIR_DOMAIN_VIDEO_TYPE_XEN:
            /* Original Xen PVFB hardcoded to 4 MB */
            dev->data.video->vram = 4 * 1024;
            break;

        case VIR_DOMAIN_VIDEO_TYPE_QXL:
            /* Use 64M as the minimal video video memory for qxl device */
            return 64 * 1024;
        }
    }

365 366 367 368 369 370 371
    return 0;
}


static int
xenDomainDefPostParse(virDomainDefPtr def,
                      virCapsPtr caps ATTRIBUTE_UNUSED,
372
                      unsigned int parseFlags ATTRIBUTE_UNUSED,
373 374
                      void *opaque ATTRIBUTE_UNUSED,
                      void *parseOpaque ATTRIBUTE_UNUSED)
375
{
376 377 378 379 380 381 382 383 384
    if (!def->memballoon) {
        virDomainMemballoonDefPtr memballoon;
        if (VIR_ALLOC(memballoon) < 0)
            return -1;

        memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_XEN;
        def->memballoon = memballoon;
    }

P
Pavel Hrdina 已提交
385 386 387 388
    /* add implicit input device */
    if (xenDomainDefAddImplicitInputDevice(def) <0)
        return -1;

389 390 391 392
    return 0;
}


393 394
virDomainDefParserConfig xenDomainDefParserConfig = {
    .macPrefix = { 0x00, 0x16, 0x3e },
395
    .devicesPostParseCallback = xenDomainDeviceDefPostParse,
396
    .domainPostParseCallback = xenDomainDefPostParse,
397 398
};

399

400 401 402 403 404 405 406 407
virDomainXMLOptionPtr
xenDomainXMLConfInit(void)
{
    return virDomainXMLOptionNew(&xenDomainDefParserConfig,
                                 NULL, NULL);
}


408
static virDrvOpenStatus
409 410 411
xenUnifiedConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
                      virConfPtr conf ATTRIBUTE_UNUSED,
                      unsigned int flags)
412
{
413
    xenUnifiedPrivatePtr priv;
414

J
John Levon 已提交
415 416 417 418
    /*
     * Only the libvirtd instance can open this driver.
     * Everything else falls back to the remote driver.
     */
419
    if (!is_privileged)
J
John Levon 已提交
420 421
        return VIR_DRV_OPEN_DECLINED;

422 423 424 425
    if (conn->uri == NULL) {
        if (!xenUnifiedProbe())
            return VIR_DRV_OPEN_DECLINED;

426 427 428 429 430 431 432
#ifdef WITH_LIBXL
        /* Decline xen:// URI if xend is not running and libxenlight
         * driver is potentially available. */
        if (!xenUnifiedXendProbe())
            return VIR_DRV_OPEN_DECLINED;
#endif

433
        if (!(conn->uri = virURIParse("xen:///")))
434
            return VIR_DRV_OPEN_ERROR;
435 436 437 438 439 440 441
    } else {
        if (conn->uri->scheme) {
            /* Decline any scheme which isn't "xen://" or "http://". */
            if (STRCASENEQ(conn->uri->scheme, "xen") &&
                STRCASENEQ(conn->uri->scheme, "http"))
                return VIR_DRV_OPEN_DECLINED;

442 443 444 445 446 447
#ifdef WITH_LIBXL
            /* Decline xen:// URI if xend is not running and libxenlight
             * driver is potentially available. */
            if (!xenUnifiedXendProbe())
                return VIR_DRV_OPEN_DECLINED;
#endif
448 449 450 451 452

            /* Return an error if the path isn't '' or '/' */
            if (conn->uri->path &&
                STRNEQ(conn->uri->path, "") &&
                STRNEQ(conn->uri->path, "/")) {
453 454 455
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unexpected Xen URI path '%s', try xen:///"),
                               conn->uri->path);
456 457
                return VIR_DRV_OPEN_ERROR;
            }
458

459 460 461 462 463 464
            /* Decline any xen:// URI with a server specified, allowing remote
             * driver to handle, but keep any http:/// URIs */
            if (STRCASEEQ(conn->uri->scheme, "xen") &&
                conn->uri->server)
                return VIR_DRV_OPEN_DECLINED;
        } else {
465
            return VIR_DRV_OPEN_DECLINED;
466 467
        }
    }
468

469 470
    /* We now know the URI is definitely for this driver, so beyond
     * here, don't return DECLINED, always use ERROR */
471

472 473 474
    if (virConnectOpenEnsureACL(conn) < 0)
        return VIR_DRV_OPEN_ERROR;

475
    /* Allocate per-connection private data. */
476
    if (VIR_ALLOC(priv) < 0)
477
        return VIR_DRV_OPEN_ERROR;
D
Daniel P. Berrange 已提交
478
    if (virMutexInit(&priv->lock) < 0) {
479 480
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot initialize mutex"));
D
Daniel P. Berrange 已提交
481 482 483
        VIR_FREE(priv);
        return VIR_DRV_OPEN_ERROR;
    }
484

485
    if (!(priv->domainEvents = virObjectEventStateNew())) {
D
Daniel P. Berrange 已提交
486 487
        virMutexDestroy(&priv->lock);
        VIR_FREE(priv);
488 489
        return VIR_DRV_OPEN_ERROR;
    }
D
Daniel P. Berrange 已提交
490 491
    conn->privateData = priv;

492 493 494 495
    priv->handle = -1;
    priv->xshandle = NULL;


496 497 498 499 500 501
    /* Hypervisor required to succeed */
    VIR_DEBUG("Trying hypervisor sub-driver");
    if (xenHypervisorOpen(conn, auth, flags) < 0)
        goto error;
    VIR_DEBUG("Activated hypervisor sub-driver");
    priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] = 1;
502

503
    /* XenD is required to succeed */
504
    VIR_DEBUG("Trying XenD sub-driver");
505 506 507 508 509 510 511 512 513 514
    if (xenDaemonOpen(conn, auth, flags) < 0)
        goto error;
    VIR_DEBUG("Activated XenD sub-driver");
    priv->opened[XEN_UNIFIED_XEND_OFFSET] = 1;

    VIR_DEBUG("Trying XS sub-driver");
    if (xenStoreOpen(conn, auth, flags) < 0)
        goto error;
    VIR_DEBUG("Activated XS sub-driver");
    priv->opened[XEN_UNIFIED_XS_OFFSET] = 1;
515

D
Daniel P. Berrange 已提交
516 517
    xenNumaInit(conn);

518
    if (!(priv->caps = xenHypervisorMakeCapabilities(conn))) {
519
        VIR_DEBUG("Failed to make capabilities");
520
        goto error;
521 522
    }

523
    if (!(priv->xmlopt = xenDomainXMLConfInit()))
524
        goto error;
525

526
#if WITH_XEN_INOTIFY
527 528 529 530 531
    VIR_DEBUG("Trying Xen inotify sub-driver");
    if (xenInotifyOpen(conn, auth, flags) < 0)
        goto error;
    VIR_DEBUG("Activated Xen inotify sub-driver");
    priv->opened[XEN_UNIFIED_INOTIFY_OFFSET] = 1;
532 533
#endif

534
    if (VIR_STRDUP(priv->saveDir, XEN_SAVE_DIR) < 0)
535
        goto error;
536 537

    if (virFileMakePath(priv->saveDir) < 0) {
538 539
        virReportSystemError(errno, _("Errored to create save dir '%s'"),
                             priv->saveDir);
540
        goto error;
541 542
    }

543
    return VIR_DRV_OPEN_SUCCESS;
544

545
 error:
546
    VIR_DEBUG("Failed to activate a mandatory sub-driver");
547 548 549 550 551 552 553 554 555 556 557 558
#if WITH_XEN_INOTIFY
    if (priv->opened[XEN_UNIFIED_INOTIFY_OFFSET])
        xenInotifyClose(conn);
#endif
    if (priv->opened[XEN_UNIFIED_XM_OFFSET])
        xenXMClose(conn);
    if (priv->opened[XEN_UNIFIED_XS_OFFSET])
        xenStoreClose(conn);
    if (priv->opened[XEN_UNIFIED_XEND_OFFSET])
        xenDaemonClose(conn);
    if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET])
        xenHypervisorClose(conn);
D
Daniel P. Berrange 已提交
559
    virMutexDestroy(&priv->lock);
560
    VIR_FREE(priv->saveDir);
561
    VIR_FREE(priv);
D
Daniel P. Berrange 已提交
562
    conn->privateData = NULL;
563
    return VIR_DRV_OPEN_ERROR;
564 565 566
}

static int
567
xenUnifiedConnectClose(virConnectPtr conn)
568
{
569
    xenUnifiedPrivatePtr priv = conn->privateData;
570

571
    virObjectUnref(priv->caps);
572
    virObjectUnref(priv->xmlopt);
573
    virObjectUnref(priv->domainEvents);
574

575 576 577 578 579 580 581 582 583 584 585 586
#if WITH_XEN_INOTIFY
    if (priv->opened[XEN_UNIFIED_INOTIFY_OFFSET])
        xenInotifyClose(conn);
#endif
    if (priv->opened[XEN_UNIFIED_XM_OFFSET])
        xenXMClose(conn);
    if (priv->opened[XEN_UNIFIED_XS_OFFSET])
        xenStoreClose(conn);
    if (priv->opened[XEN_UNIFIED_XEND_OFFSET])
        xenDaemonClose(conn);
    if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET])
        xenHypervisorClose(conn);
587

588
    VIR_FREE(priv->saveDir);
D
Daniel P. Berrange 已提交
589 590
    virMutexDestroy(&priv->lock);
    VIR_FREE(conn->privateData);
591

592
    return 0;
593 594
}

595 596 597 598 599 600 601 602 603 604 605

#define HV_VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 +         \
                    ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +   \
                    (DOM0_INTERFACE_VERSION & 0xFFFF))

unsigned long xenUnifiedVersion(void)
{
    return HV_VERSION;
}


606
static const char *
607
xenUnifiedConnectGetType(virConnectPtr conn)
608
{
609 610 611
    if (virConnectGetTypeEnsureACL(conn) < 0)
        return NULL;

612
    return "Xen";
613 614
}

615 616
/* Which features are supported by this driver? */
static int
617
xenUnifiedConnectSupportsFeature(virConnectPtr conn, int feature)
618
{
619 620 621
    if (virConnectSupportsFeatureEnsureACL(conn) < 0)
        return -1;

622
    switch (feature) {
623 624 625 626 627
    case VIR_DRV_FEATURE_MIGRATION_V1:
    case VIR_DRV_FEATURE_MIGRATION_DIRECT:
        return 1;
    default:
        return 0;
628 629 630
    }
}

631
static int
632
xenUnifiedConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
633
{
634 635 636
    if (virConnectGetVersionEnsureACL(conn) < 0)
        return -1;

637
    return xenHypervisorGetVersion(conn, hvVer);
638 639
}

640

641
static char *xenUnifiedConnectGetHostname(virConnectPtr conn)
642
{
643 644 645
    if (virConnectGetHostnameEnsureACL(conn) < 0)
        return NULL;

646 647 648
    return virGetHostname();
}

J
Jim Fehlig 已提交
649 650 651 652 653 654 655 656
static char *
xenUnifiedConnectGetSysinfo(virConnectPtr conn ATTRIBUTE_UNUSED,
                            unsigned int flags)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    virCheckFlags(0, NULL);

657 658 659
    if (virConnectGetSysinfoEnsureACL(conn) < 0)
        return NULL;

J
Jim Fehlig 已提交
660 661 662 663 664 665 666 667
    if (!hostsysinfo) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Host SMBIOS information is not available"));
        return NULL;
    }

    if (virSysinfoFormat(&buf, hostsysinfo) < 0)
        return NULL;
668
    if (virBufferCheckError(&buf) < 0)
J
Jim Fehlig 已提交
669 670 671
        return NULL;
    return virBufferContentAndReset(&buf);
}
672

673
static int
674
xenUnifiedConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
675 676 677 678 679
{
    return 0;
}

static int
680
xenUnifiedConnectIsSecure(virConnectPtr conn)
681
{
682
    xenUnifiedPrivatePtr priv = conn->privateData;
683 684 685 686 687 688 689 690 691 692
    int ret = 1;

    /* All drivers are secure, except for XenD over TCP */
    if (priv->opened[XEN_UNIFIED_XEND_OFFSET] &&
        priv->addrfamily != AF_UNIX)
        ret = 0;

    return ret;
}

693
static int
694
xenUnifiedConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
695 696 697 698 699
{
    /* XenD reconnects for each request */
    return 1;
}

700
int
701
xenUnifiedConnectGetMaxVcpus(virConnectPtr conn, const char *type)
702
{
703 704 705
    if (virConnectGetMaxVcpusEnsureACL(conn) < 0)
        return -1;

706
    if (type && STRCASENEQ(type, "Xen")) {
707
        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
708 709
        return -1;
    }
710

711
    return xenHypervisorGetMaxVcpus(conn, type);
712 713 714
}

static int
715
xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
716
{
717 718 719
    if (virNodeGetInfoEnsureACL(conn) < 0)
        return -1;

720
    return xenDaemonNodeGetInfo(conn, info);
721 722 723
}

static char *
724
xenUnifiedConnectGetCapabilities(virConnectPtr conn)
725
{
D
Daniel P. Berrange 已提交
726
    xenUnifiedPrivatePtr priv = conn->privateData;
727

728 729 730
    if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
        return NULL;

731
    return virCapabilitiesFormatXML(priv->caps);
732 733 734
}

static int
735
xenUnifiedConnectListDomains(virConnectPtr conn, int *ids, int maxids)
736
{
737 738 739
    if (virConnectListDomainsEnsureACL(conn) < 0)
        return -1;

740
    return xenStoreListDomains(conn, ids, maxids);
741 742 743
}

static int
744
xenUnifiedConnectNumOfDomains(virConnectPtr conn)
745
{
746 747 748
    if (virConnectNumOfDomainsEnsureACL(conn) < 0)
        return -1;

749
    return xenStoreNumOfDomains(conn);
750 751 752
}

static virDomainPtr
753
xenUnifiedDomainCreateXML(virConnectPtr conn,
754 755
                          const char *xml,
                          unsigned int flags)
756
{
757 758 759
    xenUnifiedPrivatePtr priv = conn->privateData;
    virDomainDefPtr def = NULL;
    virDomainPtr ret = NULL;
760
    unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
761

762 763 764
    virCheckFlags(VIR_DOMAIN_START_VALIDATE, NULL);

    if (flags & VIR_DOMAIN_START_VALIDATE)
765
        parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
766

767
    if (!(def = virDomainDefParseString(xml, priv->caps, priv->xmlopt,
768
                                        NULL, parse_flags)))
769 770
        goto cleanup;

771 772 773
    if (virDomainCreateXMLEnsureACL(conn, def) < 0)
        goto cleanup;

774 775 776 777 778 779 780
    if (xenDaemonCreateXML(conn, def) < 0)
        goto cleanup;

    ret = virGetDomain(conn, def->name, def->uuid);
    if (ret)
        ret->id = def->id;

781
 cleanup:
782 783
    virDomainDefFree(def);
    return ret;
784 785 786
}

static virDomainPtr
787
xenUnifiedDomainLookupByID(virConnectPtr conn, int id)
788
{
789
    virDomainPtr ret = NULL;
790
    virDomainDefPtr def = NULL;
791

792 793
    if (!(def = xenGetDomainDefForID(conn, id)))
        goto cleanup;
794

795 796 797
    if (virDomainLookupByIDEnsureACL(conn, def) < 0)
        goto cleanup;

798 799
    if (!(ret = virGetDomain(conn, def->name, def->uuid)))
        goto cleanup;
800

801 802
    ret->id = def->id;

803
 cleanup:
804
    virDomainDefFree(def);
805
    return ret;
806 807 808
}

static virDomainPtr
809 810
xenUnifiedDomainLookupByUUID(virConnectPtr conn,
                             const unsigned char *uuid)
811
{
812 813
    virDomainPtr ret = NULL;
    virDomainDefPtr def = NULL;
814

815 816
    if (!(def = xenGetDomainDefForUUID(conn, uuid)))
        goto cleanup;
817

818 819 820
    if (virDomainLookupByUUIDEnsureACL(conn, def) < 0)
        goto cleanup;

821 822
    if (!(ret = virGetDomain(conn, def->name, def->uuid)))
        goto cleanup;
823

824
    ret->id = def->id;
825

826
 cleanup:
827
    virDomainDefFree(def);
828
    return ret;
829 830 831
}

static virDomainPtr
832 833
xenUnifiedDomainLookupByName(virConnectPtr conn,
                             const char *name)
834
{
835 836
    virDomainPtr ret = NULL;
    virDomainDefPtr def = NULL;
837

838 839
    if (!(def = xenGetDomainDefForName(conn, name)))
        goto cleanup;
840

841 842 843
    if (virDomainLookupByNameEnsureACL(conn, def) < 0)
        goto cleanup;

844 845
    if (!(ret = virGetDomain(conn, def->name, def->uuid)))
        goto cleanup;
846

847
    ret->id = def->id;
848

849
 cleanup:
850
    virDomainDefFree(def);
851
    return ret;
852 853
}

854 855 856 857

static int
xenUnifiedDomainIsActive(virDomainPtr dom)
{
858
    virDomainDefPtr def;
859 860
    int ret = -1;

861 862
    if (!(def = xenGetDomainDefForUUID(dom->conn, dom->uuid)))
        goto cleanup;
863

864
    ret = def->id == -1 ? 0 : 1;
865

866
 cleanup:
867
    virDomainDefFree(def);
868 869 870 871
    return ret;
}

static int
872
xenUnifiedDomainIsPersistent(virDomainPtr dom)
873
{
874
    xenUnifiedPrivatePtr priv = dom->conn->privateData;
875
    virDomainDefPtr def = NULL;
876 877 878 879 880
    int ret = -1;

    if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
        /* Old Xen, pre-inactive domain management.
         * If the XM driver can see the guest, it is definitely persistent */
881 882
        def = xenXMDomainLookupByUUID(dom->conn, dom->uuid);
        if (def)
883 884 885 886 887
            ret = 1;
        else
            ret = 0;
    } else {
        /* New Xen with inactive domain management */
888 889 890
        def = xenDaemonLookupByUUID(dom->conn, dom->uuid);
        if (def) {
            if (def->id == -1) {
891 892 893 894 895 896 897 898 899
                /* If its inactive, then trivially, it must be persistent */
                ret = 1;
            } else {
                char *path;
                char uuidstr[VIR_UUID_STRING_BUFLEN];

                /* If its running there's no official way to tell, so we
                 * go behind xend's back & look at the config dir */
                virUUIDFormat(dom->uuid, uuidstr);
900
                if (virAsprintf(&path, "%s/%s", XEND_DOMAINS_DIR, uuidstr) < 0)
901
                    goto cleanup;
902 903 904 905
                if (access(path, R_OK) == 0)
                    ret = 1;
                else if (errno == ENOENT)
                    ret = 0;
906 907 908 909
            }
        }
    }

910
 cleanup:
911
    virDomainDefFree(def);
912 913 914 915

    return ret;
}

916 917 918 919 920 921
static int
xenUnifiedDomainIsUpdated(virDomainPtr dom ATTRIBUTE_UNUSED)
{
    return 0;
}

922
static int
923
xenUnifiedDomainSuspend(virDomainPtr dom)
924
{
925 926 927 928 929 930
    int ret = -1;
    virDomainDefPtr def;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

931 932 933
    if (virDomainSuspendEnsureACL(dom->conn, def) < 0)
        goto cleanup;

934 935
    ret = xenDaemonDomainSuspend(dom->conn, def);

936
 cleanup:
937 938
    virDomainDefFree(def);
    return ret;
939 940 941
}

static int
942
xenUnifiedDomainResume(virDomainPtr dom)
943
{
944 945 946 947 948 949
    int ret = -1;
    virDomainDefPtr def;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

950 951 952
    if (virDomainResumeEnsureACL(dom->conn, def) < 0)
        goto cleanup;

953 954
    ret = xenDaemonDomainResume(dom->conn, def);

955
 cleanup:
956 957
    virDomainDefFree(def);
    return ret;
958 959 960
}

static int
961 962
xenUnifiedDomainShutdownFlags(virDomainPtr dom,
                              unsigned int flags)
963
{
964 965 966
    int ret = -1;
    virDomainDefPtr def;

967 968
    virCheckFlags(0, -1);

969 970 971
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

972
    if (virDomainShutdownFlagsEnsureACL(dom->conn, def, flags) < 0)
973 974
        goto cleanup;

975 976
    ret = xenDaemonDomainShutdown(dom->conn, def);

977
 cleanup:
978 979
    virDomainDefFree(def);
    return ret;
980 981
}

982 983 984 985 986 987
static int
xenUnifiedDomainShutdown(virDomainPtr dom)
{
    return xenUnifiedDomainShutdownFlags(dom, 0);
}

988
static int
989
xenUnifiedDomainReboot(virDomainPtr dom, unsigned int flags)
990
{
991 992 993
    int ret = -1;
    virDomainDefPtr def;

994
    virCheckFlags(0, -1);
995

996 997 998
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

999
    if (virDomainRebootEnsureACL(dom->conn, def, flags) < 0)
1000 1001
        goto cleanup;

1002 1003
    ret = xenDaemonDomainReboot(dom->conn, def);

1004
 cleanup:
1005 1006
    virDomainDefFree(def);
    return ret;
1007 1008
}

1009 1010 1011 1012
static int
xenUnifiedDomainDestroyFlags(virDomainPtr dom,
                             unsigned int flags)
{
1013 1014 1015
    int ret = -1;
    virDomainDefPtr def;

1016 1017
    virCheckFlags(0, -1);

1018 1019 1020
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1021 1022 1023
    if (virDomainDestroyFlagsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1024 1025
    ret = xenDaemonDomainDestroy(dom->conn, def);

1026
 cleanup:
1027 1028
    virDomainDefFree(def);
    return ret;
1029 1030
}

1031 1032 1033 1034 1035 1036
static int
xenUnifiedDomainDestroy(virDomainPtr dom)
{
    return xenUnifiedDomainDestroyFlags(dom, 0);
}

1037
static char *
1038
xenUnifiedDomainGetOSType(virDomainPtr dom)
1039
{
1040 1041 1042 1043 1044
    char *ret = NULL;
    virDomainDefPtr def;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1045

1046 1047 1048
    if (virDomainGetOSTypeEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1049 1050 1051
    if (def->id < 0)
        ret = xenDaemonDomainGetOSType(dom->conn, def);
    else
1052 1053
        ret = xenHypervisorDomainGetOSType(dom->conn, def);

1054
 cleanup:
1055 1056
    virDomainDefFree(def);
    return ret;
1057 1058
}

1059

1060
static unsigned long long
1061
xenUnifiedDomainGetMaxMemory(virDomainPtr dom)
1062
{
1063 1064 1065 1066 1067
    unsigned long long ret = 0;
    virDomainDefPtr def;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1068

1069 1070 1071
    if (virDomainGetMaxMemoryEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1072 1073 1074
    if (def->id < 0)
        ret = xenDaemonDomainGetMaxMemory(dom->conn, def);
    else
1075 1076
        ret = xenHypervisorGetMaxMemory(dom->conn, def);

1077
 cleanup:
1078 1079
    virDomainDefFree(def);
    return ret;
1080 1081 1082
}

static int
1083
xenUnifiedDomainSetMaxMemory(virDomainPtr dom, unsigned long memory)
1084
{
1085 1086
    int ret = -1;
    virDomainDefPtr def;
1087

1088 1089 1090
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1091 1092 1093
    if (virDomainSetMaxMemoryEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1094 1095 1096
    if (def->id < 0)
        ret = xenDaemonDomainSetMaxMemory(dom->conn, def, memory);
    else
1097 1098
        ret = xenHypervisorSetMaxMemory(dom->conn, def, memory);

1099
 cleanup:
1100 1101
    virDomainDefFree(def);
    return ret;
1102 1103 1104
}

static int
1105
xenUnifiedDomainSetMemory(virDomainPtr dom, unsigned long memory)
1106
{
1107 1108 1109 1110 1111
    int ret = -1;
    virDomainDefPtr def;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1112

1113 1114 1115
    if (virDomainSetMemoryEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1116
    ret = xenDaemonDomainSetMemory(dom->conn, def, memory);
1117

1118
 cleanup:
1119 1120
    virDomainDefFree(def);
    return ret;
1121 1122 1123
}

static int
1124
xenUnifiedDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
1125
{
1126 1127 1128 1129 1130
    int ret = -1;
    virDomainDefPtr def;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1131

1132 1133 1134
    if (virDomainGetInfoEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1135 1136 1137
    if (def->id < 0)
        ret = xenDaemonDomainGetInfo(dom->conn, def, info);
    else
1138 1139
        ret = xenHypervisorGetDomainInfo(dom->conn, def, info);

1140
 cleanup:
1141 1142
    virDomainDefFree(def);
    return ret;
1143 1144
}

1145 1146 1147 1148 1149 1150
static int
xenUnifiedDomainGetState(virDomainPtr dom,
                         int *state,
                         int *reason,
                         unsigned int flags)
{
1151

1152 1153
    int ret = -1;
    virDomainDefPtr def;
1154 1155 1156

    virCheckFlags(0, -1);

1157 1158 1159
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1160 1161 1162
    if (virDomainGetStateEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1163 1164 1165
    if (def->id < 0)
        ret = xenDaemonDomainGetState(dom->conn, def, state, reason);
    else
1166 1167
        ret = xenHypervisorGetDomainState(dom->conn, def, state, reason);

1168
 cleanup:
1169 1170
    virDomainDefFree(def);
    return ret;
1171 1172
}

1173
static int
1174 1175
xenUnifiedDomainSaveFlags(virDomainPtr dom, const char *to, const char *dxml,
                          unsigned int flags)
1176
{
1177 1178 1179
    int ret = -1;
    virDomainDefPtr def;

1180
    virCheckFlags(0, -1);
1181

1182
    if (dxml) {
1183 1184
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("xml modification unsupported"));
1185 1186 1187
        return -1;
    }

1188 1189 1190
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1191 1192 1193
    if (virDomainSaveFlagsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1194 1195
    ret = xenDaemonDomainSave(dom->conn, def, to);

1196
 cleanup:
1197 1198
    virDomainDefFree(def);
    return ret;
1199 1200 1201
}

static int
1202 1203 1204 1205 1206
xenUnifiedDomainSave(virDomainPtr dom, const char *to)
{
    return xenUnifiedDomainSaveFlags(dom, to, NULL, 0);
}

1207
static char *
1208 1209
xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv,
                                virDomainDefPtr def)
1210 1211 1212
{
    char *ret;

1213
    if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, def->name) < 0)
1214 1215 1216 1217 1218 1219 1220 1221 1222
        return NULL;

    VIR_DEBUG("managed save image: %s", ret);
    return ret;
}

static int
xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags)
{
1223
    xenUnifiedPrivatePtr priv = dom->conn->privateData;
1224 1225
    char *name = NULL;
    virDomainDefPtr def = NULL;
1226 1227 1228 1229
    int ret = -1;

    virCheckFlags(0, -1);

1230 1231 1232
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1233 1234 1235
    if (virDomainManagedSaveEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1236
    if (!(name = xenUnifiedDomainManagedSavePath(priv, def)))
1237 1238
        goto cleanup;

1239
    ret = xenDaemonDomainSave(dom->conn, def, name);
1240

1241
 cleanup:
1242
    VIR_FREE(name);
1243
    virDomainDefFree(def);
1244 1245 1246 1247 1248 1249
    return ret;
}

static int
xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
{
1250
    xenUnifiedPrivatePtr priv = dom->conn->privateData;
1251 1252
    char *name = NULL;
    virDomainDefPtr def = NULL;
1253 1254 1255 1256
    int ret = -1;

    virCheckFlags(0, -1);

1257 1258 1259
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1260 1261 1262
    if (virDomainHasManagedSaveImageEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1263 1264
    if (!(name = xenUnifiedDomainManagedSavePath(priv, def)))
        goto cleanup;
1265 1266

    ret = virFileExists(name);
1267

1268
 cleanup:
1269
    VIR_FREE(name);
1270
    virDomainDefFree(def);
1271 1272 1273 1274 1275 1276
    return ret;
}

static int
xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
{
1277
    xenUnifiedPrivatePtr priv = dom->conn->privateData;
1278 1279
    char *name = NULL;
    virDomainDefPtr def = NULL;
1280 1281 1282 1283
    int ret = -1;

    virCheckFlags(0, -1);

1284 1285 1286
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1287 1288 1289
    if (virDomainManagedSaveRemoveEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1290 1291
    if (!(name = xenUnifiedDomainManagedSavePath(priv, def)))
        goto cleanup;
1292 1293

    ret = unlink(name);
1294

1295
 cleanup:
1296 1297 1298 1299
    VIR_FREE(name);
    return ret;
}

1300 1301 1302
static int
xenUnifiedDomainRestoreFlags(virConnectPtr conn, const char *from,
                             const char *dxml, unsigned int flags)
1303
{
1304 1305
    virCheckFlags(0, -1);
    if (dxml) {
1306 1307
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("xml modification unsupported"));
1308 1309 1310
        return -1;
    }

1311
    return xenDaemonDomainRestore(conn, from);
1312 1313
}

1314
static int
1315
xenUnifiedDomainRestore(virConnectPtr conn, const char *from)
1316 1317 1318 1319
{
    return xenUnifiedDomainRestoreFlags(conn, from, NULL, 0);
}

1320
static int
1321
xenUnifiedDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
1322
{
1323 1324 1325 1326 1327 1328 1329 1330
    virDomainDefPtr def = NULL;
    int ret = -1;

    virCheckFlags(0, -1);

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1331 1332 1333
    if (virDomainCoreDumpEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1334 1335
    ret = xenDaemonDomainCoreDump(dom->conn, def, to, flags);

1336
 cleanup:
1337 1338
    virDomainDefFree(def);
    return ret;
1339 1340 1341
}

static int
1342 1343
xenUnifiedDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
                              unsigned int flags)
1344
{
1345 1346
    virDomainDefPtr def = NULL;
    int ret = -1;
1347

1348 1349 1350 1351 1352 1353 1354 1355 1356
    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
                  VIR_DOMAIN_VCPU_CONFIG |
                  VIR_DOMAIN_VCPU_MAXIMUM, -1);

    /* At least one of LIVE or CONFIG must be set.  MAXIMUM cannot be
     * mixed with LIVE.  */
    if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
        (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
         (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
1357 1358
        virReportError(VIR_ERR_INVALID_ARG,
                       _("invalid flag combination: (0x%x)"), flags);
1359 1360 1361
        return -1;
    }
    if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
1362 1363
        virReportError(VIR_ERR_INVALID_ARG,
                       _("argument out of range: %d"), nvcpus);
1364 1365 1366
        return -1;
    }

1367 1368 1369
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1370 1371 1372
    if (virDomainSetVcpusFlagsEnsureACL(dom->conn, def, flags) < 0)
        goto cleanup;

1373
    ret = xenDaemonDomainSetVcpusFlags(dom->conn, def, nvcpus, flags);
1374

1375
 cleanup:
1376 1377
    virDomainDefFree(def);
    return ret;
1378 1379
}

1380
static int
1381
xenUnifiedDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
1382
{
1383
    unsigned int flags;
1384 1385

    /* Per the documented API, it is hypervisor-dependent whether this
1386 1387 1388
     * affects just _LIVE or _LIVE|_CONFIG; in xen's case, both are
     * affected. */
    flags = VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG;
1389 1390

    return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags);
1391 1392
}

1393
static int
1394 1395
xenUnifiedDomainPinVcpu(virDomainPtr dom, unsigned int vcpu,
                        unsigned char *cpumap, int maplen)
1396
{
1397 1398 1399 1400 1401
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1402

1403 1404 1405
    if (virDomainPinVcpuEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1406 1407 1408
    if (dom->id < 0)
        ret = xenDaemonDomainPinVcpu(dom->conn, def, vcpu, cpumap, maplen);
    else
1409 1410
        ret = xenHypervisorPinVcpu(dom->conn, def, vcpu, cpumap, maplen);

1411
 cleanup:
1412 1413
    virDomainDefFree(def);
    return ret;
1414 1415 1416
}

static int
1417 1418 1419 1420 1421 1422
xenUnifiedDomainGetVcpusInternal(virDomainPtr dom,
                                 virDomainDefPtr def,
                                 virVcpuInfoPtr info,
                                 int maxinfo,
                                 unsigned char *cpumaps,
                                 int maplen)
1423
{
1424 1425
    int ret = -1;

1426
    if (dom->id < 0) {
1427 1428
        ret = xenDaemonDomainGetVcpus(dom->conn, def, info, maxinfo,
                                      cpumaps, maplen);
1429
    } else {
1430 1431
        ret = xenHypervisorGetVcpus(dom->conn, def, info, maxinfo, cpumaps,
                                    maplen);
1432
    }
1433 1434

    return ret;
1435 1436 1437
}

static int
1438 1439 1440
xenUnifiedDomainGetVcpus(virDomainPtr dom,
                         virVcpuInfoPtr info, int maxinfo,
                         unsigned char *cpumaps, int maplen)
1441
{
1442 1443
    virDomainDefPtr def = NULL;
    int ret = -1;
1444

1445 1446 1447
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1448
    if (virDomainGetVcpusEnsureACL(dom->conn, def) < 0)
1449 1450
        goto cleanup;

1451 1452 1453
    ret = xenUnifiedDomainGetVcpusInternal(dom, def, info, maxinfo, cpumaps,
                                           maplen);

1454
 cleanup:
1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
    virDomainDefFree(def);
    return ret;
}

static int
xenUnifiedDomainGetVcpusFlagsInternal(virDomainPtr dom,
                                      virDomainDefPtr def,
                                      unsigned int flags)
{
    int ret = -1;

1466
    if (dom->id < 0) {
1467
        ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags);
1468 1469
    } else {
        if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM))
1470
            ret = xenHypervisorGetVcpuMax(dom->conn, def);
1471
        else
1472
            ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags);
1473
    }
1474

1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
   return ret;
}

static int
xenUnifiedDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
{
    virDomainDefPtr def = NULL;
    int ret = -1;

    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
                  VIR_DOMAIN_VCPU_CONFIG |
                  VIR_DOMAIN_VCPU_MAXIMUM, -1);

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1491
    if (virDomainGetVcpusFlagsEnsureACL(dom->conn, def, flags) < 0)
1492 1493 1494 1495
        goto cleanup;

    ret = xenUnifiedDomainGetVcpusFlagsInternal(dom, def, flags);

1496
 cleanup:
1497 1498
    virDomainDefFree(def);
    return ret;
1499 1500
}

1501
static int
1502
xenUnifiedDomainGetMaxVcpus(virDomainPtr dom)
1503 1504 1505 1506 1507
{
    return xenUnifiedDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
                                               VIR_DOMAIN_VCPU_MAXIMUM));
}

1508
static char *
1509
xenUnifiedDomainGetXMLDesc(virDomainPtr dom, unsigned int flags)
1510
{
1511
    xenUnifiedPrivatePtr priv = dom->conn->privateData;
1512 1513 1514
    virDomainDefPtr minidef = NULL;
    virDomainDefPtr def = NULL;
    char *ret = NULL;
1515
    char *cpus = NULL;
1516 1517 1518

    if (!(minidef = xenGetDomainDefForDom(dom)))
        goto cleanup;
1519

1520 1521 1522
    if (virDomainGetXMLDescEnsureACL(dom->conn, minidef, flags) < 0)
        goto cleanup;

1523 1524 1525 1526
    xenUnifiedLock(priv);
    cpus = xenDomainUsedCpus(dom, minidef);
    xenUnifiedUnlock(priv);
    def = xenDaemonDomainGetXMLDesc(dom->conn, minidef, cpus);
1527 1528

    if (def)
1529
        ret = virDomainDefFormat(def, priv->caps,
1530
                                 virDomainDefFormatConvertXMLFlags(flags));
1531

1532
 cleanup:
1533
    VIR_FREE(cpus);
1534 1535 1536
    virDomainDefFree(def);
    virDomainDefFree(minidef);
    return ret;
1537 1538
}

1539 1540

static char *
1541 1542 1543 1544
xenUnifiedConnectDomainXMLFromNative(virConnectPtr conn,
                                     const char *format,
                                     const char *config,
                                     unsigned int flags)
1545 1546 1547 1548
{
    virDomainDefPtr def = NULL;
    char *ret = NULL;
    virConfPtr conf = NULL;
1549 1550 1551
    int id;
    char * tty;
    int vncport;
1552
    xenUnifiedPrivatePtr priv = conn->privateData;
1553

E
Eric Blake 已提交
1554 1555
    virCheckFlags(0, NULL);

1556 1557 1558
    if (virConnectDomainXMLFromNativeEnsureACL(conn) < 0)
        return NULL;

1559 1560
    if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
        STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
1561 1562
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unsupported config type %s"), format);
1563 1564 1565 1566
        return NULL;
    }

    if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
1567
        conf = virConfReadMem(config, strlen(config), 0);
1568 1569 1570
        if (!conf)
            goto cleanup;

1571
        def = xenParseXM(conf, priv->caps, priv->xmlopt);
1572
    } else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
1573
        if (xenGetDomIdFromSxprString(config, &id) < 0)
1574
            goto cleanup;
1575 1576 1577 1578
        xenUnifiedLock(priv);
        tty = xenStoreDomainGetConsolePath(conn, id);
        vncport = xenStoreDomainGetVNCPort(conn, id);
        xenUnifiedUnlock(priv);
1579
        def = xenParseSxprString(config, tty,
1580
                                 vncport, priv->caps, priv->xmlopt);
1581 1582 1583 1584
    }
    if (!def)
        goto cleanup;

1585
    ret = virDomainDefFormat(def, priv->caps, 0);
1586

1587
 cleanup:
1588
    virDomainDefFree(def);
1589 1590
    if (conf)
        virConfFree(conf);
1591 1592 1593 1594 1595 1596
    return ret;
}


#define MAX_CONFIG_SIZE (1024 * 65)
static char *
1597 1598 1599 1600
xenUnifiedConnectDomainXMLToNative(virConnectPtr conn,
                                   const char *format,
                                   const char *xmlData,
                                   unsigned int flags)
1601 1602 1603 1604
{
    virDomainDefPtr def = NULL;
    char *ret = NULL;
    virConfPtr conf = NULL;
1605
    xenUnifiedPrivatePtr priv = conn->privateData;
1606

E
Eric Blake 已提交
1607 1608
    virCheckFlags(0, NULL);

1609 1610 1611
    if (virConnectDomainXMLToNativeEnsureACL(conn) < 0)
        return NULL;

1612 1613
    if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
        STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
1614 1615
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unsupported config type %s"), format);
1616 1617 1618
        goto cleanup;
    }

1619
    if (!(def = virDomainDefParseString(xmlData, priv->caps, priv->xmlopt,
1620
                                        NULL,
1621
                                        VIR_DOMAIN_DEF_PARSE_INACTIVE)))
1622 1623 1624 1625
        goto cleanup;

    if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
        int len = MAX_CONFIG_SIZE;
1626
        conf = xenFormatXM(conn, def);
1627 1628 1629
        if (!conf)
            goto cleanup;

1630
        if (VIR_ALLOC_N(ret, len) < 0)
1631 1632 1633 1634 1635 1636 1637
            goto cleanup;

        if (virConfWriteMem(ret, &len, conf) < 0) {
            VIR_FREE(ret);
            goto cleanup;
        }
    } else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
1638
        ret = xenFormatSxpr(conn, def);
1639 1640
    }

1641
 cleanup:
1642 1643 1644 1645 1646 1647 1648
    virDomainDefFree(def);
    if (conf)
        virConfFree(conf);
    return ret;
}


1649
static int
1650 1651 1652 1653 1654 1655 1656 1657
xenUnifiedDomainMigratePrepare(virConnectPtr dconn,
                               char **cookie,
                               int *cookielen,
                               const char *uri_in,
                               char **uri_out,
                               unsigned long flags,
                               const char *dname,
                               unsigned long resource)
1658
{
E
Eric Blake 已提交
1659 1660
    virCheckFlags(XEN_MIGRATION_FLAGS, -1);

1661 1662 1663
    return xenDaemonDomainMigratePrepare(dconn, cookie, cookielen,
                                         uri_in, uri_out,
                                         flags, dname, resource);
1664 1665 1666
}

static int
1667 1668 1669 1670 1671 1672 1673
xenUnifiedDomainMigratePerform(virDomainPtr dom,
                               const char *cookie,
                               int cookielen,
                               const char *uri,
                               unsigned long flags,
                               const char *dname,
                               unsigned long resource)
1674
{
1675 1676 1677
    virDomainDefPtr def = NULL;
    int ret = -1;

E
Eric Blake 已提交
1678 1679
    virCheckFlags(XEN_MIGRATION_FLAGS, -1);

1680 1681 1682
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1683 1684 1685
    if (virDomainMigratePerformEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1686 1687 1688 1689
    ret = xenDaemonDomainMigratePerform(dom->conn, def,
                                        cookie, cookielen, uri,
                                        flags, dname, resource);

1690
 cleanup:
1691 1692
    virDomainDefFree(def);
    return ret;
1693 1694 1695
}

static virDomainPtr
1696 1697 1698 1699 1700 1701
xenUnifiedDomainMigrateFinish(virConnectPtr dconn,
                              const char *dname,
                              const char *cookie ATTRIBUTE_UNUSED,
                              int cookielen ATTRIBUTE_UNUSED,
                              const char *uri ATTRIBUTE_UNUSED,
                              unsigned long flags)
1702
{
1703 1704 1705
    virDomainPtr ret = NULL;
    virDomainDefPtr minidef = NULL;
    virDomainDefPtr def = NULL;
1706

E
Eric Blake 已提交
1707 1708
    virCheckFlags(XEN_MIGRATION_FLAGS, NULL);

1709 1710
    if (!(minidef = xenGetDomainDefForName(dconn, dname)))
        goto cleanup;
1711

1712 1713 1714
    if (virDomainMigrateFinishEnsureACL(dconn, minidef) < 0)
        goto cleanup;

1715
    if (flags & VIR_MIGRATE_PERSIST_DEST) {
1716 1717
        if (!(def = xenDaemonDomainGetXMLDesc(dconn, minidef, NULL)))
            goto cleanup;
1718

1719 1720
        if (xenDaemonDomainDefineXML(dconn, def) < 0)
            goto cleanup;
1721 1722
    }

1723 1724 1725
    ret = virGetDomain(dconn, minidef->name, minidef->uuid);
    if (ret)
        ret->id = minidef->id;
1726

1727
 cleanup:
1728 1729 1730
    virDomainDefFree(def);
    virDomainDefFree(minidef);
    return ret;
1731 1732
}

1733
static int
1734 1735
xenUnifiedConnectListDefinedDomains(virConnectPtr conn, char **const names,
                                    int maxnames)
1736
{
1737 1738 1739
    if (virConnectListDefinedDomainsEnsureACL(conn) < 0)
        return -1;

1740
    return xenDaemonListDefinedDomains(conn, names, maxnames);
1741 1742 1743
}

static int
1744
xenUnifiedConnectNumOfDefinedDomains(virConnectPtr conn)
1745
{
1746 1747 1748
    if (virConnectNumOfDefinedDomainsEnsureACL(conn) < 0)
        return -1;

1749
    return xenDaemonNumOfDefinedDomains(conn);
1750 1751 1752
}

static int
1753
xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
1754
{
1755
    xenUnifiedPrivatePtr priv = dom->conn->privateData;
1756
    int ret = -1;
1757
    virDomainDefPtr def = NULL;
1758
    char *name = NULL;
1759

1760 1761
    virCheckFlags(0, -1);

1762 1763 1764
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1765 1766 1767
    if (virDomainCreateWithFlagsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1768
    if (!(name = xenUnifiedDomainManagedSavePath(priv, def)))
1769 1770 1771
        goto cleanup;

    if (virFileExists(name)) {
1772 1773 1774
        ret = xenDaemonDomainRestore(dom->conn, name);
        if (ret == 0)
            unlink(name);
1775 1776 1777
        goto cleanup;
    }

1778
    ret = xenDaemonDomainCreate(dom->conn, def);
1779 1780 1781

    if (ret >= 0)
        dom->id = def->id;
1782

1783
 cleanup:
1784
    virDomainDefFree(def);
1785 1786
    VIR_FREE(name);
    return ret;
1787 1788
}

1789
static int
1790
xenUnifiedDomainCreate(virDomainPtr dom)
1791 1792 1793 1794
{
    return xenUnifiedDomainCreateWithFlags(dom, 0);
}

1795
static virDomainPtr
1796
xenUnifiedDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
1797
{
1798
    xenUnifiedPrivatePtr priv = conn->privateData;
1799 1800
    virDomainDefPtr def = NULL;
    virDomainPtr ret = NULL;
1801
    unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
1802

1803 1804 1805
    virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL);

    if (flags & VIR_DOMAIN_DEFINE_VALIDATE)
1806
        parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
1807

1808
    if (!(def = virDomainDefParseString(xml, priv->caps, priv->xmlopt,
1809
                                        NULL, parse_flags)))
1810 1811
        goto cleanup;

1812 1813 1814
    if (virXMLCheckIllegalChars("name", def->name, "\n") < 0)
        goto cleanup;

1815
    if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0)
1816 1817
        goto cleanup;

1818 1819 1820
    if (xenDaemonDomainDefineXML(conn, def) < 0)
        goto cleanup;
    ret = virGetDomain(conn, def->name, def->uuid);
1821 1822 1823 1824

    if (ret)
        ret->id = -1;

1825
 cleanup:
1826 1827
    virDomainDefFree(def);
    return ret;
1828 1829
}

1830 1831 1832 1833 1834 1835
static virDomainPtr
xenUnifiedDomainDefineXML(virConnectPtr conn, const char *xml)
{
    return xenUnifiedDomainDefineXMLFlags(conn, xml, 0);
}

1836
static int
1837
xenUnifiedDomainUndefineFlags(virDomainPtr dom, unsigned int flags)
1838
{
1839 1840
    virDomainDefPtr def = NULL;
    int ret = -1;
1841

1842
    virCheckFlags(0, -1);
1843 1844 1845 1846

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1847 1848 1849
    if (virDomainUndefineFlagsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1850
    ret = xenDaemonDomainUndefine(dom->conn, def);
1851

1852
 cleanup:
1853 1854
    virDomainDefFree(def);
    return ret;
1855 1856
}

1857
static int
1858 1859
xenUnifiedDomainUndefine(virDomainPtr dom)
{
1860 1861 1862
    return xenUnifiedDomainUndefineFlags(dom, 0);
}

1863
static int
1864
xenUnifiedDomainAttachDevice(virDomainPtr dom, const char *xml)
1865
{
1866
    unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE;
1867 1868
    virDomainDefPtr def = NULL;
    int ret = -1;
1869

1870
    /*
1871 1872
     * HACK: xend does not support changing live config without also touching
     * persistent config. We add the extra flag here to make this API work
1873
     */
1874
    flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
1875

1876 1877 1878
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1879 1880 1881
    if (virDomainAttachDeviceEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1882
    ret = xenDaemonAttachDeviceFlags(dom->conn, def, xml, flags);
1883

1884
 cleanup:
1885 1886
    virDomainDefFree(def);
    return ret;
1887 1888 1889
}

static int
1890 1891
xenUnifiedDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
                                  unsigned int flags)
1892
{
1893 1894 1895 1896 1897
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1898

1899 1900 1901
    if (virDomainAttachDeviceFlagsEnsureACL(dom->conn, def, flags) < 0)
        goto cleanup;

1902
    ret = xenDaemonAttachDeviceFlags(dom->conn, def, xml, flags);
1903

1904
 cleanup:
1905 1906
    virDomainDefFree(def);
    return ret;
1907 1908 1909
}

static int
1910
xenUnifiedDomainDetachDevice(virDomainPtr dom, const char *xml)
1911
{
1912
    unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE;
1913 1914
    virDomainDefPtr def = NULL;
    int ret = -1;
1915

1916
    /*
1917 1918
     * HACK: xend does not support changing live config without also touching
     * persistent config. We add the extra flag here to make this API work
1919
     */
1920
    flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
1921

1922 1923 1924
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1925 1926 1927
    if (virDomainDetachDeviceEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1928
    ret = xenDaemonDetachDeviceFlags(dom->conn, def, xml, flags);
1929

1930
 cleanup:
1931 1932
    virDomainDefFree(def);
    return ret;
1933 1934 1935
}

static int
1936 1937
xenUnifiedDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
                                  unsigned int flags)
1938
{
1939 1940 1941 1942 1943
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1944

1945 1946 1947
    if (virDomainDetachDeviceFlagsEnsureACL(dom->conn, def, flags) < 0)
        goto cleanup;

1948
    ret = xenDaemonDetachDeviceFlags(dom->conn, def, xml, flags);
1949

1950
 cleanup:
1951 1952
    virDomainDefFree(def);
    return ret;
1953 1954
}

1955
static int
1956 1957
xenUnifiedDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
                                  unsigned int flags)
1958
{
1959 1960 1961 1962 1963 1964
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

1965 1966 1967
    if (virDomainUpdateDeviceFlagsEnsureACL(dom->conn, def, flags) < 0)
        goto cleanup;

1968 1969
    ret = xenDaemonUpdateDeviceFlags(dom->conn, def, xml, flags);

1970
 cleanup:
1971 1972
    virDomainDefFree(def);
    return ret;
1973 1974
}

1975
static int
1976
xenUnifiedDomainGetAutostart(virDomainPtr dom, int *autostart)
1977
{
1978 1979 1980 1981 1982
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
1983

1984 1985 1986
    if (virDomainGetAutostartEnsureACL(dom->conn, def) < 0)
        goto cleanup;

1987
    ret = xenDaemonDomainGetAutostart(dom->conn, def, autostart);
1988

1989
 cleanup:
1990 1991
    virDomainDefFree(def);
    return ret;
1992 1993 1994
}

static int
1995
xenUnifiedDomainSetAutostart(virDomainPtr dom, int autostart)
1996
{
1997 1998 1999 2000 2001
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
2002

2003 2004 2005
    if (virDomainSetAutostartEnsureACL(dom->conn, def) < 0)
        goto cleanup;

2006
    ret = xenDaemonDomainSetAutostart(dom->conn, def, autostart);
2007

2008
 cleanup:
2009 2010
    virDomainDefFree(def);
    return ret;
2011 2012
}

2013
static char *
2014
xenUnifiedDomainGetSchedulerType(virDomainPtr dom, int *nparams)
2015
{
2016 2017 2018 2019 2020
    virDomainDefPtr def = NULL;
    char *ret = NULL;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;
2021

2022 2023 2024
    if (virDomainGetSchedulerTypeEnsureACL(dom->conn, def) < 0)
        goto cleanup;

2025
    if (dom->id < 0)
2026
        ret = xenDaemonGetSchedulerType(dom->conn, nparams);
2027
    else
2028 2029
        ret = xenHypervisorGetSchedulerType(dom->conn, nparams);

2030
 cleanup:
2031 2032
    virDomainDefFree(def);
    return ret;
2033 2034 2035
}

static int
2036 2037 2038 2039
xenUnifiedDomainGetSchedulerParametersFlags(virDomainPtr dom,
                                            virTypedParameterPtr params,
                                            int *nparams,
                                            unsigned int flags)
2040
{
2041 2042
    virDomainDefPtr def = NULL;
    int ret = -1;
2043

2044 2045
    virCheckFlags(0, -1);

2046 2047 2048
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

2049 2050 2051
    if (virDomainGetSchedulerParametersFlagsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

2052
    if (dom->id < 0)
2053
        ret = xenDaemonGetSchedulerParameters(dom->conn, def, params, nparams);
2054
    else
2055 2056
        ret = xenHypervisorGetSchedulerParameters(dom->conn, def, params, nparams);

2057
 cleanup:
2058 2059
    virDomainDefFree(def);
    return ret;
2060 2061 2062
}

static int
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
xenUnifiedDomainGetSchedulerParameters(virDomainPtr dom,
                                       virTypedParameterPtr params,
                                       int *nparams)
{
    return xenUnifiedDomainGetSchedulerParametersFlags(dom, params,
                                                       nparams, 0);
}

static int
xenUnifiedDomainSetSchedulerParametersFlags(virDomainPtr dom,
                                            virTypedParameterPtr params,
                                            int nparams,
                                            unsigned int flags)
2076
{
2077 2078
    virDomainDefPtr def = NULL;
    int ret = -1;
2079

2080 2081
    virCheckFlags(0, -1);

2082 2083 2084
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

2085 2086 2087
    if (virDomainSetSchedulerParametersFlagsEnsureACL(dom->conn, def, flags) < 0)
        goto cleanup;

2088
    if (dom->id < 0)
2089
        ret = xenDaemonSetSchedulerParameters(dom->conn, def, params, nparams);
2090
    else
2091 2092
        ret = xenHypervisorSetSchedulerParameters(dom->conn, def, params, nparams);

2093
 cleanup:
2094 2095
    virDomainDefFree(def);
    return ret;
2096 2097
}

2098 2099 2100 2101 2102 2103 2104 2105 2106
static int
xenUnifiedDomainSetSchedulerParameters(virDomainPtr dom,
                                       virTypedParameterPtr params,
                                       int nparams)
{
    return xenUnifiedDomainSetSchedulerParametersFlags(dom, params,
                                                       nparams, 0);
}

2107
static int
2108
xenUnifiedDomainBlockStats(virDomainPtr dom, const char *path,
2109
                           virDomainBlockStatsPtr stats)
2110
{
2111 2112 2113 2114 2115 2116
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

2117 2118 2119
    if (virDomainBlockStatsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

2120 2121
    ret = xenHypervisorDomainBlockStats(dom->conn, def, path, stats);

2122
 cleanup:
2123 2124
    virDomainDefFree(def);
    return ret;
2125 2126 2127
}

static int
2128
xenUnifiedDomainInterfaceStats(virDomainPtr dom, const char *path,
2129
                               virDomainInterfaceStatsPtr stats)
2130
{
2131 2132 2133 2134 2135 2136
    virDomainDefPtr def = NULL;
    int ret = -1;

    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

2137 2138 2139
    if (virDomainInterfaceStatsEnsureACL(dom->conn, def) < 0)
        goto cleanup;

2140 2141
    ret = xenHypervisorDomainInterfaceStats(def, path, stats);

2142
 cleanup:
2143 2144
    virDomainDefFree(def);
    return ret;
2145 2146
}

R
Richard W.M. Jones 已提交
2147
static int
2148 2149 2150
xenUnifiedDomainBlockPeek(virDomainPtr dom, const char *path,
                          unsigned long long offset, size_t size,
                          void *buffer, unsigned int flags)
R
Richard W.M. Jones 已提交
2151
{
2152 2153
    virDomainDefPtr def = NULL;
    int ret = -1;
R
Richard W.M. Jones 已提交
2154

E
Eric Blake 已提交
2155 2156
    virCheckFlags(0, -1);

2157 2158 2159
    if (!(def = xenGetDomainDefForDom(dom)))
        goto cleanup;

2160 2161 2162
    if (virDomainBlockPeekEnsureACL(dom->conn, def) < 0)
        goto cleanup;

2163
    ret = xenDaemonDomainBlockPeek(dom->conn, def, path, offset, size, buffer);
2164

2165
 cleanup:
2166 2167
    virDomainDefFree(def);
    return ret;
R
Richard W.M. Jones 已提交
2168 2169
}

2170
static int
2171 2172
xenUnifiedNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems,
                                 int startCell, int maxCells)
2173
{
2174 2175 2176
    if (virNodeGetCellsFreeMemoryEnsureACL(conn) < 0)
        return 0;

2177 2178
    return xenHypervisorNodeGetCellsFreeMemory(conn, freeMems,
                                               startCell, maxCells);
2179 2180
}

2181
static unsigned long long
2182
xenUnifiedNodeGetFreeMemory(virConnectPtr conn)
2183 2184 2185
{
    unsigned long long freeMem = 0;

2186 2187 2188
    if (virNodeGetFreeMemoryEnsureACL(conn) < 0)
        return 0;

2189 2190 2191
    if (xenHypervisorNodeGetCellsFreeMemory(conn, &freeMem, -1, 1) < 0)
        return 0;
    return freeMem;
2192 2193
}

2194

2195
static int
2196 2197 2198 2199
xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
                                     virConnectDomainEventCallback callback,
                                     void *opaque,
                                     virFreeCallback freefunc)
2200
{
2201
    xenUnifiedPrivatePtr priv = conn->privateData;
2202
    int ret = 0;
2203 2204 2205 2206

    if (virConnectDomainEventRegisterEnsureACL(conn) < 0)
        return -1;

D
Daniel P. Berrange 已提交
2207
    xenUnifiedLock(priv);
2208

2209
    if (priv->xsWatch == -1) {
2210
        virReportUnsupportedError();
D
Daniel P. Berrange 已提交
2211
        xenUnifiedUnlock(priv);
2212 2213 2214
        return -1;
    }

2215 2216 2217
    if (virDomainEventStateRegister(conn, priv->domainEvents,
                                    callback, opaque, freefunc) < 0)
        ret = -1;
2218

D
Daniel P. Berrange 已提交
2219
    xenUnifiedUnlock(priv);
2220
    return ret;
2221 2222
}

2223

2224
static int
2225 2226
xenUnifiedConnectDomainEventDeregister(virConnectPtr conn,
                                       virConnectDomainEventCallback callback)
2227
{
2228
    int ret = 0;
2229
    xenUnifiedPrivatePtr priv = conn->privateData;
2230 2231 2232 2233

    if (virConnectDomainEventDeregisterEnsureACL(conn) < 0)
        return -1;

D
Daniel P. Berrange 已提交
2234 2235
    xenUnifiedLock(priv);

2236
    if (priv->xsWatch == -1) {
2237
        virReportUnsupportedError();
D
Daniel P. Berrange 已提交
2238
        xenUnifiedUnlock(priv);
2239 2240 2241
        return -1;
    }

2242 2243 2244 2245
    if (virDomainEventStateDeregister(conn,
                                      priv->domainEvents,
                                      callback) < 0)
        ret = -1;
2246

D
Daniel P. Berrange 已提交
2247
    xenUnifiedUnlock(priv);
2248 2249 2250
    return ret;
}

2251

2252
static int
2253 2254 2255 2256 2257 2258
xenUnifiedConnectDomainEventRegisterAny(virConnectPtr conn,
                                        virDomainPtr dom,
                                        int eventID,
                                        virConnectDomainEventGenericCallback callback,
                                        void *opaque,
                                        virFreeCallback freefunc)
2259
{
2260
    xenUnifiedPrivatePtr priv = conn->privateData;
2261
    int ret;
2262 2263 2264 2265

    if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0)
        return -1;

2266 2267 2268
    xenUnifiedLock(priv);

    if (priv->xsWatch == -1) {
2269
        virReportUnsupportedError();
2270 2271 2272 2273
        xenUnifiedUnlock(priv);
        return -1;
    }

2274 2275 2276
    if (virDomainEventStateRegisterID(conn, priv->domainEvents,
                                      dom, eventID,
                                      callback, opaque, freefunc, &ret) < 0)
2277
        ret = -1;
2278 2279

    xenUnifiedUnlock(priv);
2280
    return ret;
2281 2282 2283
}

static int
2284 2285
xenUnifiedConnectDomainEventDeregisterAny(virConnectPtr conn,
                                          int callbackID)
2286
{
2287
    int ret = 0;
2288
    xenUnifiedPrivatePtr priv = conn->privateData;
2289 2290 2291 2292

    if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
        return -1;

2293 2294 2295
    xenUnifiedLock(priv);

    if (priv->xsWatch == -1) {
2296
        virReportUnsupportedError();
2297 2298 2299 2300
        xenUnifiedUnlock(priv);
        return -1;
    }

2301 2302 2303 2304
    if (virObjectEventStateDeregisterID(conn,
                                        priv->domainEvents,
                                        callbackID) < 0)
        ret = -1;
2305 2306 2307 2308 2309 2310

    xenUnifiedUnlock(priv);
    return ret;
}


2311
static int
2312
xenUnifiedNodeDeviceGetPCIInfo(virNodeDevicePtr dev,
2313 2314 2315 2316
                               unsigned *domain,
                               unsigned *bus,
                               unsigned *slot,
                               unsigned *function)
2317 2318 2319 2320 2321 2322 2323 2324 2325 2326
{
    virNodeDeviceDefPtr def = NULL;
    virNodeDevCapsDefPtr cap;
    char *xml = NULL;
    int ret = -1;

    xml = virNodeDeviceGetXMLDesc(dev, 0);
    if (!xml)
        goto out;

2327
    def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
2328 2329 2330 2331 2332
    if (!def)
        goto out;

    cap = def->caps;
    while (cap) {
2333
        if (cap->data.type == VIR_NODE_DEV_CAP_PCI_DEV) {
2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344
            *domain   = cap->data.pci_dev.domain;
            *bus      = cap->data.pci_dev.bus;
            *slot     = cap->data.pci_dev.slot;
            *function = cap->data.pci_dev.function;
            break;
        }

        cap = cap->next;
    }

    if (!cap) {
2345 2346
        virReportError(VIR_ERR_INVALID_ARG,
                       _("device %s is not a PCI device"), dev->name);
2347 2348 2349 2350
        goto out;
    }

    ret = 0;
2351
 out:
2352 2353 2354 2355 2356 2357
    virNodeDeviceDefFree(def);
    VIR_FREE(xml);
    return ret;
}

static int
2358 2359 2360
xenUnifiedNodeDeviceDetachFlags(virNodeDevicePtr dev,
                                const char *driverName,
                                unsigned int flags)
2361
{
2362
    virPCIDevicePtr pci;
2363 2364 2365
    unsigned domain, bus, slot, function;
    int ret = -1;

2366 2367
    virCheckFlags(0, -1);

2368
    if (xenUnifiedNodeDeviceGetPCIInfo(dev, &domain, &bus, &slot, &function) < 0)
2369 2370
        return -1;

2371
    pci = virPCIDeviceNew(domain, bus, slot, function);
2372 2373 2374
    if (!pci)
        return -1;

2375
    if (!driverName) {
2376
        virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
2377 2378 2379 2380 2381 2382
    } else {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unknown driver name '%s'"), driverName);
        goto out;
    }

2383
    if (virPCIDeviceDetach(pci, NULL, NULL) < 0)
2384 2385 2386
        goto out;

    ret = 0;
2387
 out:
2388
    virPCIDeviceFree(pci);
2389 2390 2391
    return ret;
}

2392 2393 2394 2395 2396 2397
static int
xenUnifiedNodeDeviceDettach(virNodeDevicePtr dev)
{
    return xenUnifiedNodeDeviceDetachFlags(dev, NULL, 0);
}

2398
static int
2399
xenUnifiedNodeDeviceAssignedDomainId(virNodeDevicePtr dev)
2400 2401
{
    int numdomains;
2402 2403
    int ret = -1;
    size_t i;
2404 2405 2406 2407 2408 2409 2410 2411
    int *ids = NULL;
    char *bdf = NULL;
    char *xref = NULL;
    unsigned int domain, bus, slot, function;
    virConnectPtr conn = dev->conn;
    xenUnifiedPrivatePtr priv = conn->privateData;

    /* Get active domains */
2412
    numdomains = xenUnifiedConnectNumOfDomains(conn);
2413
    if (numdomains < 0)
2414
        return ret;
2415
    if (numdomains > 0) {
2416
        if (VIR_ALLOC_N(ids, numdomains) < 0)
2417
            goto out;
2418
        if ((numdomains = xenUnifiedConnectListDomains(conn, &ids[0], numdomains)) < 0)
2419 2420 2421 2422
            goto out;
    }

    /* Get pci bdf */
2423
    if (xenUnifiedNodeDeviceGetPCIInfo(dev, &domain, &bus, &slot, &function) < 0)
2424 2425 2426
        goto out;

    if (virAsprintf(&bdf, "%04x:%02x:%02x.%0x",
2427
                    domain, bus, slot, function) < 0)
2428 2429 2430 2431
        goto out;

    xenUnifiedLock(priv);
    /* Check if bdf is assigned to one of active domains */
2432
    for (i = 0; i < numdomains; i++) {
2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444
        xref = xenStoreDomainGetPCIID(conn, ids[i], bdf);
        if (xref == NULL) {
            continue;
        } else {
            ret = ids[i];
            break;
        }
    }
    xenUnifiedUnlock(priv);

    VIR_FREE(xref);
    VIR_FREE(bdf);
2445
 out:
2446 2447 2448 2449 2450
    VIR_FREE(ids);

    return ret;
}

2451
static int
2452
xenUnifiedNodeDeviceReAttach(virNodeDevicePtr dev)
2453
{
2454
    virPCIDevicePtr pci;
2455 2456
    unsigned domain, bus, slot, function;
    int ret = -1;
2457
    int domid;
2458

2459
    if (xenUnifiedNodeDeviceGetPCIInfo(dev, &domain, &bus, &slot, &function) < 0)
2460 2461
        return -1;

2462
    pci = virPCIDeviceNew(domain, bus, slot, function);
2463 2464 2465
    if (!pci)
        return -1;

2466 2467
    /* Check if device is assigned to an active guest */
    if ((domid = xenUnifiedNodeDeviceAssignedDomainId(dev)) >= 0) {
2468 2469 2470
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Device %s has been assigned to guest %d"),
                       dev->name, domid);
2471 2472 2473
        goto out;
    }

2474
    if (virPCIDeviceReattach(pci, NULL, NULL) < 0)
2475 2476 2477
        goto out;

    ret = 0;
2478
 out:
2479
    virPCIDeviceFree(pci);
2480 2481 2482 2483
    return ret;
}

static int
2484
xenUnifiedNodeDeviceReset(virNodeDevicePtr dev)
2485
{
2486
    virPCIDevicePtr pci;
2487 2488 2489
    unsigned domain, bus, slot, function;
    int ret = -1;

2490
    if (xenUnifiedNodeDeviceGetPCIInfo(dev, &domain, &bus, &slot, &function) < 0)
2491 2492
        return -1;

2493
    pci = virPCIDeviceNew(domain, bus, slot, function);
2494 2495 2496
    if (!pci)
        return -1;

2497
    if (virPCIDeviceReset(pci, NULL, NULL) < 0)
2498 2499 2500
        goto out;

    ret = 0;
2501
 out:
2502
    virPCIDeviceFree(pci);
2503 2504 2505 2506
    return ret;
}


2507 2508
static int
xenUnifiedDomainOpenConsole(virDomainPtr dom,
2509
                            const char *dev_name,
2510 2511 2512 2513 2514 2515 2516 2517 2518 2519
                            virStreamPtr st,
                            unsigned int flags)
{
    virDomainDefPtr def = NULL;
    int ret = -1;
    virDomainChrDefPtr chr = NULL;

    virCheckFlags(0, -1);

    if (dom->id == -1) {
2520 2521
        virReportError(VIR_ERR_OPERATION_INVALID,
                       "%s", _("domain is not running"));
2522 2523 2524
        goto cleanup;
    }

2525
    if (dev_name) {
2526
        /* XXX support device aliases in future */
2527 2528
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Named device aliases are not supported"));
2529 2530 2531 2532 2533 2534 2535
        goto cleanup;
    }

    def = xenDaemonDomainFetch(dom->conn, dom->id, dom->name, NULL);
    if (!def)
        goto cleanup;

2536 2537
    if (def->nconsoles)
        chr = def->consoles[0];
2538 2539 2540 2541
    else if (def->nserials)
        chr = def->serials[0];

    if (!chr) {
2542 2543
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("cannot find default console device"));
2544 2545 2546
        goto cleanup;
    }

2547
    if (chr->source->type != VIR_DOMAIN_CHR_TYPE_PTY) {
2548
        virReportError(VIR_ERR_INTERNAL_ERROR,
2549 2550
                       _("character device %s is not using a PTY"),
                       dev_name ? dev_name : NULLSTR(chr->info.alias));
2551 2552 2553
        goto cleanup;
    }

2554
    if (virFDStreamOpenFile(st, chr->source->data.file.path,
E
Eric Blake 已提交
2555
                            0, 0, O_RDWR) < 0)
2556 2557 2558
        goto cleanup;

    ret = 0;
2559
 cleanup:
2560 2561 2562
    virDomainDefFree(def);
    return ret;
}
2563 2564

static int
2565
xenUnifiedNodeGetMemoryParameters(virConnectPtr conn,
2566 2567 2568 2569
                                  virTypedParameterPtr params,
                                  int *nparams,
                                  unsigned int flags)
{
2570 2571 2572
    if (virNodeGetMemoryParametersEnsureACL(conn) < 0)
        return -1;

2573
    return virHostMemGetParameters(params, nparams, flags);
2574 2575 2576 2577
}


static int
2578
xenUnifiedNodeSetMemoryParameters(virConnectPtr conn,
2579 2580 2581 2582
                                  virTypedParameterPtr params,
                                  int nparams,
                                  unsigned int flags)
{
2583 2584 2585
    if (virNodeSetMemoryParametersEnsureACL(conn) < 0)
        return -1;

2586
    return virHostMemSetParameters(params, nparams, flags);
2587 2588
}

2589 2590

static int
2591
xenUnifiedNodeSuspendForDuration(virConnectPtr conn,
2592 2593 2594 2595
                                 unsigned int target,
                                 unsigned long long duration,
                                 unsigned int flags)
{
2596 2597 2598
    if (virNodeSuspendForDurationEnsureACL(conn) < 0)
        return -1;

2599
    return virNodeSuspend(target, duration, flags);
2600 2601 2602
}


E
Eric Blake 已提交
2603
/*----- Register with libvirt.c, and initialize Xen drivers. -----*/
2604 2605

/* The interface which we export upwards to libvirt.c. */
2606
static virHypervisorDriver xenUnifiedHypervisorDriver = {
2607
    .name = "Xen",
2608 2609 2610 2611 2612
    .connectOpen = xenUnifiedConnectOpen, /* 0.0.3 */
    .connectClose = xenUnifiedConnectClose, /* 0.0.3 */
    .connectSupportsFeature = xenUnifiedConnectSupportsFeature, /* 0.3.2 */
    .connectGetType = xenUnifiedConnectGetType, /* 0.0.3 */
    .connectGetVersion = xenUnifiedConnectGetVersion, /* 0.0.3 */
2613
    .connectGetHostname = xenUnifiedConnectGetHostname, /* 0.7.3 */
2614
    .connectGetSysinfo = xenUnifiedConnectGetSysinfo, /* 1.1.0 */
2615
    .connectGetMaxVcpus = xenUnifiedConnectGetMaxVcpus, /* 0.2.1 */
2616
    .nodeGetInfo = xenUnifiedNodeGetInfo, /* 0.1.0 */
2617 2618 2619
    .connectGetCapabilities = xenUnifiedConnectGetCapabilities, /* 0.2.1 */
    .connectListDomains = xenUnifiedConnectListDomains, /* 0.0.3 */
    .connectNumOfDomains = xenUnifiedConnectNumOfDomains, /* 0.0.3 */
2620 2621 2622 2623 2624 2625 2626
    .domainCreateXML = xenUnifiedDomainCreateXML, /* 0.0.3 */
    .domainLookupByID = xenUnifiedDomainLookupByID, /* 0.0.3 */
    .domainLookupByUUID = xenUnifiedDomainLookupByUUID, /* 0.0.5 */
    .domainLookupByName = xenUnifiedDomainLookupByName, /* 0.0.3 */
    .domainSuspend = xenUnifiedDomainSuspend, /* 0.0.3 */
    .domainResume = xenUnifiedDomainResume, /* 0.0.3 */
    .domainShutdown = xenUnifiedDomainShutdown, /* 0.0.3 */
2627
    .domainShutdownFlags = xenUnifiedDomainShutdownFlags, /* 0.9.10 */
2628 2629
    .domainReboot = xenUnifiedDomainReboot, /* 0.1.0 */
    .domainDestroy = xenUnifiedDomainDestroy, /* 0.0.3 */
2630
    .domainDestroyFlags = xenUnifiedDomainDestroyFlags, /* 0.9.4 */
2631 2632 2633 2634 2635 2636 2637
    .domainGetOSType = xenUnifiedDomainGetOSType, /* 0.0.3 */
    .domainGetMaxMemory = xenUnifiedDomainGetMaxMemory, /* 0.0.3 */
    .domainSetMaxMemory = xenUnifiedDomainSetMaxMemory, /* 0.0.3 */
    .domainSetMemory = xenUnifiedDomainSetMemory, /* 0.1.1 */
    .domainGetInfo = xenUnifiedDomainGetInfo, /* 0.0.3 */
    .domainGetState = xenUnifiedDomainGetState, /* 0.9.2 */
    .domainSave = xenUnifiedDomainSave, /* 0.0.3 */
2638
    .domainSaveFlags = xenUnifiedDomainSaveFlags, /* 0.9.4 */
2639 2640 2641
    .domainManagedSave = xenUnifiedDomainManagedSave, /* 1.0.1 */
    .domainHasManagedSaveImage = xenUnifiedDomainHasManagedSaveImage, /* 1.0.1 */
    .domainManagedSaveRemove = xenUnifiedDomainManagedSaveRemove, /* 1.0.1 */
2642
    .domainRestore = xenUnifiedDomainRestore, /* 0.0.3 */
2643
    .domainRestoreFlags = xenUnifiedDomainRestoreFlags, /* 0.9.4 */
2644 2645 2646 2647 2648 2649 2650 2651
    .domainCoreDump = xenUnifiedDomainCoreDump, /* 0.1.9 */
    .domainSetVcpus = xenUnifiedDomainSetVcpus, /* 0.1.4 */
    .domainSetVcpusFlags = xenUnifiedDomainSetVcpusFlags, /* 0.8.5 */
    .domainGetVcpusFlags = xenUnifiedDomainGetVcpusFlags, /* 0.8.5 */
    .domainPinVcpu = xenUnifiedDomainPinVcpu, /* 0.1.4 */
    .domainGetVcpus = xenUnifiedDomainGetVcpus, /* 0.1.4 */
    .domainGetMaxVcpus = xenUnifiedDomainGetMaxVcpus, /* 0.2.1 */
    .domainGetXMLDesc = xenUnifiedDomainGetXMLDesc, /* 0.0.3 */
2652 2653 2654 2655
    .connectDomainXMLFromNative = xenUnifiedConnectDomainXMLFromNative, /* 0.6.4 */
    .connectDomainXMLToNative = xenUnifiedConnectDomainXMLToNative, /* 0.6.4 */
    .connectListDefinedDomains = xenUnifiedConnectListDefinedDomains, /* 0.1.1 */
    .connectNumOfDefinedDomains = xenUnifiedConnectNumOfDefinedDomains, /* 0.1.5 */
2656 2657 2658
    .domainCreate = xenUnifiedDomainCreate, /* 0.1.1 */
    .domainCreateWithFlags = xenUnifiedDomainCreateWithFlags, /* 0.8.2 */
    .domainDefineXML = xenUnifiedDomainDefineXML, /* 0.1.1 */
2659
    .domainDefineXMLFlags = xenUnifiedDomainDefineXMLFlags, /* 1.2.12 */
2660
    .domainUndefine = xenUnifiedDomainUndefine, /* 0.1.1 */
2661
    .domainUndefineFlags = xenUnifiedDomainUndefineFlags, /* 0.9.4 */
2662 2663 2664 2665 2666 2667 2668 2669 2670
    .domainAttachDevice = xenUnifiedDomainAttachDevice, /* 0.1.9 */
    .domainAttachDeviceFlags = xenUnifiedDomainAttachDeviceFlags, /* 0.7.7 */
    .domainDetachDevice = xenUnifiedDomainDetachDevice, /* 0.1.9 */
    .domainDetachDeviceFlags = xenUnifiedDomainDetachDeviceFlags, /* 0.7.7 */
    .domainUpdateDeviceFlags = xenUnifiedDomainUpdateDeviceFlags, /* 0.8.0 */
    .domainGetAutostart = xenUnifiedDomainGetAutostart, /* 0.4.4 */
    .domainSetAutostart = xenUnifiedDomainSetAutostart, /* 0.4.4 */
    .domainGetSchedulerType = xenUnifiedDomainGetSchedulerType, /* 0.2.3 */
    .domainGetSchedulerParameters = xenUnifiedDomainGetSchedulerParameters, /* 0.2.3 */
2671
    .domainGetSchedulerParametersFlags = xenUnifiedDomainGetSchedulerParametersFlags, /* 0.9.2 */
2672
    .domainSetSchedulerParameters = xenUnifiedDomainSetSchedulerParameters, /* 0.2.3 */
2673
    .domainSetSchedulerParametersFlags = xenUnifiedDomainSetSchedulerParametersFlags, /* 0.9.2 */
2674 2675 2676 2677 2678 2679 2680 2681
    .domainMigratePrepare = xenUnifiedDomainMigratePrepare, /* 0.3.2 */
    .domainMigratePerform = xenUnifiedDomainMigratePerform, /* 0.3.2 */
    .domainMigrateFinish = xenUnifiedDomainMigrateFinish, /* 0.3.2 */
    .domainBlockStats = xenUnifiedDomainBlockStats, /* 0.3.2 */
    .domainInterfaceStats = xenUnifiedDomainInterfaceStats, /* 0.3.2 */
    .domainBlockPeek = xenUnifiedDomainBlockPeek, /* 0.4.4 */
    .nodeGetCellsFreeMemory = xenUnifiedNodeGetCellsFreeMemory, /* 0.3.3 */
    .nodeGetFreeMemory = xenUnifiedNodeGetFreeMemory, /* 0.3.3 */
2682 2683
    .connectDomainEventRegister = xenUnifiedConnectDomainEventRegister, /* 0.5.0 */
    .connectDomainEventDeregister = xenUnifiedConnectDomainEventDeregister, /* 0.5.0 */
2684
    .nodeDeviceDettach = xenUnifiedNodeDeviceDettach, /* 0.6.1 */
2685
    .nodeDeviceDetachFlags = xenUnifiedNodeDeviceDetachFlags, /* 1.0.5 */
2686 2687
    .nodeDeviceReAttach = xenUnifiedNodeDeviceReAttach, /* 0.6.1 */
    .nodeDeviceReset = xenUnifiedNodeDeviceReset, /* 0.6.1 */
2688 2689
    .connectIsEncrypted = xenUnifiedConnectIsEncrypted, /* 0.7.3 */
    .connectIsSecure = xenUnifiedConnectIsSecure, /* 0.7.3 */
2690 2691 2692
    .domainIsActive = xenUnifiedDomainIsActive, /* 0.7.3 */
    .domainIsPersistent = xenUnifiedDomainIsPersistent, /* 0.7.3 */
    .domainIsUpdated = xenUnifiedDomainIsUpdated, /* 0.8.6 */
2693 2694
    .connectDomainEventRegisterAny = xenUnifiedConnectDomainEventRegisterAny, /* 0.8.0 */
    .connectDomainEventDeregisterAny = xenUnifiedConnectDomainEventDeregisterAny, /* 0.8.0 */
2695
    .domainOpenConsole = xenUnifiedDomainOpenConsole, /* 0.8.6 */
2696
    .connectIsAlive = xenUnifiedConnectIsAlive, /* 0.9.8 */
2697
    .nodeSuspendForDuration = xenUnifiedNodeSuspendForDuration, /* 0.9.8 */
2698 2699
    .nodeGetMemoryParameters = xenUnifiedNodeGetMemoryParameters, /* 0.10.2 */
    .nodeSetMemoryParameters = xenUnifiedNodeSetMemoryParameters, /* 0.10.2 */
2700 2701
};

2702 2703 2704 2705 2706

static virConnectDriver xenUnifiedConnectDriver = {
    .hypervisorDriver = &xenUnifiedHypervisorDriver,
};

2707
/**
2708
 * xenRegister:
2709 2710 2711 2712 2713
 *
 * Register xen related drivers
 *
 * Returns the driver priority or -1 in case of error.
 */
2714
int
2715
xenRegister(void)
2716
{
2717
    if (virRegisterStateDriver(&state_driver) == -1) return -1;
J
John Levon 已提交
2718

2719 2720
    return virRegisterConnectDriver(&xenUnifiedConnectDriver,
                                    true);
2721 2722
}

2723 2724 2725 2726 2727 2728 2729 2730
/**
 * xenUnifiedDomainInfoListFree:
 *
 * Free the Domain Info List
 */
void
xenUnifiedDomainInfoListFree(xenUnifiedDomainInfoListPtr list)
{
2731
    size_t i;
J
John Levon 已提交
2732 2733 2734 2735

    if (list == NULL)
        return;

2736
    for (i = 0; i < list->count; i++) {
2737 2738 2739
        VIR_FREE(list->doms[i]->name);
        VIR_FREE(list->doms[i]);
    }
2740
    VIR_FREE(list->doms);
2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759
    VIR_FREE(list);
}

/**
 * xenUnifiedAddDomainInfo:
 *
 * Add name and uuid to the domain info list
 *
 * Returns: 0 on success, -1 on failure
 */
int
xenUnifiedAddDomainInfo(xenUnifiedDomainInfoListPtr list,
                        int id, char *name,
                        unsigned char *uuid)
{
    xenUnifiedDomainInfoPtr info;
    int n;

    /* check if we already have this callback on our list */
2760
    for (n = 0; n < list->count; n++) {
2761 2762
        if (STREQ(list->doms[n]->name, name) &&
            !memcmp(list->doms[n]->uuid, uuid, VIR_UUID_BUFLEN)) {
2763
            VIR_DEBUG("WARNING: dom already tracked");
2764 2765 2766 2767 2768
            return -1;
        }
    }

    if (VIR_ALLOC(info) < 0)
2769
        goto error;
2770 2771
    if (VIR_STRDUP(info->name, name) < 0)
        goto error;
2772 2773 2774 2775 2776

    memcpy(info->uuid, uuid, VIR_UUID_BUFLEN);
    info->id = id;

    /* Make space on list */
2777
    if (VIR_APPEND_ELEMENT(list->doms, list->count, info) < 0)
2778
        goto error;
2779 2780

    return 0;
2781
 error:
2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799
    if (info)
        VIR_FREE(info->name);
    VIR_FREE(info);
    return -1;
}

/**
 * xenUnifiedRemoveDomainInfo:
 *
 * Removes name and uuid to the domain info list
 *
 * Returns: 0 on success, -1 on failure
 */
int
xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr list,
                           int id, char *name,
                           unsigned char *uuid)
{
2800
    size_t i;
2801
    for (i = 0; i < list->count; i++) {
2802
        if (list->doms[i]->id == id &&
2803 2804 2805 2806 2807 2808
            STREQ(list->doms[i]->name, name) &&
            !memcmp(list->doms[i]->uuid, uuid, VIR_UUID_BUFLEN)) {

            VIR_FREE(list->doms[i]->name);
            VIR_FREE(list->doms[i]);

2809
            VIR_DELETE_ELEMENT(list->doms, i, list->count);
2810 2811 2812 2813 2814 2815
            return 0;
        }
    }
    return -1;
}

2816

2817 2818
/**
 * xenUnifiedDomainEventDispatch:
D
Daniel P. Berrange 已提交
2819 2820
 * @priv: the connection to dispatch events on
 * @event: the event to dispatch
2821 2822 2823
 *
 * Dispatch domain events to registered callbacks
 *
D
Daniel P. Berrange 已提交
2824 2825
 * The caller must hold the lock in 'priv' before invoking
 *
2826
 */
2827
void xenUnifiedDomainEventDispatch(xenUnifiedPrivatePtr priv,
2828
                                    virObjectEventPtr event)
2829
{
D
Daniel P. Berrange 已提交
2830
    if (!priv)
2831
        return;
2832

2833
    virObjectEventStateQueue(priv->domainEvents, event);
D
Daniel P. Berrange 已提交
2834 2835 2836 2837 2838 2839 2840 2841 2842 2843
}

void xenUnifiedLock(xenUnifiedPrivatePtr priv)
{
    virMutexLock(&priv->lock);
}

void xenUnifiedUnlock(xenUnifiedPrivatePtr priv)
{
    virMutexUnlock(&priv->lock);
2844
}