qemu_capabilities.c 146.5 KB
Newer Older
1 2 3
/*
 * qemu_capabilities.c: QEMU capabilities generation
 *
4
 * Copyright (C) 2006-2016 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
20 21 22 23 24 25 26
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

#include "qemu_capabilities.h"
27
#include "viralloc.h"
28
#include "vircrypto.h"
29
#include "virlog.h"
30
#include "virerror.h"
E
Eric Blake 已提交
31
#include "virfile.h"
32 33
#include "virpidfile.h"
#include "virprocess.h"
34 35 36
#include "nodeinfo.h"
#include "cpu/cpu.h"
#include "domain_conf.h"
37
#include "vircommand.h"
38
#include "virbitmap.h"
39
#include "virnodesuspend.h"
40
#include "virnuma.h"
41
#include "virhostcpu.h"
42
#include "qemu_monitor.h"
43
#include "virstring.h"
44
#include "qemu_hostdev.h"
45
#include "qemu_domain.h"
46 47
#define __QEMU_CAPSRIV_H_ALLOW__
#include "qemu_capspriv.h"
48

49
#include <fcntl.h>
50 51 52
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
53
#include <stdarg.h>
54 55 56

#define VIR_FROM_THIS VIR_FROM_QEMU

57 58
VIR_LOG_INIT("qemu.qemu_capabilities");

59 60 61 62
/* While not public, these strings must not change. They
 * are used in domain status files which are read on
 * daemon restarts
 */
63
VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
              "kqemu",  /* 0 */
              "vnc-colon",
              "no-reboot",
              "drive",
              "drive-boot",

              "name", /* 5 */
              "uuid",
              "domid",
              "vnet-hdr",
              "migrate-kvm-stdio",

              "migrate-qemu-tcp", /* 10 */
              "migrate-qemu-exec",
              "drive-cache-v2",
              "kvm",
              "drive-format",

              "vga", /* 15 */
              "0.10",
              "pci-device",
              "mem-path",
              "drive-serial",

              "xen-domid", /* 20 */
              "migrate-qemu-unix",
              "chardev",
              "enable-kvm",
              "monitor-json",

              "balloon", /* 25 */
              "device",
              "sdl",
              "smp-topology",
              "netdev",

              "rtc", /* 30 */
101
              "vhost-net",
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 130 131 132 133 134
              "rtc-td-hack",
              "no-hpet",
              "no-kvm-pit",

              "tdf", /* 35 */
              "pci-configfd",
              "nodefconfig",
              "boot-menu",
              "enable-kqemu",

              "fsdev", /* 40 */
              "nesting",
              "name-process",
              "drive-readonly",
              "smbios-type",

              "vga-qxl", /* 45 */
              "spice",
              "vga-none",
              "migrate-qemu-fd",
              "boot-index",

              "hda-duplex", /* 50 */
              "drive-aio",
              "pci-multibus",
              "pci-bootindex",
              "ccid-emulated",

              "ccid-passthru", /* 55 */
              "chardev-spicevmc",
              "device-spicevmc",
              "virtio-tx-alg",
              "device-qxl-vga",
135 136

              "pci-multifunction", /* 60 */
137
              "virtio-blk-pci.ioeventfd",
M
Michal Privoznik 已提交
138
              "sga",
139 140
              "virtio-blk-pci.event_idx",
              "virtio-net-pci.event_idx",
141 142 143 144 145 146 147 148 149 150

              "cache-directsync", /* 65 */
              "piix3-usb-uhci",
              "piix4-usb-uhci",
              "usb-ehci",
              "ich9-usb-ehci1",

              "vt82c686b-usb-uhci", /* 70 */
              "pci-ohci",
              "usb-redir",
M
Marc-André Lureau 已提交
151
              "usb-hub",
152
              "no-shutdown",
153 154

              "cache-unsafe", /* 75 */
155
              "rombar",
J
Jim Fehlig 已提交
156
              "ich9-ahci",
157
              "no-acpi",
158
              "fsdev-readonly",
159

160
              "virtio-blk-pci.scsi", /* 80 */
161
              "blk-sg-io",
O
Osier Yang 已提交
162
              "drive-copy-on-read",
163
              "cpu-host",
164
              "fsdev-writeout",
165 166

              "drive-iotune", /* 85 */
167
              "system_wakeup",
168
              "scsi-disk.channel",
169
              "scsi-block",
170
              "transaction",
171 172 173

              "block-job-sync", /* 90 */
              "block-job-async",
174
              "scsi-cd",
175
              "ide-cd",
176
              "no-user-config",
M
Marc-André Lureau 已提交
177 178

              "hda-micro", /* 95 */
179
              "dump-guest-memory",
G
Gerd Hoffmann 已提交
180
              "nec-usb-xhci",
181
              "virtio-s390",
182
              "balloon-event",
M
Marc-André Lureau 已提交
183

R
Richa Marwaha 已提交
184
              "bridge", /* 100 */
185 186
              "lsi",
              "virtio-scsi-pci",
V
Viktor Mihajlovski 已提交
187
              "blockio",
188
              "disable-s3",
R
Richa Marwaha 已提交
189

190
              "disable-s4", /* 105 */
191
              "usb-redir.filter",
192 193
              "ide-drive.wwn",
              "scsi-disk.wwn",
194
              "seccomp-sandbox",
195 196

              "reboot-timeout", /* 110 */
197
              "dump-guest-core",
198
              "seamless-migration",
199
              "block-commit",
200
              "vnc",
201 202

              "drive-mirror", /* 115 */
203 204
              "usb-redir.bootindex",
              "usb-host.bootindex",
205
              "blockdev-snapshot-sync",
206 207 208 209 210 211
              "qxl",

              "VGA", /* 120 */
              "cirrus-vga",
              "vmware-svga",
              "device-video-primary",
212
              "s390-sclp",
213 214

              "usb-serial", /* 125 */
G
Guannan Ren 已提交
215
              "usb-net",
216
              "add-fd",
217
              "nbd-server",
218 219 220
              "virtio-rng",

              "rng-random", /* 130 */
221
              "rng-egd",
O
Olivia Yin 已提交
222 223
              "virtio-ccw",
              "dtb",
224
              "megasas",
J
Ján Tomko 已提交
225 226

              "ipv6-migration", /* 135 */
227
              "machine-opt",
L
Li Zhang 已提交
228
              "machine-usb-opt",
S
Stefan Berger 已提交
229 230
              "tpm-passthrough",
              "tpm-tis",
231 232

              "nvram",  /* 140 */
H
Han Cheng 已提交
233 234 235 236 237 238
              "pci-bridge",
              "vfio-pci",
              "vfio-pci.bootindex",
              "scsi-generic",

              "scsi-generic.bootindex", /* 145 */
239
              "mem-merge",
240
              "vnc-websocket",
O
Osier Yang 已提交
241
              "drive-discard",
242
              "mlock",
243 244

              "vnc-share-policy", /* 150 */
245
              "device-del-event",
246
              "dmi-to-pci-bridge",
247 248
              "i440fx-pci-hole64-size",
              "q35-pci-hole64-size",
249 250

              "usb-storage", /* 155 */
251
              "usb-storage.removable",
252
              "virtio-mmio",
253
              "ich9-intel-hda",
254
              "kvm-pit-lost-tick-policy",
255 256

              "boot-strict", /* 160 */
257 258
              "pvpanic",
              "enable-fips",
259 260
              "spice-file-xfer-disable",
              "spiceport",
L
Li Zhang 已提交
261 262

              "usb-kbd", /* 165 */
263
              "host-pci-multidomain",
264
              "msg-timestamp",
265
              "active-commit",
266
              "change-backing-file",
267 268

              "memory-backend-ram", /* 170 */
269
              "numa",
270
              "memory-backend-file",
271
              "usb-audio",
272
              "rtc-reset-reinjection",
273 274

              "splash-timeout", /* 175 */
J
John Ferlan 已提交
275
              "iothread",
276
              "migrate-rdma",
277
              "ivshmem",
278
              "drive-iotune-max",
279 280 281 282 283

              "VGA.vgamem_mb", /* 180 */
              "vmware-svga.vgamem_mb",
              "qxl.vgamem_mb",
              "qxl-vga.vgamem_mb",
284
              "pc-dimm",
285 286

              "machine-vmport-opt", /* 185 */
287 288
              "aes-key-wrap",
              "dea-key-wrap",
M
Michal Privoznik 已提交
289
              "pci-serial",
290
              "aarch64-off",
291

J
Ján Tomko 已提交
292
              "vhost-user-multiqueue", /* 190 */
293
              "migration-event",
294
              "gpex-pcihost",
295
              "ioh3420",
296
              "x3130-upstream",
297 298 299

              "xio3130-downstream", /* 195 */
              "rtl8139",
300
              "e1000",
301
              "virtio-net",
302
              "gic-version",
303 304

              "incoming-defer", /* 200 */
M
Marc-André Lureau 已提交
305
              "virtio-gpu",
306
              "virtio-gpu.virgl",
307 308 309 310
              "virtio-keyboard",
              "virtio-mouse",

              "virtio-tablet", /* 205 */
311
              "virtio-input-host",
312
              "chardev-file-append",
313 314
              "ich9-disable-s3",
              "ich9-disable-s4",
315 316

              "vserport-change-event", /* 210 */
317
              "virtio-balloon-pci.deflate-on-oom",
318
              "mptsas1068",
319
              "spice-gl",
320 321 322
              "qxl.vram64_size_mb",

              "qxl-vga.vram64_size_mb", /* 215 */
323
              "chardev-logfile",
324
              "debug-threads",
325
              "secret",
326
              "pxb",
327 328

              "pxb-pcie", /* 220 */
329
              "device-tray-moved-event",
330
              "nec-usb-xhci-ports",
331
              "virtio-scsi-pci.iothread",
332
              "name-guest",
333 334 335

              "qxl.max_outputs", /* 225 */
              "qxl-vga.max_outputs",
336
              "spice-unix",
337
              "drive-detect-zeroes",
B
Boris Fiuczynski 已提交
338
              "tls-creds-x509",
339

B
Boris Fiuczynski 已提交
340
              "display", /* 230 */
J
Ján Tomko 已提交
341
              "intel-iommu",
M
Michal Privoznik 已提交
342
              "smm",
343
              "virtio-pci-disable-legacy",
344
              "query-hotpluggable-cpus",
345 346

              "virtio-net.rx_queue_size", /* 235 */
347
              "machine-iommu",
348
              "virtio-vga",
349
              "drive-iotune-max-length",
350 351 352
              "ivshmem-plain",

              "ivshmem-doorbell", /* 240 */
353
              "query-qmp-schema",
354
              "gluster.debug_level",
355
              "vhost-scsi",
356 357
    );

358

359 360 361 362
struct virQEMUCapsMachineType {
    char *name;
    char *alias;
    unsigned int maxCpus;
363
    bool hotplugCpus;
364
};
365 366 367 368 369 370
/*
 * Update the XML parser/formatter when adding more
 * information to this struct so that it gets cached
 * correctly. It does not have to be ABI-stable, as
 * the cache will be discarded & repopulated if the
 * timestamp on the libvirtd binary changes.
371 372
 *
 * And don't forget to update virQEMUCapsNewCopy.
373
 */
374
struct _virQEMUCaps {
375 376
    virObject object;

377 378
    bool usedQMP;

379
    char *binary;
380
    time_t ctime;
381

382
    virBitmapPtr flags;
383 384 385

    unsigned int version;
    unsigned int kvmVersion;
386
    char *package;
387

388
    virArch arch;
389

390
    virDomainCapsCPUModelsPtr cpuDefinitions;
391 392

    size_t nmachineTypes;
393
    struct virQEMUCapsMachineType *machineTypes;
A
Andrea Bolognani 已提交
394 395 396

    size_t ngicCapabilities;
    virGICCapability *gicCapabilities;
397 398 399 400 401 402

    /* Anything below is not stored in the cache since the values are
     * re-computed from the other fields or external data sources every
     * time we probe QEMU or load the results from the cache.
     */
    virCPUDefPtr hostCPUModel;
403 404
};

405 406 407 408
struct virQEMUCapsSearchData {
    virArch arch;
};

409

410 411
static virClassPtr virQEMUCapsClass;
static void virQEMUCapsDispose(void *obj);
412

413
static int virQEMUCapsOnceInit(void)
414
{
415 416 417 418
    if (!(virQEMUCapsClass = virClassNew(virClassForObject(),
                                         "virQEMUCaps",
                                         sizeof(virQEMUCaps),
                                         virQEMUCapsDispose)))
419 420 421 422 423
        return -1;

    return 0;
}

424
VIR_ONCE_GLOBAL_INIT(virQEMUCaps)
425

426
static virArch virQEMUCapsArchFromString(const char *arch)
427 428 429 430 431
{
    if (STREQ(arch, "i386"))
        return VIR_ARCH_I686;
    if (STREQ(arch, "arm"))
        return VIR_ARCH_ARMV7L;
432 433
    if (STREQ(arch, "or32"))
        return VIR_ARCH_OR32;
434 435 436 437 438

    return virArchFromString(arch);
}


439
static const char *virQEMUCapsArchToString(virArch arch)
440 441 442 443 444
{
    if (arch == VIR_ARCH_I686)
        return "i386";
    else if (arch == VIR_ARCH_ARMV7L)
        return "arm";
445 446
    else if (arch == VIR_ARCH_OR32)
        return "or32";
447 448 449 450

    return virArchToString(arch);
}

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473

/* Checks whether a domain with @guest arch can run natively on @host.
 */
static bool
virQEMUCapsGuestIsNative(virArch host,
                         virArch guest)
{
    if (host == guest)
        return true;

    if (host == VIR_ARCH_X86_64 && guest == VIR_ARCH_I686)
        return true;

    if (host == VIR_ARCH_AARCH64 && guest == VIR_ARCH_ARMV7L)
        return true;

    if (ARCH_IS_PPC64(host) && ARCH_IS_PPC64(guest))
        return true;

    return false;
}


474 475 476 477 478 479 480 481 482 483 484 485 486
/* Given a host and guest architectures, find a suitable QEMU target.
 *
 * This is meant to be used as a second attempt if qemu-system-$guestarch
 * can't be found, eg. on a x86_64 host you want to use qemu-system-i386,
 * if available, instead of qemu-system-x86_64 to run i686 guests */
static virArch
virQEMUCapsFindTarget(virArch hostarch,
                      virArch guestarch)
{
    /* Both ppc64 and ppc64le guests can use the ppc64 target */
    if (ARCH_IS_PPC64(guestarch))
        guestarch = VIR_ARCH_PPC64;

487 488
    if (virQEMUCapsGuestIsNative(hostarch, guestarch))
        guestarch = hostarch;
489 490 491

    return guestarch;
}
492

493
static virCommandPtr
494 495
virQEMUCapsProbeCommand(const char *qemu,
                        virQEMUCapsPtr qemuCaps,
496
                        uid_t runUid, gid_t runGid)
497 498 499
{
    virCommandPtr cmd = virCommandNew(qemu);

500 501
    if (qemuCaps) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG))
502
            virCommandAddArg(cmd, "-no-user-config");
503
        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
504 505 506 507 508
            virCommandAddArg(cmd, "-nodefconfig");
    }

    virCommandAddEnvPassCommon(cmd);
    virCommandClearCaps(cmd);
509 510
    virCommandSetGID(cmd, runGid);
    virCommandSetUID(cmd, runUid);
511 512 513 514 515

    return cmd;
}


516
static void
517 518
virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps,
                             size_t defIdx)
519
{
520
    struct virQEMUCapsMachineType tmp = qemuCaps->machineTypes[defIdx];
521 522 523 524

    memmove(qemuCaps->machineTypes + 1,
            qemuCaps->machineTypes,
            sizeof(qemuCaps->machineTypes[0]) * defIdx);
525 526

    qemuCaps->machineTypes[0] = tmp;
527 528
}

529 530 531 532
/* Format is:
 * <machine> <desc> [(default)|(alias of <canonical>)]
 */
static int
533 534
virQEMUCapsParseMachineTypesStr(const char *output,
                                virQEMUCapsPtr qemuCaps)
535 536 537
{
    const char *p = output;
    const char *next;
538
    size_t defIdx = 0;
539 540 541

    do {
        const char *t;
542 543
        char *name;
        char *canonical = NULL;
544 545 546 547 548 549 550 551 552 553

        if ((next = strchr(p, '\n')))
            ++next;

        if (STRPREFIX(p, "Supported machines are:"))
            continue;

        if (!(t = strchr(p, ' ')) || (next && t >= next))
            continue;

554 555
        if (VIR_STRNDUP(name, p, t - p) < 0)
            return -1;
556 557

        p = t;
558
        if ((t = strstr(p, "(default)")) && (!next || t < next))
559
            defIdx = qemuCaps->nmachineTypes;
560 561 562

        if ((t = strstr(p, "(alias of ")) && (!next || t < next)) {
            p = t + strlen("(alias of ");
563 564
            if (!(t = strchr(p, ')')) || (next && t >= next)) {
                VIR_FREE(name);
565
                continue;
566
            }
567

568
            if (VIR_STRNDUP(canonical, p, t - p) < 0) {
569
                VIR_FREE(name);
570
                return -1;
571 572 573
            }
        }

574
        if (VIR_REALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes + 1) < 0) {
575 576
            VIR_FREE(name);
            VIR_FREE(canonical);
577
            return -1;
578
        }
579
        qemuCaps->nmachineTypes++;
580
        if (canonical) {
581 582
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].name = canonical;
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].alias = name;
583
        } else {
584 585
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].name = name;
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].alias = NULL;
586
        }
587
        /* When parsing from command line we don't have information about maxCpus */
588
        qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].maxCpus = 0;
589
        qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].hotplugCpus = false;
590 591
    } while ((p = next));

592

593
    if (defIdx)
594
        virQEMUCapsSetDefaultMachine(qemuCaps, defIdx);
595 596 597 598

    return 0;
}

599
static int
600 601
virQEMUCapsProbeMachineTypes(virQEMUCapsPtr qemuCaps,
                             uid_t runUid, gid_t runGid)
602 603
{
    char *output;
604 605
    int ret = -1;
    virCommandPtr cmd;
606
    int status;
607

608 609 610 611
    /* Make sure the binary we are about to try exec'ing exists.
     * Technically we could catch the exec() failure, but that's
     * in a sub-process so it's hard to feed back a useful error.
     */
612
    if (!virFileIsExecutable(qemuCaps->binary)) {
613
        virReportSystemError(errno, _("Cannot find QEMU binary %s"),
614
                             qemuCaps->binary);
615 616 617
        return -1;
    }

618
    cmd = virQEMUCapsProbeCommand(qemuCaps->binary, qemuCaps, runUid, runGid);
619
    virCommandAddArgList(cmd, "-M", "?", NULL);
620
    virCommandSetOutputBuffer(cmd, &output);
621

622 623
    /* Ignore failure from older qemu that did not understand '-M ?'.  */
    if (virCommandRun(cmd, &status) < 0)
624 625
        goto cleanup;

626
    if (virQEMUCapsParseMachineTypesStr(output, qemuCaps) < 0)
627
        goto cleanup;
628 629 630

    ret = 0;

631
 cleanup:
632 633
    VIR_FREE(output);
    virCommandFree(cmd);
634 635 636 637 638 639

    return ret;
}


typedef int
640 641
(*virQEMUCapsParseCPUModels)(const char *output,
                             virQEMUCapsPtr qemuCaps);
642 643 644 645 646 647 648

/* Format:
 *      <arch> <model>
 * qemu-0.13 encloses some model names in []:
 *      <arch> [<model>]
 */
static int
649 650
virQEMUCapsParseX86Models(const char *output,
                          virQEMUCapsPtr qemuCaps)
651 652 653
{
    const char *p = output;
    const char *next;
654 655 656 657
    virDomainCapsCPUModelsPtr cpus;

    if (!(cpus = virDomainCapsCPUModelsNew(0)))
        return -1;
658 659 660

    do {
        const char *t;
661
        size_t len;
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678

        if ((next = strchr(p, '\n')))
            next++;

        if (!(t = strchr(p, ' ')) || (next && t >= next))
            continue;

        if (!STRPREFIX(p, "x86"))
            continue;

        p = t;
        while (*p == ' ')
            p++;

        if (*p == '\0' || *p == '\n')
            continue;

679 680 681 682
        if (next)
            len = next - p - 1;
        else
            len = strlen(p);
683

684 685 686 687
        if (len > 2 && *p == '[' && p[len - 1] == ']') {
            p++;
            len -= 2;
        }
688

J
Jiri Denemark 已提交
689 690
        if (virDomainCapsCPUModelsAdd(cpus, p, len,
                                      VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
691
            goto error;
692 693
    } while ((p = next));

694 695
    qemuCaps->cpuDefinitions = cpus;
    return 0;
696

697 698 699
 error:
    virObjectUnref(cpus);
    return -1;
700 701
}

P
Prerna Saxena 已提交
702 703 704 705
/* ppc64 parser.
 * Format : PowerPC <machine> <description>
 */
static int
706 707
virQEMUCapsParsePPCModels(const char *output,
                          virQEMUCapsPtr qemuCaps)
P
Prerna Saxena 已提交
708 709 710
{
    const char *p = output;
    const char *next;
711 712 713 714
    virDomainCapsCPUModelsPtr cpus;

    if (!(cpus = virDomainCapsCPUModelsNew(0)))
        return -1;
P
Prerna Saxena 已提交
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737

    do {
        const char *t;

        if ((next = strchr(p, '\n')))
            next++;

        if (!STRPREFIX(p, "PowerPC "))
            continue;

        /* Skip the preceding sub-string "PowerPC " */
        p += 8;

        /*Malformed string, does not obey the format 'PowerPC <model> <desc>'*/
        if (!(t = strchr(p, ' ')) || (next && t >= next))
            continue;

        if (*p == '\0')
            break;

        if (*p == '\n')
            continue;

J
Jiri Denemark 已提交
738 739
        if (virDomainCapsCPUModelsAdd(cpus, p, t - p - 1,
                                      VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
740
            goto error;
P
Prerna Saxena 已提交
741 742
    } while ((p = next));

743 744
    qemuCaps->cpuDefinitions = cpus;
    return 0;
P
Prerna Saxena 已提交
745

746 747 748
 error:
    virObjectUnref(cpus);
    return -1;
P
Prerna Saxena 已提交
749
}
750

751
static int
752
virQEMUCapsProbeCPUModels(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
753 754 755
{
    char *output = NULL;
    int ret = -1;
756
    virQEMUCapsParseCPUModels parse;
757
    virCommandPtr cmd;
758

759
    if (qemuCaps->arch == VIR_ARCH_I686 ||
760
        qemuCaps->arch == VIR_ARCH_X86_64) {
761
        parse = virQEMUCapsParseX86Models;
762
    } else if ARCH_IS_PPC64(qemuCaps->arch) {
763
        parse = virQEMUCapsParsePPCModels;
764
    } else {
765
        VIR_DEBUG("don't know how to parse %s CPU models",
766
                  virArchToString(qemuCaps->arch));
767 768 769
        return 0;
    }

770
    cmd = virQEMUCapsProbeCommand(qemuCaps->binary, qemuCaps, runUid, runGid);
771
    virCommandAddArgList(cmd, "-cpu", "?", NULL);
772
    virCommandSetOutputBuffer(cmd, &output);
773

774
    if (virCommandRun(cmd, NULL) < 0)
775 776
        goto cleanup;

777
    if (parse(output, qemuCaps) < 0)
778 779 780 781
        goto cleanup;

    ret = 0;

782
 cleanup:
783
    VIR_FREE(output);
784
    virCommandFree(cmd);
785 786 787 788

    return ret;
}

789
static char *
790 791
virQEMUCapsFindBinary(const char *format,
                      const char *archstr)
792
{
793 794
    char *ret = NULL;
    char *binary = NULL;
795

796 797
    if (virAsprintf(&binary, format, archstr) < 0)
        goto out;
798 799 800

    ret = virFindFileInPath(binary);
    VIR_FREE(binary);
801 802
    if (ret && virFileIsExecutable(ret))
        goto out;
803

804
    VIR_FREE(ret);
805

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
 out:
    return ret;
}

static char *
virQEMUCapsFindBinaryForArch(virArch hostarch,
                             virArch guestarch)
{
    char *ret = NULL;
    const char *archstr;
    virArch target;

    /* First attempt: try the guest architecture as it is */
    archstr = virQEMUCapsArchToString(guestarch);
    if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
        goto out;

    /* Second attempt: try looking up by target instead */
    target = virQEMUCapsFindTarget(hostarch, guestarch);
    if (target != guestarch) {
        archstr = virQEMUCapsArchToString(target);
        if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
            goto out;
829
    }
830

831 832 833 834
    /* Third attempt, i686 only: try 'qemu' */
    if (guestarch == VIR_ARCH_I686) {
        if ((ret = virQEMUCapsFindBinary("%s", "qemu")) != NULL)
            goto out;
835
    }
836

837
 out:
838 839 840
    return ret;
}

841
static int
842 843 844 845
virQEMUCapsInitGuest(virCapsPtr caps,
                     virQEMUCapsCachePtr cache,
                     virArch hostarch,
                     virArch guestarch)
846
{
847
    size_t i;
848 849
    char *kvmbin = NULL;
    char *binary = NULL;
850 851
    virQEMUCapsPtr qemubinCaps = NULL;
    virQEMUCapsPtr kvmbinCaps = NULL;
852 853
    int ret = -1;

J
Ján Tomko 已提交
854
    /* Check for existence of base emulator, or alternate base
855 856
     * which can be used with magic cpu choice
     */
857
    binary = virQEMUCapsFindBinaryForArch(hostarch, guestarch);
858

859
    /* Ignore binary if extracting version info fails */
860
    if (binary) {
861
        if (!(qemubinCaps = virQEMUCapsCacheLookup(caps, cache, binary))) {
862 863 864 865
            virResetLastError();
            VIR_FREE(binary);
        }
    }
866 867

    /* qemu-kvm/kvm binaries can only be used if
868
     *  - host & guest arches match
869 870
     *  - hostarch is x86_64 and guest arch is i686 (needs -cpu qemu32)
     *  - hostarch is aarch64 and guest arch is armv7l (needs -cpu aarch64=off)
871
     *  - hostarch and guestarch are both ppc64*
872
     */
873
    if (virQEMUCapsGuestIsNative(hostarch, guestarch)) {
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
        const char *kvmbins[] = {
            "/usr/libexec/qemu-kvm", /* RHEL */
            "qemu-kvm", /* Fedora */
            "kvm", /* Debian/Ubuntu */
            NULL,
        };

        /* x86 32-on-64 can be used with qemu-system-i386 and
         * qemu-system-x86_64, so if we don't find a specific kvm binary,
         * we can just fall back to the host arch native binary and
         * everything works fine.
         *
         * arm is different in that 32-on-64 _only_ works with
         * qemu-system-aarch64. So we have to add it to the kvmbins list
         */
889
        if (hostarch == VIR_ARCH_AARCH64 && guestarch == VIR_ARCH_ARMV7L)
890
            kvmbins[3] = "qemu-system-aarch64";
891

892
        for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
893 894 895
            if (!kvmbins[i])
                continue;

896
            kvmbin = virFindFileInPath(kvmbins[i]);
897

898 899
            if (!kvmbin)
                continue;
900

901
            if (!(kvmbinCaps = virQEMUCapsCacheLookup(caps, cache, kvmbin))) {
902
                virResetLastError();
903 904 905
                VIR_FREE(kvmbin);
                continue;
            }
906

907 908
            if (!binary) {
                binary = kvmbin;
909
                qemubinCaps = kvmbinCaps;
910
                kvmbin = NULL;
911
                kvmbinCaps = NULL;
912
            }
913
            break;
914 915 916
        }
    }

917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944
    ret = virQEMUCapsInitGuestFromBinary(caps,
                                         binary, qemubinCaps,
                                         kvmbin, kvmbinCaps,
                                         guestarch);

    VIR_FREE(binary);
    VIR_FREE(kvmbin);
    virObjectUnref(qemubinCaps);
    virObjectUnref(kvmbinCaps);

    return ret;
}

int
virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
                               const char *binary,
                               virQEMUCapsPtr qemubinCaps,
                               const char *kvmbin,
                               virQEMUCapsPtr kvmbinCaps,
                               virArch guestarch)
{
    virCapsGuestPtr guest;
    bool haskvm = false;
    virCapsGuestMachinePtr *machines = NULL;
    size_t nmachines = 0;
    int ret = -1;
    bool hasdisksnapshot = false;

945 946 947
    if (!binary)
        return 0;

948
    if (virFileExists("/dev/kvm") &&
949 950
        (virQEMUCapsGet(qemubinCaps, QEMU_CAPS_KVM) ||
         virQEMUCapsGet(qemubinCaps, QEMU_CAPS_ENABLE_KVM) ||
951
         kvmbin))
952
        haskvm = true;
953

954
    if (virQEMUCapsGetMachineTypesCaps(qemubinCaps, &nmachines, &machines) < 0)
955
        goto cleanup;
956 957 958 959

    /* We register kvm as the base emulator too, since we can
     * just give -no-kvm to disable acceleration if required */
    if ((guest = virCapabilitiesAddGuest(caps,
960
                                         VIR_DOMAIN_OSTYPE_HVM,
961
                                         guestarch,
962 963 964 965
                                         binary,
                                         NULL,
                                         nmachines,
                                         machines)) == NULL)
966
        goto cleanup;
967 968 969 970

    machines = NULL;
    nmachines = 0;

A
Andrea Bolognani 已提交
971 972 973
    /* CPU selection is always available, because all QEMU versions
     * we support can use at least '-cpu host' */
    if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
974
        goto cleanup;
975

976
    if (virQEMUCapsGet(qemubinCaps, QEMU_CAPS_BOOTINDEX) &&
977
        !virCapabilitiesAddGuestFeature(guest, "deviceboot", true, false))
978
        goto cleanup;
979

980 981 982
    if (virQEMUCapsGet(qemubinCaps, QEMU_CAPS_DISK_SNAPSHOT))
        hasdisksnapshot = true;

983 984
    if (!virCapabilitiesAddGuestFeature(guest, "disksnapshot", hasdisksnapshot,
                                        false))
985
        goto cleanup;
986

D
Daniel P. Berrange 已提交
987
    if (virCapabilitiesAddGuestDomain(guest,
988
                                      VIR_DOMAIN_VIRT_QEMU,
D
Daniel P. Berrange 已提交
989 990 991 992
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
993
        goto cleanup;
994

D
Daniel P. Berrange 已提交
995 996
    if (haskvm) {
        virCapsGuestDomainPtr dom;
997

D
Daniel P. Berrange 已提交
998
        if (kvmbin &&
999
            virQEMUCapsGetMachineTypesCaps(kvmbinCaps, &nmachines, &machines) < 0)
1000
            goto cleanup;
1001

D
Daniel P. Berrange 已提交
1002
        if ((dom = virCapabilitiesAddGuestDomain(guest,
1003
                                                 VIR_DOMAIN_VIRT_KVM,
D
Daniel P. Berrange 已提交
1004 1005 1006 1007
                                                 kvmbin ? kvmbin : binary,
                                                 NULL,
                                                 nmachines,
                                                 machines)) == NULL) {
1008
            goto cleanup;
D
Daniel P. Berrange 已提交
1009
        }
1010

D
Daniel P. Berrange 已提交
1011 1012
        machines = NULL;
        nmachines = 0;
1013 1014 1015

    }

1016 1017
    if (((guestarch == VIR_ARCH_I686) ||
         (guestarch == VIR_ARCH_X86_64)) &&
1018 1019
        (virCapabilitiesAddGuestFeature(guest, "acpi", true, true) == NULL ||
         virCapabilitiesAddGuestFeature(guest, "apic", true, false) == NULL))
1020
        goto cleanup;
1021

1022
    if ((guestarch == VIR_ARCH_I686) &&
1023 1024
        (virCapabilitiesAddGuestFeature(guest, "pae", true, false) == NULL ||
         virCapabilitiesAddGuestFeature(guest, "nonpae", true, false) == NULL))
1025
        goto cleanup;
1026 1027 1028

    ret = 0;

1029
 cleanup:
1030 1031 1032

    virCapabilitiesFreeMachines(machines, nmachines);

1033
    return ret;
1034 1035 1036 1037
}


static int
1038 1039
virQEMUCapsInitCPU(virCapsPtr caps,
                   virArch arch)
1040 1041
{
    virCPUDefPtr cpu = NULL;
1042
    virCPUDataPtr data = NULL;
1043 1044 1045
    virNodeInfo nodeinfo;
    int ret = -1;

1046
    if (VIR_ALLOC(cpu) < 0)
1047 1048
        goto error;

1049 1050
    cpu->arch = arch;

1051
    if (nodeGetInfo(&nodeinfo))
1052 1053 1054 1055 1056 1057
        goto error;

    cpu->type = VIR_CPU_TYPE_HOST;
    cpu->sockets = nodeinfo.sockets;
    cpu->cores = nodeinfo.cores;
    cpu->threads = nodeinfo.threads;
J
Jiri Denemark 已提交
1058
    caps->host.cpu = cpu;
1059

1060
    if (!(data = cpuNodeData(arch))
1061
        || cpuDecode(cpu, data, NULL, 0, NULL) < 0)
J
Jiri Denemark 已提交
1062
        goto cleanup;
1063 1064 1065

    ret = 0;

1066
 cleanup:
J
Jiri Denemark 已提交
1067
    cpuDataFree(data);
1068 1069 1070

    return ret;

1071
 error:
1072 1073 1074 1075 1076
    virCPUDefFree(cpu);
    goto cleanup;
}


M
Michal Privoznik 已提交
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
static int
virQEMUCapsInitPages(virCapsPtr caps)
{
    int ret = -1;
    unsigned int *pages_size = NULL;
    size_t npages;

    if (virNumaGetPages(-1 /* Magic constant for overall info */,
                        &pages_size, NULL, NULL, &npages) < 0)
        goto cleanup;

    caps->host.pagesSize = pages_size;
    pages_size = NULL;
    caps->host.nPagesSize = npages;
    npages = 0;

    ret = 0;
 cleanup:
    VIR_FREE(pages_size);
    return ret;
}


1100
virCapsPtr virQEMUCapsInit(virQEMUCapsCachePtr cache)
1101 1102
{
    virCapsPtr caps;
1103
    size_t i;
T
Tal Kain 已提交
1104
    virArch hostarch = virArchFromHost();
1105

T
Tal Kain 已提交
1106
    if ((caps = virCapabilitiesNew(hostarch,
1107
                                   true, true)) == NULL)
1108
        goto error;
1109 1110 1111 1112 1113

    /* Some machines have problematic NUMA toplogy causing
     * unexpected failures. We don't want to break the QEMU
     * driver in this scenario, so log errors & carry on
     */
1114
    if (nodeCapsInitNUMA(caps) < 0) {
1115
        virCapabilitiesFreeNUMAInfo(caps);
1116
        VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities");
1117 1118
    }

T
Tal Kain 已提交
1119
    if (virQEMUCapsInitCPU(caps, hostarch) < 0)
1120
        VIR_WARN("Failed to get host CPU");
1121

1122
    /* Add the power management features of the host */
1123
    if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)
1124 1125
        VIR_WARN("Failed to get host power management capabilities");

M
Michal Privoznik 已提交
1126 1127 1128 1129
    /* Add huge pages info */
    if (virQEMUCapsInitPages(caps) < 0)
        VIR_WARN("Failed to get pages info");

1130 1131 1132
    /* Add domain migration transport URIs */
    virCapabilitiesAddHostMigrateTransport(caps, "tcp");
    virCapabilitiesAddHostMigrateTransport(caps, "rdma");
1133

1134 1135 1136 1137
    /* QEMU can support pretty much every arch that exists,
     * so just probe for them all - we gracefully fail
     * if a qemu-system-$ARCH binary can't be found
     */
1138
    for (i = 0; i < VIR_ARCH_LAST; i++)
1139
        if (virQEMUCapsInitGuest(caps, cache,
T
Tal Kain 已提交
1140
                                 hostarch,
1141
                                 i) < 0)
1142
            goto error;
1143 1144 1145

    return caps;

1146
 error:
1147
    virObjectUnref(caps);
1148 1149 1150 1151
    return NULL;
}


1152
static int
1153 1154 1155 1156
virQEMUCapsComputeCmdFlags(const char *help,
                           unsigned int version,
                           virQEMUCapsPtr qemuCaps,
                           bool check_yajl ATTRIBUTE_UNUSED)
1157 1158
{
    const char *p;
R
Richa Marwaha 已提交
1159
    const char *fsdev, *netdev;
1160
    const char *cache;
1161 1162

    if (strstr(help, "-no-kvm"))
1163
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
1164
    if (strstr(help, "-enable-kvm"))
1165
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ENABLE_KVM);
1166 1167
    if (strstr(help, ",process="))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NAME_PROCESS);
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182

    cache = strstr(help, "cache=");
    if (cache && (p = strchr(cache, ']'))) {
        if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1))
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
        if (memmem(cache, p - cache, "unsafe", sizeof("unsafe") - 1))
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
    }
    if (strstr(help, "aio=threads|native"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_AIO);
    if (strstr(help, "copy-on-read=on|off"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
    if (strstr(help, "bps="))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);

P
Paolo Bonzini 已提交
1183 1184
    if (strstr(help, "-display"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DISPLAY);
1185 1186 1187
    if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
        const char *nl = strstr(p, "\n");
        if ((p = strstr(p, "|none")) && p < nl)
1188
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_VGA_NONE);
1189 1190
    }
    if (strstr(help, "-spice"))
1191
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SPICE);
1192
    if (strstr(help, "-vnc"))
1193
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC);
1194
    if (strstr(help, "seamless-migration="))
1195
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION);
1196
    if (strstr(help, "boot=on"))
1197
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
1198
    if (strstr(help, "serial=s"))
1199
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL);
1200 1201
    if (strstr(help, "host=[seg:]bus"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN);
1202
    if (strstr(help, "-mem-path"))
1203
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MEM_PATH);
1204
    if (strstr(help, "-chardev")) {
1205
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV);
1206
        if (strstr(help, "-chardev spicevmc"))
1207
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC);
1208 1209
        if (strstr(help, "-chardev spiceport"))
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEPORT);
1210
    }
1211
    if (strstr(help, "-nodefconfig"))
1212
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NODEFCONFIG);
1213
    if (strstr(help, "-no-user-config"))
1214
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG);
1215 1216
    /* The trailing ' ' is important to avoid a bogus match */
    if (strstr(help, "-rtc "))
1217
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_RTC);
1218 1219
    /* to wit */
    if (strstr(help, "-rtc-td-hack"))
1220
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_RTC_TD_HACK);
1221
    if (strstr(help, "-no-hpet"))
1222
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_HPET);
1223
    if (strstr(help, "-no-acpi"))
1224
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI);
1225
    if (strstr(help, "-no-kvm-pit-reinjection"))
1226
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
1227
    if (strstr(help, "-tdf"))
1228
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_TDF);
1229
    if (strstr(help, "-enable-nesting"))
1230
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NESTING);
1231
    if (strstr(help, ",menu=on"))
1232
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BOOT_MENU);
1233
    if (strstr(help, ",reboot-timeout=rb_time"))
1234
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT);
1235 1236
    if (strstr(help, ",splash-time=sp_time"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SPLASH_TIMEOUT);
1237
    if ((fsdev = strstr(help, "-fsdev"))) {
1238
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV);
1239
        if (strstr(fsdev, "readonly"))
1240
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_READONLY);
1241
        if (strstr(fsdev, "writeout"))
1242
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT);
1243
    }
1244
    if (strstr(help, "-smbios type"))
1245
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE);
1246
    if (strstr(help, "-sandbox"))
1247
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX);
1248

R
Richa Marwaha 已提交
1249
    if ((netdev = strstr(help, "-netdev"))) {
1250 1251
        /* Disable -netdev on 0.12 since although it exists,
         * the corresponding netdev_add/remove monitor commands
1252 1253
         * do not, and we need them to be able to do hotplug.
         * But see below about RHEL build. */
R
Richa Marwaha 已提交
1254 1255
        if (version >= 13000) {
            if (strstr(netdev, "bridge"))
1256
                virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE);
1257
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
R
Richa Marwaha 已提交
1258
        }
1259 1260 1261
    }

    if (strstr(help, "-sdl"))
1262
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SDL);
1263

1264
    if (strstr(help, ",vhost="))
1265
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOST_NET);
1266

1267 1268
    /* Do not use -no-shutdown if qemu doesn't support it or SIGTERM handling
     * is most likely buggy when used with -no-shutdown (which applies for qemu
1269
     * 0.14.* and 0.15.0)
1270
     */
1271
    if (strstr(help, "-no-shutdown") && (version < 14000 || version > 15000))
1272
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN);
1273

1274
    if (strstr(help, "dump-guest-core=on|off"))
1275
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE);
1276

O
Olivia Yin 已提交
1277 1278 1279
    if (strstr(help, "-dtb"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB);

1280 1281 1282
    if (strstr(help, "-machine"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);

1283 1284 1285
    /* While JSON mode was available in 0.12.0, it was too
     * incomplete to contemplate using. The 0.13.0 release
     * is good enough to use, even though it lacks one or
1286 1287 1288 1289 1290
     * two features. This is also true of versions of qemu
     * built for RHEL, labeled 0.12.1, but with extra text
     * in the help output that mentions that features were
     * backported for libvirt. The benefits of JSON mode now
     * outweigh the downside.
1291
     */
1292
#if WITH_YAJL
1293
    if (version >= 13000) {
1294
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MONITOR_JSON);
1295 1296
    } else if (version >= 12000 &&
               strstr(help, "libvirt")) {
1297 1298
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MONITOR_JSON);
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
1299
    }
1300 1301 1302 1303 1304
#else
    /* Starting with qemu 0.15 and newer, upstream qemu no longer
     * promises to keep the human interface stable, but requests that
     * we use QMP (the JSON interface) for everything.  If the user
     * forgot to include YAJL libraries when building their own
M
Martin Kletzander 已提交
1305
     * libvirt but is targeting a newer qemu, we are better off
1306
     * telling them to recompile (the spec file includes the
1307
     * dependency, so distros won't hit this).  This check is
1308
     * also in m4/virt-yajl.m4 (see $with_yajl).  */
1309 1310 1311
    if (version >= 15000 ||
        (version >= 12000 && strstr(help, "libvirt"))) {
        if (check_yajl) {
1312 1313 1314
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu binary requires libvirt to be "
                             "compiled with yajl"));
1315 1316
            return -1;
        }
1317
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
1318
    }
E
Eric Blake 已提交
1319
#endif
1320 1321

    if (version >= 13000)
1322
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION);
1323

1324
    if (version >= 1001000) {
J
Ján Tomko 已提交
1325
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION);
1326 1327
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY);
    }
J
Ján Tomko 已提交
1328

1329
    return 0;
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
}

/* We parse the output of 'qemu -help' to get the QEMU
 * version number. The first bit is easy, just parse
 * 'QEMU PC emulator version x.y.z'
 * or
 * 'QEMU emulator version x.y.z'.
 *
 * With qemu-kvm, however, that is followed by a string
 * in parenthesis as follows:
 *  - qemu-kvm-x.y.z in stable releases
 *  - kvm-XX for kvm versions up to kvm-85
 *  - qemu-kvm-devel-XX for kvm version kvm-86 and later
 *
 * For qemu-kvm versions before 0.10.z, we need to detect
 * the KVM version number for some features. With 0.10.z
 * and later, we just need the QEMU version number and
 * whether it is KVM QEMU or mainline QEMU.
 */
#define QEMU_VERSION_STR_1  "QEMU emulator version"
#define QEMU_VERSION_STR_2  "QEMU PC emulator version"
#define QEMU_KVM_VER_PREFIX "(qemu-kvm-"
#define KVM_VER_PREFIX      "(kvm-"

#define SKIP_BLANKS(p) do { while ((*(p) == ' ') || (*(p) == '\t')) (p)++; } while (0)

1356 1357 1358 1359
int virQEMUCapsParseHelpStr(const char *qemu,
                            const char *help,
                            virQEMUCapsPtr qemuCaps,
                            unsigned int *version,
1360
                            bool *is_kvm,
1361
                            unsigned int *kvm_version,
1362 1363
                            bool check_yajl,
                            const char *qmperr)
1364 1365 1366
{
    unsigned major, minor, micro;
    const char *p = help;
1367
    char *strflags;
1368

1369 1370
    *version = *kvm_version = 0;
    *is_kvm = false;
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387

    if (STRPREFIX(p, QEMU_VERSION_STR_1))
        p += strlen(QEMU_VERSION_STR_1);
    else if (STRPREFIX(p, QEMU_VERSION_STR_2))
        p += strlen(QEMU_VERSION_STR_2);
    else
        goto fail;

    SKIP_BLANKS(p);

    major = virParseNumber(&p);
    if (major == -1 || *p != '.')
        goto fail;

    ++p;

    minor = virParseNumber(&p);
J
Jiri Denemark 已提交
1388
    if (minor == -1)
1389 1390
        goto fail;

J
Jiri Denemark 已提交
1391 1392 1393 1394 1395 1396 1397 1398
    if (*p != '.') {
        micro = 0;
    } else {
        ++p;
        micro = virParseNumber(&p);
        if (micro == -1)
            goto fail;
    }
1399 1400 1401 1402

    SKIP_BLANKS(p);

    if (STRPREFIX(p, QEMU_KVM_VER_PREFIX)) {
1403
        *is_kvm = true;
1404 1405 1406 1407
        p += strlen(QEMU_KVM_VER_PREFIX);
    } else if (STRPREFIX(p, KVM_VER_PREFIX)) {
        int ret;

1408
        *is_kvm = true;
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
        p += strlen(KVM_VER_PREFIX);

        ret = virParseNumber(&p);
        if (ret == -1)
            goto fail;

        *kvm_version = ret;
    }

    *version = (major * 1000 * 1000) + (minor * 1000) + micro;

1420 1421 1422 1423 1424 1425 1426
    if (*version < 12000) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("QEMU version >= 0.12.00 is required, but %d.%d.%d found"),
                       major, minor, micro);
        goto cleanup;
    }

1427 1428 1429 1430
    /* Refuse to parse -help output for QEMU releases >= 1.2.0 that should be
     * using QMP probing.
     */
    if (*version >= 1002000) {
1431 1432 1433 1434 1435 1436 1437 1438 1439
        if (qmperr && *qmperr) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("QEMU / QMP failed: %s"),
                           qmperr);
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("QEMU %u.%u.%u is too new for help parsing"),
                           major, minor, micro);
        }
1440 1441 1442
        goto cleanup;
    }

1443
    if (virQEMUCapsComputeCmdFlags(help, *version,
1444
                                   qemuCaps, check_yajl) < 0)
1445
        goto cleanup;
1446

1447
    strflags = virBitmapString(qemuCaps->flags);
1448 1449 1450
    VIR_DEBUG("Version %u.%u.%u, cooked version %u, flags %s",
              major, minor, micro, *version, NULLSTR(strflags));
    VIR_FREE(strflags);
1451 1452 1453 1454 1455 1456 1457 1458

    if (*kvm_version)
        VIR_DEBUG("KVM version %d detected", *kvm_version);
    else if (*is_kvm)
        VIR_DEBUG("qemu-kvm version %u.%u.%u detected", major, minor, micro);

    return 0;

1459
 fail:
1460
    p = strchr(help, '\n');
1461 1462
    if (!p)
        p = strchr(help, '\0');
1463

1464 1465 1466
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot parse %s version number in '%.*s'"),
                   qemu, (int) (p - help), help);
1467

1468
 cleanup:
1469 1470 1471
    return -1;
}

1472

1473
struct virQEMUCapsStringFlags {
1474 1475 1476 1477 1478
    const char *value;
    int flag;
};


1479 1480 1481
struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
    { "system_wakeup", QEMU_CAPS_WAKEUP },
    { "transaction", QEMU_CAPS_TRANSACTION },
1482 1483
    { "block_stream", QEMU_CAPS_BLOCKJOB_SYNC },
    { "block-stream", QEMU_CAPS_BLOCKJOB_ASYNC },
1484 1485 1486 1487 1488 1489 1490 1491 1492
    { "dump-guest-memory", QEMU_CAPS_DUMP_GUEST_MEMORY },
    { "query-spice", QEMU_CAPS_SPICE },
    { "query-kvm", QEMU_CAPS_KVM },
    { "block-commit", QEMU_CAPS_BLOCK_COMMIT },
    { "query-vnc", QEMU_CAPS_VNC },
    { "drive-mirror", QEMU_CAPS_DRIVE_MIRROR },
    { "blockdev-snapshot-sync", QEMU_CAPS_DISK_SNAPSHOT },
    { "add-fd", QEMU_CAPS_ADD_FD },
    { "nbd-server-start", QEMU_CAPS_NBD_SERVER },
1493
    { "change-backing-file", QEMU_CAPS_CHANGE_BACKING_FILE },
1494
    { "rtc-reset-reinjection", QEMU_CAPS_RTC_RESET_REINJECTION },
1495
    { "migrate-incoming", QEMU_CAPS_INCOMING_DEFER },
1496
    { "query-hotpluggable-cpus", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS },
1497
    { "query-qmp-schema", QEMU_CAPS_QUERY_QMP_SCHEMA }
1498 1499
};

1500 1501 1502 1503
struct virQEMUCapsStringFlags virQEMUCapsMigration[] = {
    { "rdma-pin-all", QEMU_CAPS_MIGRATE_RDMA },
};

1504 1505 1506
struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
    { "BALLOON_CHANGE", QEMU_CAPS_BALLOON_EVENT },
    { "SPICE_MIGRATE_COMPLETED", QEMU_CAPS_SEAMLESS_MIGRATION },
1507
    { "DEVICE_DELETED", QEMU_CAPS_DEVICE_DEL_EVENT },
1508
    { "MIGRATION", QEMU_CAPS_MIGRATION_EVENT },
1509
    { "VSERPORT_CHANGE", QEMU_CAPS_VSERPORT_CHANGE },
1510
    { "DEVICE_TRAY_MOVED", QEMU_CAPS_DEVICE_TRAY_MOVED },
1511 1512
};

1513
struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528
    { "hda-duplex", QEMU_CAPS_HDA_DUPLEX },
    { "hda-micro", QEMU_CAPS_HDA_MICRO },
    { "ccid-card-emulated", QEMU_CAPS_CCID_EMULATED },
    { "ccid-card-passthru", QEMU_CAPS_CCID_PASSTHRU },
    { "piix3-usb-uhci", QEMU_CAPS_PIIX3_USB_UHCI },
    { "piix4-usb-uhci", QEMU_CAPS_PIIX4_USB_UHCI },
    { "usb-ehci", QEMU_CAPS_USB_EHCI },
    { "ich9-usb-ehci1", QEMU_CAPS_ICH9_USB_EHCI1 },
    { "vt82c686b-usb-uhci", QEMU_CAPS_VT82C686B_USB_UHCI },
    { "pci-ohci", QEMU_CAPS_PCI_OHCI },
    { "nec-usb-xhci", QEMU_CAPS_NEC_USB_XHCI },
    { "usb-redir", QEMU_CAPS_USB_REDIR },
    { "usb-hub", QEMU_CAPS_USB_HUB },
    { "ich9-ahci", QEMU_CAPS_ICH9_AHCI },
    { "virtio-blk-s390", QEMU_CAPS_VIRTIO_S390 },
1529
    { "virtio-blk-ccw", QEMU_CAPS_VIRTIO_CCW },
1530
    { "sclpconsole", QEMU_CAPS_SCLP_S390 },
1531
    { "lsi53c895a", QEMU_CAPS_SCSI_LSI },
1532
    { "virtio-scsi-pci", QEMU_CAPS_VIRTIO_SCSI },
1533 1534
    { "virtio-scsi-s390", QEMU_CAPS_VIRTIO_SCSI },
    { "virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI },
1535
    { "virtio-scsi-device", QEMU_CAPS_VIRTIO_SCSI },
1536
    { "megasas", QEMU_CAPS_SCSI_MEGASAS },
1537
    { "spicevmc", QEMU_CAPS_DEVICE_SPICEVMC },
1538
    { "qxl", QEMU_CAPS_DEVICE_QXL },
1539 1540 1541 1542
    { "sga", QEMU_CAPS_SGA },
    { "scsi-block", QEMU_CAPS_SCSI_BLOCK },
    { "scsi-cd", QEMU_CAPS_SCSI_CD },
    { "ide-cd", QEMU_CAPS_IDE_CD },
1543 1544 1545
    { "VGA", QEMU_CAPS_DEVICE_VGA },
    { "cirrus-vga", QEMU_CAPS_DEVICE_CIRRUS_VGA },
    { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA },
H
Han Cheng 已提交
1546 1547
    { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL },
    { "usb-net", QEMU_CAPS_DEVICE_USB_NET },
1548
    { "virtio-rng-pci", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1549 1550
    { "virtio-rng-s390", QEMU_CAPS_DEVICE_VIRTIO_RNG },
    { "virtio-rng-ccw", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1551
    { "virtio-rng-device", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1552
    { "rng-random", QEMU_CAPS_OBJECT_RNG_RANDOM },
1553
    { "rng-egd", QEMU_CAPS_OBJECT_RNG_EGD },
1554
    { "spapr-nvram", QEMU_CAPS_DEVICE_NVRAM },
1555
    { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE },
1556
    { "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI },
H
Han Cheng 已提交
1557
    { "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC },
1558
    { "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE },
1559
    { "usb-storage", QEMU_CAPS_DEVICE_USB_STORAGE },
1560
    { "virtio-mmio", QEMU_CAPS_DEVICE_VIRTIO_MMIO },
1561
    { "ich9-intel-hda", QEMU_CAPS_DEVICE_ICH9_INTEL_HDA },
H
Hu Tao 已提交
1562
    { "pvpanic", QEMU_CAPS_DEVICE_PANIC },
L
Li Zhang 已提交
1563
    { "usb-kbd", QEMU_CAPS_DEVICE_USB_KBD },
1564
    { "memory-backend-ram", QEMU_CAPS_OBJECT_MEMORY_RAM },
1565
    { "memory-backend-file", QEMU_CAPS_OBJECT_MEMORY_FILE },
1566
    { "usb-audio", QEMU_CAPS_OBJECT_USB_AUDIO },
J
John Ferlan 已提交
1567
    { "iothread", QEMU_CAPS_OBJECT_IOTHREAD},
1568
    { "ivshmem", QEMU_CAPS_DEVICE_IVSHMEM },
1569
    { "pc-dimm", QEMU_CAPS_DEVICE_PC_DIMM },
M
Michal Privoznik 已提交
1570
    { "pci-serial", QEMU_CAPS_DEVICE_PCI_SERIAL },
1571
    { "gpex-pcihost", QEMU_CAPS_OBJECT_GPEX},
1572
    { "ioh3420", QEMU_CAPS_DEVICE_IOH3420 },
1573
    { "x3130-upstream", QEMU_CAPS_DEVICE_X3130_UPSTREAM },
1574
    { "xio3130-downstream", QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM },
1575
    { "rtl8139", QEMU_CAPS_DEVICE_RTL8139 },
1576
    { "e1000", QEMU_CAPS_DEVICE_E1000 },
1577 1578 1579 1580
    { "virtio-net-pci", QEMU_CAPS_DEVICE_VIRTIO_NET },
    { "virtio-net-ccw", QEMU_CAPS_DEVICE_VIRTIO_NET },
    { "virtio-net-s390", QEMU_CAPS_DEVICE_VIRTIO_NET },
    { "virtio-net-device", QEMU_CAPS_DEVICE_VIRTIO_NET },
M
Marc-André Lureau 已提交
1581 1582
    { "virtio-gpu-pci", QEMU_CAPS_DEVICE_VIRTIO_GPU },
    { "virtio-gpu-device", QEMU_CAPS_DEVICE_VIRTIO_GPU },
1583
    { "virtio-vga", QEMU_CAPS_DEVICE_VIRTIO_VGA },
1584 1585 1586 1587 1588 1589
    { "virtio-keyboard-device", QEMU_CAPS_VIRTIO_KEYBOARD },
    { "virtio-keyboard-pci", QEMU_CAPS_VIRTIO_KEYBOARD },
    { "virtio-mouse-device", QEMU_CAPS_VIRTIO_MOUSE },
    { "virtio-mouse-pci", QEMU_CAPS_VIRTIO_MOUSE },
    { "virtio-tablet-device", QEMU_CAPS_VIRTIO_TABLET },
    { "virtio-tablet-pci", QEMU_CAPS_VIRTIO_TABLET },
1590 1591
    { "virtio-input-host-device", QEMU_CAPS_VIRTIO_INPUT_HOST },
    { "virtio-input-host-pci", QEMU_CAPS_VIRTIO_INPUT_HOST },
1592
    { "mptsas1068", QEMU_CAPS_SCSI_MPTSAS1068 },
1593
    { "secret", QEMU_CAPS_OBJECT_SECRET },
1594
    { "pxb", QEMU_CAPS_DEVICE_PXB },
1595
    { "pxb-pcie", QEMU_CAPS_DEVICE_PXB_PCIE },
1596
    { "tls-creds-x509", QEMU_CAPS_OBJECT_TLS_CREDS_X509 },
J
Ján Tomko 已提交
1597
    { "intel-iommu", QEMU_CAPS_DEVICE_INTEL_IOMMU },
1598 1599
    { "ivshmem-plain", QEMU_CAPS_DEVICE_IVSHMEM_PLAIN },
    { "ivshmem-doorbell", QEMU_CAPS_DEVICE_IVSHMEM_DOORBELL },
1600
    { "vhost-scsi", QEMU_CAPS_DEVICE_VHOST_SCSI },
1601 1602
};

1603 1604 1605 1606
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBalloon[] = {
    { "deflate-on-oom", QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE },
};

1607
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
1608 1609 1610 1611 1612 1613 1614 1615
    { "multifunction", QEMU_CAPS_PCI_MULTIFUNCTION },
    { "bootindex", QEMU_CAPS_BOOTINDEX },
    { "ioeventfd", QEMU_CAPS_VIRTIO_IOEVENTFD },
    { "event_idx", QEMU_CAPS_VIRTIO_BLK_EVENT_IDX },
    { "scsi", QEMU_CAPS_VIRTIO_BLK_SCSI },
    { "logical_block_size", QEMU_CAPS_BLOCKIO },
};

1616
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioNet[] = {
1617 1618
    { "tx", QEMU_CAPS_VIRTIO_TX_ALG },
    { "event_idx", QEMU_CAPS_VIRTIO_NET_EVENT_IDX },
1619
    { "rx_queue_size", QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE },
1620 1621
};

1622 1623 1624 1625
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioSCSI[] = {
    { "iothread", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD },
};

1626
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPCIAssign[] = {
1627 1628 1629 1630
    { "configfd", QEMU_CAPS_PCI_CONFIGFD },
    { "bootindex", QEMU_CAPS_PCI_BOOTINDEX },
};

1631
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVfioPCI[] = {
1632 1633 1634
    { "bootindex", QEMU_CAPS_VFIO_PCI_BOOTINDEX },
};

1635
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSCSIDisk[] = {
1636 1637 1638 1639
    { "channel", QEMU_CAPS_SCSI_DISK_CHANNEL },
    { "wwn", QEMU_CAPS_SCSI_DISK_WWN },
};

1640
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIDEDrive[] = {
1641 1642 1643
    { "wwn", QEMU_CAPS_IDE_DRIVE_WWN },
};

1644
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPiix4PM[] = {
1645 1646
    { "disable_s3", QEMU_CAPS_PIIX_DISABLE_S3 },
    { "disable_s4", QEMU_CAPS_PIIX_DISABLE_S4 },
1647 1648
};

1649
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBRedir[] = {
1650
    { "filter", QEMU_CAPS_USB_REDIR_FILTER },
1651 1652 1653
    { "bootindex", QEMU_CAPS_USB_REDIR_BOOTINDEX },
};

1654
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBHost[] = {
1655
    { "bootindex", QEMU_CAPS_USB_HOST_BOOTINDEX },
1656 1657
};

1658
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSCSIGeneric[] = {
H
Han Cheng 已提交
1659 1660 1661
    { "bootindex", QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX },
};

1662
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsI440FXPCIHost[] = {
1663 1664 1665
    { "pci-hole64-size", QEMU_CAPS_I440FX_PCI_HOLE64_SIZE },
};

1666
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQ35PCIHost[] = {
1667 1668 1669
    { "pci-hole64-size", QEMU_CAPS_Q35_PCI_HOLE64_SIZE },
};

1670
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBStorage[] = {
1671 1672 1673
    { "removable", QEMU_CAPS_USB_STORAGE_REMOVABLE },
};

1674 1675 1676 1677
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsKVMPit[] = {
    { "lost_tick_policy", QEMU_CAPS_KVM_PIT_TICK_POLICY },
};

1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVGA[] = {
    { "vgamem_mb", QEMU_CAPS_VGA_VGAMEM },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVmwareSvga[] = {
    { "vgamem_mb", QEMU_CAPS_VMWARE_SVGA_VGAMEM },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQxl[] = {
    { "vgamem_mb", QEMU_CAPS_QXL_VGAMEM },
1688
    { "vram64_size_mb", QEMU_CAPS_QXL_VRAM64 },
1689
    { "max_outputs", QEMU_CAPS_QXL_MAX_OUTPUTS },
1690 1691
};

1692
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioGpu[] = {
1693
    { "virgl", QEMU_CAPS_VIRTIO_GPU_VIRGL },
1694 1695
};

1696 1697 1698 1699 1700
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsICH9[] = {
    { "disable_s3", QEMU_CAPS_ICH9_DISABLE_S3 },
    { "disable_s4", QEMU_CAPS_ICH9_DISABLE_S4 },
};

1701 1702 1703 1704
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBNECXHCI[] = {
    { "p3", QEMU_CAPS_NEC_USB_XHCI_PORTS },
};

1705 1706
/* see documentation for virQEMUCapsQMPSchemaGetByPath for the query format */
static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
1707
    { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
1708 1709
};

1710
struct virQEMUCapsObjectTypeProps {
1711
    const char *type;
1712
    struct virQEMUCapsStringFlags *props;
1713 1714 1715
    size_t nprops;
};

1716 1717 1718 1719
static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
    { "virtio-blk-pci", virQEMUCapsObjectPropsVirtioBlk,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) },
    { "virtio-net-pci", virQEMUCapsObjectPropsVirtioNet,
1720
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) },
1721 1722
    { "virtio-scsi-pci", virQEMUCapsObjectPropsVirtioSCSI,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioSCSI) },
1723 1724 1725
    { "virtio-blk-ccw", virQEMUCapsObjectPropsVirtioBlk,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) },
    { "virtio-net-ccw", virQEMUCapsObjectPropsVirtioNet,
1726
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) },
1727 1728
    { "virtio-scsi-ccw", virQEMUCapsObjectPropsVirtioSCSI,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioSCSI) },
1729 1730 1731 1732
    { "virtio-blk-s390", virQEMUCapsObjectPropsVirtioBlk,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk) },
    { "virtio-net-s390", virQEMUCapsObjectPropsVirtioNet,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet) },
1733 1734 1735 1736 1737 1738
    { "pci-assign", virQEMUCapsObjectPropsPCIAssign,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsPCIAssign) },
    { "kvm-pci-assign", virQEMUCapsObjectPropsPCIAssign,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsPCIAssign) },
    { "vfio-pci", virQEMUCapsObjectPropsVfioPCI,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVfioPCI) },
1739 1740
    { "scsi-disk", virQEMUCapsObjectPropsSCSIDisk,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsSCSIDisk) },
1741 1742
    { "ide-drive", virQEMUCapsObjectPropsIDEDrive,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsIDEDrive) },
1743 1744
    { "PIIX4_PM", virQEMUCapsObjectPropsPiix4PM,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsPiix4PM) },
1745 1746 1747 1748
    { "usb-redir", virQEMUCapsObjectPropsUSBRedir,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBRedir) },
    { "usb-host", virQEMUCapsObjectPropsUSBHost,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBHost) },
1749 1750
    { "scsi-generic", virQEMUCapsObjectPropsSCSIGeneric,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsSCSIGeneric) },
1751 1752 1753 1754
    { "i440FX-pcihost", virQEMUCapsObjectPropsI440FXPCIHost,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsI440FXPCIHost) },
    { "q35-pcihost", virQEMUCapsObjectPropsQ35PCIHost,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsQ35PCIHost) },
1755 1756
    { "usb-storage", virQEMUCapsObjectPropsUSBStorage,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBStorage) },
1757 1758
    { "kvm-pit", virQEMUCapsObjectPropsKVMPit,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsKVMPit) },
1759 1760 1761 1762 1763 1764
    { "VGA", virQEMUCapsObjectPropsVGA,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVGA) },
    { "vmware-svga", virQEMUCapsObjectPropsVmwareSvga,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVmwareSvga) },
    { "qxl", virQEMUCapsObjectPropsQxl,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsQxl) },
1765 1766
    { "virtio-gpu-pci", virQEMUCapsObjectPropsVirtioGpu,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioGpu) },
1767 1768
    { "virtio-gpu-device", virQEMUCapsObjectPropsVirtioGpu,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioGpu) },
1769 1770
    { "ICH9-LPC", virQEMUCapsObjectPropsICH9,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsICH9) },
1771 1772 1773 1774 1775 1776
    { "virtio-balloon-pci", virQEMUCapsObjectPropsVirtioBalloon,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
    { "virtio-balloon-ccw", virQEMUCapsObjectPropsVirtioBalloon,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
    { "virtio-balloon-device", virQEMUCapsObjectPropsVirtioBalloon,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
1777 1778
    { "nec-usb-xhci", virQEMUCapsObjectPropsUSBNECXHCI,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBNECXHCI) },
1779 1780
};

1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808
struct virQEMUCapsPropTypeObjects {
    const char *prop;
    int flag;
    const char **objects;
};

static const char *virQEMUCapsVirtioPCIDisableLegacyObjects[] = {
     "virtio-balloon-pci",
     "virtio-blk-pci",
     "virtio-scsi-pci",
     "virtio-serial-pci",
     "virtio-9p-pci",
     "virtio-net-pci",
     "virtio-rng-pci",
     "virtio-gpu-pci",
     "virtio-input-host-pci",
     "virtio-keyboard-pci",
     "virtio-mouse-pci",
     "virtio-tablet-pci",
     NULL
};

static struct virQEMUCapsPropTypeObjects virQEMUCapsPropObjects[] = {
    { "disable-legacy",
      QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY,
      virQEMUCapsVirtioPCIDisableLegacyObjects }
};

1809 1810

static void
1811 1812 1813 1814 1815
virQEMUCapsProcessStringFlags(virQEMUCapsPtr qemuCaps,
                              size_t nflags,
                              struct virQEMUCapsStringFlags *flags,
                              size_t nvalues,
                              char *const*values)
1816 1817
{
    size_t i, j;
1818 1819
    for (i = 0; i < nflags; i++) {
        for (j = 0; j < nvalues; j++) {
1820
            if (STREQ(values[j], flags[i].value)) {
1821
                virQEMUCapsSet(qemuCaps, flags[i].flag);
1822 1823 1824 1825 1826 1827 1828
                break;
            }
        }
    }
}


1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844
static void
virQEMUCapsProcessProps(virQEMUCapsPtr qemuCaps,
                        size_t nprops,
                        struct virQEMUCapsPropTypeObjects *props,
                        const char *object,
                        size_t nvalues,
                        char *const*values)
{
    size_t i, j;

    for (i = 0; i < nprops; i++) {
        if (virQEMUCapsGet(qemuCaps, props[i].flag))
            continue;

        for (j = 0; j < nvalues; j++) {
            if (STREQ(values[j], props[i].prop)) {
1845
                if (virStringListHasString(props[i].objects, object))
1846 1847 1848 1849 1850 1851 1852 1853
                    virQEMUCapsSet(qemuCaps, props[i].flag);
                break;
            }
        }
    }
}


1854
static void
1855 1856
virQEMUCapsFreeStringList(size_t len,
                          char **values)
1857 1858
{
    size_t i;
1859 1860
    if (!values)
        return;
1861
    for (i = 0; i < len; i++)
1862 1863 1864 1865 1866 1867 1868 1869
        VIR_FREE(values[i]);
    VIR_FREE(values);
}


#define OBJECT_TYPE_PREFIX "name \""

static int
1870 1871
virQEMUCapsParseDeviceStrObjectTypes(const char *str,
                                     char ***types)
1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889
{
    const char *tmp = str;
    int ret = -1;
    size_t ntypelist = 0;
    char **typelist = NULL;

    *types = NULL;

    while ((tmp = strstr(tmp, OBJECT_TYPE_PREFIX))) {
        char *end;
        tmp += strlen(OBJECT_TYPE_PREFIX);
        end = strstr(tmp, "\"");
        if (!end) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Malformed QEMU device list string, missing quote"));
            goto cleanup;
        }

1890
        if (VIR_EXPAND_N(typelist, ntypelist, 1) < 0)
1891
            goto cleanup;
1892
        if (VIR_STRNDUP(typelist[ntypelist - 1], tmp, end-tmp) < 0)
1893 1894 1895 1896 1897 1898
            goto cleanup;
    }

    *types = typelist;
    ret = ntypelist;

1899
 cleanup:
1900
    if (ret < 0)
1901
        virQEMUCapsFreeStringList(ntypelist, typelist);
1902 1903 1904 1905 1906
    return ret;
}


static int
1907 1908 1909
virQEMUCapsParseDeviceStrObjectProps(const char *str,
                                     const char *type,
                                     char ***props)
1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942
{
    const char *tmp = str;
    int ret = -1;
    size_t nproplist = 0;
    char **proplist = NULL;

    VIR_DEBUG("Extract type %s", type);
    *props = NULL;

    while ((tmp = strchr(tmp, '\n'))) {
        char *end;
        tmp += 1;

        if (*tmp == '\0')
            break;

        if (STRPREFIX(tmp, OBJECT_TYPE_PREFIX))
            continue;

        if (!STRPREFIX(tmp, type))
            continue;

        tmp += strlen(type);
        if (*tmp != '.')
            continue;
        tmp++;

        end = strstr(tmp, "=");
        if (!end) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Malformed QEMU device list string, missing '='"));
            goto cleanup;
        }
1943
        if (VIR_EXPAND_N(proplist, nproplist, 1) < 0)
1944
            goto cleanup;
1945
        if (VIR_STRNDUP(proplist[nproplist - 1], tmp, end-tmp) < 0)
1946 1947 1948 1949 1950 1951
            goto cleanup;
    }

    *props = proplist;
    ret = nproplist;

1952
 cleanup:
1953
    if (ret < 0)
1954
        virQEMUCapsFreeStringList(nproplist, proplist);
1955 1956 1957 1958 1959
    return ret;
}


int
1960
virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps, const char *str)
1961 1962 1963 1964 1965
{
    int nvalues;
    char **values;
    size_t i;

1966
    if ((nvalues = virQEMUCapsParseDeviceStrObjectTypes(str, &values)) < 0)
1967
        return -1;
1968 1969 1970 1971 1972 1973
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsObjectTypes),
                                  virQEMUCapsObjectTypes,
                                  nvalues, values);
    virQEMUCapsFreeStringList(nvalues, values);

1974
    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsObjectProps); i++) {
1975 1976 1977 1978
        const char *type = virQEMUCapsObjectProps[i].type;
        if ((nvalues = virQEMUCapsParseDeviceStrObjectProps(str,
                                                            type,
                                                            &values)) < 0)
1979
            return -1;
1980 1981 1982 1983 1984
        virQEMUCapsProcessStringFlags(qemuCaps,
                                      virQEMUCapsObjectProps[i].nprops,
                                      virQEMUCapsObjectProps[i].props,
                                      nvalues, values);
        virQEMUCapsFreeStringList(nvalues, values);
1985 1986 1987
    }

    /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
1988 1989
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC);
1990 1991 1992 1993 1994

    return 0;
}


E
Eric Blake 已提交
1995
static int
1996 1997
virQEMUCapsExtractDeviceStr(const char *qemu,
                            virQEMUCapsPtr qemuCaps,
1998
                            uid_t runUid, gid_t runGid)
1999
{
E
Eric Blake 已提交
2000
    char *output = NULL;
2001
    virCommandPtr cmd;
E
Eric Blake 已提交
2002
    int ret = -1;
2003

E
Eric Blake 已提交
2004 2005
    /* Cram together all device-related queries into one invocation;
     * the output format makes it possible to distinguish what we
2006 2007
     * need.  With qemu 0.13.0 and later, unrecognized '-device
     * bogus,?' cause an error in isolation, but are silently ignored
2008
     * in combination with '-device ?'.  Upstream qemu 0.12.x doesn't
2009 2010
     * understand '-device name,?', and always exits with status 1 for
     * the simpler '-device ?', so this function is really only useful
2011
     * if -help includes "device driver,?".  */
2012
    cmd = virQEMUCapsProbeCommand(qemu, qemuCaps, runUid, runGid);
2013 2014 2015 2016 2017 2018
    virCommandAddArgList(cmd,
                         "-device", "?",
                         "-device", "pci-assign,?",
                         "-device", "virtio-blk-pci,?",
                         "-device", "virtio-net-pci,?",
                         "-device", "scsi-disk,?",
2019
                         "-device", "PIIX4_PM,?",
2020
                         "-device", "usb-redir,?",
2021
                         "-device", "ide-drive,?",
2022
                         "-device", "usb-host,?",
H
Han Cheng 已提交
2023
                         "-device", "scsi-generic,?",
2024
                         "-device", "usb-storage,?",
2025 2026 2027 2028
                         "-device", "VGA,?",
                         "-device", "vmware-svga,?",
                         "-device", "qxl,?",
                         "-device", "qxl-vga,?",
2029
                         NULL);
2030
    /* qemu -help goes to stdout, but qemu -device ? goes to stderr.  */
E
Eric Blake 已提交
2031
    virCommandSetErrorBuffer(cmd, &output);
2032

2033
    if (virCommandRun(cmd, NULL) < 0)
2034 2035
        goto cleanup;

2036
    ret = virQEMUCapsParseDeviceStr(qemuCaps, output);
2037

2038
 cleanup:
E
Eric Blake 已提交
2039
    VIR_FREE(output);
2040
    virCommandFree(cmd);
E
Eric Blake 已提交
2041 2042 2043
    return ret;
}

2044

2045 2046 2047
int virQEMUCapsGetDefaultVersion(virCapsPtr caps,
                                 virQEMUCapsCachePtr capsCache,
                                 unsigned int *version)
2048
{
2049
    virQEMUCapsPtr qemucaps;
T
Tal Kain 已提交
2050
    virArch hostarch;
2051
    virCapsDomainDataPtr capsdata;
2052 2053 2054 2055

    if (*version > 0)
        return 0;

T
Tal Kain 已提交
2056
    hostarch = virArchFromHost();
2057 2058 2059
    if (!(capsdata = virCapabilitiesDomainDataLookup(caps,
            VIR_DOMAIN_OSTYPE_HVM, hostarch, VIR_DOMAIN_VIRT_QEMU,
            NULL, NULL))) {
2060
        virReportError(VIR_ERR_INTERNAL_ERROR,
2061
                       _("Cannot find suitable emulator for %s"),
T
Tal Kain 已提交
2062
                       virArchToString(hostarch));
2063 2064 2065
        return -1;
    }

2066
    qemucaps = virQEMUCapsCacheLookup(caps, capsCache, capsdata->emulator);
2067 2068
    VIR_FREE(capsdata);
    if (!qemucaps)
2069 2070
        return -1;

2071
    *version = virQEMUCapsGetVersion(qemucaps);
2072
    virObjectUnref(qemucaps);
2073 2074
    return 0;
}
2075 2076


2077 2078


2079 2080
virQEMUCapsPtr
virQEMUCapsNew(void)
2081
{
2082
    virQEMUCapsPtr qemuCaps;
2083

2084
    if (virQEMUCapsInitialize() < 0)
2085 2086
        return NULL;

2087
    if (!(qemuCaps = virObjectNew(virQEMUCapsClass)))
2088 2089
        return NULL;

2090
    if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
2091
        goto error;
2092

2093
    return qemuCaps;
2094

2095
 error:
2096
    virObjectUnref(qemuCaps);
2097
    return NULL;
2098 2099 2100
}


2101
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
2102
{
2103
    virQEMUCapsPtr ret = virQEMUCapsNew();
2104 2105 2106 2107 2108
    size_t i;

    if (!ret)
        return NULL;

2109 2110
    ret->usedQMP = qemuCaps->usedQMP;

2111 2112 2113 2114 2115
    if (VIR_STRDUP(ret->binary, qemuCaps->binary) < 0)
        goto error;

    ret->ctime = qemuCaps->ctime;

2116
    virBitmapCopy(ret->flags, qemuCaps->flags);
2117

2118 2119
    ret->version = qemuCaps->version;
    ret->kvmVersion = qemuCaps->kvmVersion;
2120 2121 2122 2123

    if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
        goto error;

2124
    ret->arch = qemuCaps->arch;
2125

2126 2127 2128
    if (qemuCaps->cpuDefinitions) {
        ret->cpuDefinitions = virDomainCapsCPUModelsCopy(qemuCaps->cpuDefinitions);
        if (!ret->cpuDefinitions)
2129
            goto error;
2130 2131
    }

2132 2133 2134 2135
    if (qemuCaps->hostCPUModel &&
        !(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel)))
        goto error;

2136
    if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
2137
        goto error;
2138
    ret->nmachineTypes = qemuCaps->nmachineTypes;
2139
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2140 2141
        if (VIR_STRDUP(ret->machineTypes[i].name, qemuCaps->machineTypes[i].name) < 0 ||
            VIR_STRDUP(ret->machineTypes[i].alias, qemuCaps->machineTypes[i].alias) < 0)
2142
            goto error;
2143
        ret->machineTypes[i].maxCpus = qemuCaps->machineTypes[i].maxCpus;
2144
        ret->machineTypes[i].hotplugCpus = qemuCaps->machineTypes[i].hotplugCpus;
2145 2146
    }

2147 2148 2149 2150 2151 2152
    if (VIR_ALLOC_N(ret->gicCapabilities, qemuCaps->ngicCapabilities) < 0)
        goto error;
    ret->ngicCapabilities = qemuCaps->ngicCapabilities;
    for (i = 0; i < qemuCaps->ngicCapabilities; i++)
        ret->gicCapabilities[i] = qemuCaps->gicCapabilities[i];

2153 2154
    return ret;

2155
 error:
2156 2157 2158 2159 2160
    virObjectUnref(ret);
    return NULL;
}


2161
void virQEMUCapsDispose(void *obj)
2162
{
2163
    virQEMUCapsPtr qemuCaps = obj;
2164 2165
    size_t i;

2166
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2167 2168
        VIR_FREE(qemuCaps->machineTypes[i].name);
        VIR_FREE(qemuCaps->machineTypes[i].alias);
2169
    }
2170
    VIR_FREE(qemuCaps->machineTypes);
2171

2172
    virObjectUnref(qemuCaps->cpuDefinitions);
2173

2174
    virBitmapFree(qemuCaps->flags);
2175

2176
    VIR_FREE(qemuCaps->package);
2177
    VIR_FREE(qemuCaps->binary);
A
Andrea Bolognani 已提交
2178 2179

    VIR_FREE(qemuCaps->gicCapabilities);
2180 2181

    virCPUDefFree(qemuCaps->hostCPUModel);
2182 2183
}

2184
void
2185
virQEMUCapsSet(virQEMUCapsPtr qemuCaps,
2186
               virQEMUCapsFlags flag)
2187
{
2188
    ignore_value(virBitmapSetBit(qemuCaps->flags, flag));
2189 2190 2191 2192
}


void
2193
virQEMUCapsSetList(virQEMUCapsPtr qemuCaps, ...)
2194 2195 2196 2197
{
    va_list list;
    int flag;

2198
    va_start(list, qemuCaps);
2199
    while ((flag = va_arg(list, int)) < QEMU_CAPS_LAST)
2200
        ignore_value(virBitmapSetBit(qemuCaps->flags, flag));
2201
    va_end(list);
2202 2203 2204 2205
}


void
2206
virQEMUCapsClear(virQEMUCapsPtr qemuCaps,
2207
                 virQEMUCapsFlags flag)
2208
{
2209
    ignore_value(virBitmapClearBit(qemuCaps->flags, flag));
2210 2211 2212
}


2213
char *virQEMUCapsFlagsString(virQEMUCapsPtr qemuCaps)
2214
{
2215
    return virBitmapString(qemuCaps->flags);
2216 2217 2218 2219
}


bool
2220
virQEMUCapsGet(virQEMUCapsPtr qemuCaps,
2221
               virQEMUCapsFlags flag)
2222
{
J
Ján Tomko 已提交
2223
    return qemuCaps && virBitmapIsBitSet(qemuCaps->flags, flag);
2224
}
2225 2226


D
Daniel P. Berrange 已提交
2227 2228 2229 2230 2231 2232 2233 2234 2235
bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
                               virDomainDefPtr def)
{
    bool hasMultiBus = virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);

    if (hasMultiBus)
        return true;

    if (def->os.arch == VIR_ARCH_PPC ||
2236
        ARCH_IS_PPC64(def->os.arch)) {
D
Daniel P. Berrange 已提交
2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272
        /*
         * Usage of pci.0 naming:
         *
         *    ref405ep: no pci
         *       taihu: no pci
         *      bamboo: 1.1.0
         *       mac99: 2.0.0
         *     g3beige: 2.0.0
         *        prep: 1.4.0
         *     pseries: 2.0.0
         *   mpc8544ds: forever
         * virtex-m507: no pci
         *     ppce500: 1.6.0
         */

        if (qemuCaps->version >= 2000000)
            return true;

        if (qemuCaps->version >= 1006000 &&
            STREQ(def->os.machine, "ppce500"))
            return true;

        if (qemuCaps->version >= 1004000 &&
            STREQ(def->os.machine, "prep"))
            return true;

        if (qemuCaps->version >= 1001000 &&
            STREQ(def->os.machine, "bamboo"))
            return true;

        if (STREQ(def->os.machine, "mpc8544ds"))
            return true;

        return false;
    }

2273 2274 2275 2276 2277
    /* If 'virt' supports PCI, it supports multibus.
     * No extra conditions here for simplicity.
     */
    if (qemuDomainMachineIsVirt(def))
        return true;
2278

D
Daniel P. Berrange 已提交
2279 2280 2281 2282
    return false;
}


2283
const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps)
2284
{
2285
    return qemuCaps->binary;
2286 2287
}

2288 2289 2290 2291 2292 2293 2294 2295 2296

void
virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps,
                   virArch arch)
{
    qemuCaps->arch = arch;
}


2297
virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps)
2298
{
2299
    return qemuCaps->arch;
2300 2301 2302
}


2303
unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps)
2304
{
2305
    return qemuCaps->version;
2306 2307 2308
}


2309
unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps)
2310
{
2311
    return qemuCaps->kvmVersion;
2312 2313 2314
}


2315 2316 2317 2318 2319 2320
const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
{
    return qemuCaps->package;
}


2321 2322 2323 2324
int
virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
                             const char **name,
                             size_t count)
2325
{
2326
    size_t i;
2327

2328 2329
    if (!qemuCaps->cpuDefinitions &&
        !(qemuCaps->cpuDefinitions = virDomainCapsCPUModelsNew(count)))
2330
        return -1;
2331 2332

    for (i = 0; i < count; i++) {
J
Jiri Denemark 已提交
2333 2334
        if (virDomainCapsCPUModelsAdd(qemuCaps->cpuDefinitions, name[i], -1,
                                      VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
2335
            return -1;
2336
    }
2337

2338 2339 2340 2341
    return 0;
}


2342 2343 2344 2345
int
virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
                             char ***names,
                             size_t *count)
2346
{
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365
    size_t i;
    char **models = NULL;

    *count = 0;
    if (names)
        *names = NULL;

    if (!qemuCaps->cpuDefinitions)
        return 0;

    if (names && VIR_ALLOC_N(models, qemuCaps->cpuDefinitions->nmodels) < 0)
        return -1;

    for (i = 0; i < qemuCaps->cpuDefinitions->nmodels; i++) {
        virDomainCapsCPUModelPtr cpu = qemuCaps->cpuDefinitions->models + i;
        if (models && VIR_STRDUP(models[i], cpu->name) < 0)
            goto error;
    }

2366
    if (names)
2367 2368 2369 2370 2371
        *names = models;
    *count = qemuCaps->cpuDefinitions->nmodels;
    return 0;

 error:
2372
    virStringListFreeCount(models, i);
2373
    return -1;
2374 2375 2376
}


2377 2378 2379 2380 2381 2382 2383
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps)
{
    return qemuCaps->hostCPUModel;
}


2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409
bool
virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
                              virCapsPtr caps,
                              virDomainVirtType type,
                              virCPUMode mode)
{
    switch (mode) {
    case VIR_CPU_MODE_HOST_PASSTHROUGH:
        return type == VIR_DOMAIN_VIRT_KVM &&
               virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch);

    case VIR_CPU_MODE_HOST_MODEL:
        return !!qemuCaps->hostCPUModel;

    case VIR_CPU_MODE_CUSTOM:
        return qemuCaps->cpuDefinitions &&
               qemuCaps->cpuDefinitions->nmodels > 0;

    case VIR_CPU_MODE_LAST:
        break;
    }

    return false;
}


2410 2411 2412
int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
                                   size_t *nmachines,
                                   virCapsGuestMachinePtr **machines)
2413 2414 2415 2416
{
    size_t i;

    *machines = NULL;
2417
    *nmachines = qemuCaps->nmachineTypes;
2418

2419 2420 2421 2422
    if (*nmachines &&
        VIR_ALLOC_N(*machines, qemuCaps->nmachineTypes) < 0)
        goto error;

2423
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2424 2425
        virCapsGuestMachinePtr mach;
        if (VIR_ALLOC(mach) < 0)
2426
            goto error;
2427
        (*machines)[i] = mach;
2428 2429 2430
        if (qemuCaps->machineTypes[i].alias) {
            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i].alias) < 0 ||
                VIR_STRDUP(mach->canonical, qemuCaps->machineTypes[i].name) < 0)
2431
                goto error;
2432
        } else {
2433
            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i].name) < 0)
2434
                goto error;
2435
        }
2436
        mach->maxCpus = qemuCaps->machineTypes[i].maxCpus;
2437 2438
    }

2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476
    /* Make sure all canonical machine types also have their own entry so that
     * /capabilities/guest/arch[@name='...']/machine/text() XPath selects all
     * supported machine types.
     */
    i = 0;
    while (i < *nmachines) {
        size_t j;
        bool found = false;
        virCapsGuestMachinePtr machine = (*machines)[i];

        if (!machine->canonical) {
            i++;
            continue;
        }

        for (j = 0; j < *nmachines; j++) {
            if (STREQ(machine->canonical, (*machines)[j]->name)) {
                found = true;
                break;
            }
        }

        if (!found) {
            virCapsGuestMachinePtr mach;
            if (VIR_ALLOC(mach) < 0)
                goto error;
            if (VIR_INSERT_ELEMENT_COPY(*machines, i, *nmachines, mach) < 0) {
                VIR_FREE(mach);
                goto error;
            }
            if (VIR_STRDUP(mach->name, machine->canonical) < 0)
                goto error;
            mach->maxCpus = machine->maxCpus;
            i++;
        }
        i++;
    }

2477 2478
    return 0;

2479
 error:
2480 2481 2482 2483 2484 2485 2486 2487
    virCapabilitiesFreeMachines(*machines, *nmachines);
    *nmachines = 0;
    *machines = NULL;
    return -1;
}



2488

2489 2490
const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
                                           const char *name)
2491 2492 2493
{
    size_t i;

2494 2495 2496
    if (!name)
        return NULL;

2497
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2498
        if (!qemuCaps->machineTypes[i].alias)
2499
            continue;
2500 2501
        if (STREQ(qemuCaps->machineTypes[i].alias, name))
            return qemuCaps->machineTypes[i].name;
2502 2503 2504 2505
    }

    return name;
}
2506 2507


2508 2509 2510 2511 2512 2513 2514 2515 2516
int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,
                                 const char *name)
{
    size_t i;

    if (!name)
        return 0;

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2517
        if (!qemuCaps->machineTypes[i].maxCpus)
2518
            continue;
2519 2520
        if (STREQ(qemuCaps->machineTypes[i].name, name))
            return qemuCaps->machineTypes[i].maxCpus;
2521 2522 2523 2524 2525 2526
    }

    return 0;
}


2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540
bool virQEMUCapsGetMachineHotplugCpus(virQEMUCapsPtr qemuCaps,
                                      const char *name)
{
    size_t i;

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
        if (STREQ_NULLABLE(qemuCaps->machineTypes[i].name, name))
            return qemuCaps->machineTypes[i].hotplugCpus;
    }

    return false;
}


2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564
/**
 * virQEMUCapsSetGICCapabilities:
 * @qemuCaps: QEMU capabilities
 * @capabilities: GIC capabilities
 * @ncapabilities: number of GIC capabilities
 *
 * Set the GIC capabilities for @qemuCaps.
 *
 * The ownership of @capabilities is taken away from the caller, ie. this
 * function will not make a copy of @capabilities, so releasing that memory
 * after it's been called is a bug.
 */
void
virQEMUCapsSetGICCapabilities(virQEMUCapsPtr qemuCaps,
                              virGICCapability *capabilities,
                              size_t ncapabilities)
{
    VIR_FREE(qemuCaps->gicCapabilities);

    qemuCaps->gicCapabilities = capabilities;
    qemuCaps->ngicCapabilities = ncapabilities;
}


2565
static int
2566 2567
virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
2568 2569 2570 2571 2572 2573 2574
{
    char **commands = NULL;
    int ncommands;

    if ((ncommands = qemuMonitorGetCommands(mon, &commands)) < 0)
        return -1;

2575 2576 2577 2578 2579
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsCommands),
                                  virQEMUCapsCommands,
                                  ncommands, commands);
    virQEMUCapsFreeStringList(ncommands, commands);
2580

2581 2582 2583 2584
    /* QMP add-fd was introduced in 1.2, but did not support
     * management control of set numbering, and did not have a
     * counterpart -add-fd command line option.  We require the
     * add-fd features from 1.3 or later.  */
2585
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ADD_FD)) {
2586 2587 2588 2589 2590 2591 2592
        int fd = open("/dev/null", O_RDONLY);
        if (fd < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unable to probe for add-fd"));
            return -1;
        }
        if (qemuMonitorAddFd(mon, 0, fd, "/dev/null") < 0)
2593
            virQEMUCapsClear(qemuCaps, QEMU_CAPS_ADD_FD);
2594 2595 2596
        VIR_FORCE_CLOSE(fd);
    }

2597 2598 2599 2600 2601 2602
    /* Probe for active commit of qemu 2.1 (for now, we are choosing
     * to ignore the fact that qemu 2.0 can also do active commit) */
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCK_COMMIT) &&
        qemuMonitorSupportsActiveCommit(mon))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ACTIVE_COMMIT);

2603 2604 2605 2606 2607
    return 0;
}


static int
2608 2609
virQEMUCapsProbeQMPEvents(virQEMUCapsPtr qemuCaps,
                          qemuMonitorPtr mon)
2610 2611 2612 2613 2614 2615 2616
{
    char **events = NULL;
    int nevents;

    if ((nevents = qemuMonitorGetEvents(mon, &events)) < 0)
        return -1;

2617 2618 2619 2620 2621
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsEvents),
                                  virQEMUCapsEvents,
                                  nevents, events);
    virQEMUCapsFreeStringList(nevents, events);
2622 2623 2624 2625 2626

    return 0;
}


2627
static int
2628 2629
virQEMUCapsProbeQMPObjects(virQEMUCapsPtr qemuCaps,
                           qemuMonitorPtr mon)
2630 2631 2632 2633 2634 2635 2636
{
    int nvalues;
    char **values;
    size_t i;

    if ((nvalues = qemuMonitorGetObjectTypes(mon, &values)) < 0)
        return -1;
2637 2638 2639 2640 2641 2642
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsObjectTypes),
                                  virQEMUCapsObjectTypes,
                                  nvalues, values);
    virQEMUCapsFreeStringList(nvalues, values);

2643
    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsObjectProps); i++) {
2644
        const char *type = virQEMUCapsObjectProps[i].type;
2645 2646 2647 2648
        if ((nvalues = qemuMonitorGetObjectProps(mon,
                                                 type,
                                                 &values)) < 0)
            return -1;
2649 2650 2651 2652
        virQEMUCapsProcessStringFlags(qemuCaps,
                                      virQEMUCapsObjectProps[i].nprops,
                                      virQEMUCapsObjectProps[i].props,
                                      nvalues, values);
2653 2654 2655 2656
        virQEMUCapsProcessProps(qemuCaps,
                                ARRAY_CARDINALITY(virQEMUCapsPropObjects),
                                virQEMUCapsPropObjects, type,
                                nvalues, values);
2657
        virQEMUCapsFreeStringList(nvalues, values);
2658 2659 2660
    }

    /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
2661 2662
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC);
2663 2664 2665 2666 2667 2668

    return 0;
}


static int
2669 2670
virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
                                qemuMonitorPtr mon)
2671 2672 2673 2674 2675
{
    qemuMonitorMachineInfoPtr *machines = NULL;
    int nmachines = 0;
    int ret = -1;
    size_t i;
2676
    size_t defIdx = 0;
2677 2678

    if ((nmachines = qemuMonitorGetMachines(mon, &machines)) < 0)
2679
        return -1;
2680

2681
    if (VIR_ALLOC_N(qemuCaps->machineTypes, nmachines) < 0)
2682 2683
        goto cleanup;

2684
    for (i = 0; i < nmachines; i++) {
2685
        struct virQEMUCapsMachineType *mach;
2686 2687
        if (STREQ(machines[i]->name, "none"))
            continue;
2688 2689 2690 2691 2692

        mach = &(qemuCaps->machineTypes[qemuCaps->nmachineTypes++]);

        if (VIR_STRDUP(mach->alias, machines[i]->alias) < 0 ||
            VIR_STRDUP(mach->name, machines[i]->name) < 0)
2693
            goto cleanup;
2694 2695

        mach->maxCpus = machines[i]->maxCpus;
2696
        mach->hotplugCpus = machines[i]->hotplugCpus;
2697

2698
        if (machines[i]->isDefault)
2699
            defIdx = qemuCaps->nmachineTypes - 1;
2700
    }
2701 2702

    if (defIdx)
2703
        virQEMUCapsSetDefaultMachine(qemuCaps, defIdx);
2704 2705 2706

    ret = 0;

2707
 cleanup:
2708
    for (i = 0; i < nmachines; i++)
2709 2710 2711 2712 2713 2714 2715
        qemuMonitorMachineInfoFree(machines[i]);
    VIR_FREE(machines);
    return ret;
}


static int
2716 2717
virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps,
                                  qemuMonitorPtr mon)
2718
{
2719 2720 2721 2722
    qemuMonitorCPUDefInfoPtr *cpus;
    int ncpus;
    int ret = -1;
    size_t i;
2723

2724
    if ((ncpus = qemuMonitorGetCPUDefinitions(mon, &cpus)) < 0)
2725 2726
        return -1;

2727 2728
    if (!(qemuCaps->cpuDefinitions = virDomainCapsCPUModelsNew(ncpus)))
        goto cleanup;
2729

2730 2731
    for (i = 0; i < ncpus; i++) {
        if (virDomainCapsCPUModelsAddSteal(qemuCaps->cpuDefinitions,
J
Jiri Denemark 已提交
2732 2733
                                           &cpus[i]->name,
                                           VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
2734 2735 2736 2737 2738 2739 2740 2741 2742 2743
            goto cleanup;
    }

    ret = 0;

 cleanup:
    for (i = 0; i < ncpus; i++)
        qemuMonitorCPUDefInfoFree(cpus[i]);
    VIR_FREE(cpus);
    return ret;
2744 2745
}

2746 2747
struct tpmTypeToCaps {
    int type;
2748
    virQEMUCapsFlags caps;
2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768
};

static const struct tpmTypeToCaps virQEMUCapsTPMTypesToCaps[] = {
    {
        .type = VIR_DOMAIN_TPM_TYPE_PASSTHROUGH,
        .caps = QEMU_CAPS_DEVICE_TPM_PASSTHROUGH,
    },
};

const struct tpmTypeToCaps virQEMUCapsTPMModelsToCaps[] = {
    {
        .type = VIR_DOMAIN_TPM_MODEL_TIS,
        .caps = QEMU_CAPS_DEVICE_TPM_TIS,
    },
};

static int
virQEMUCapsProbeQMPTPM(virQEMUCapsPtr qemuCaps,
                       qemuMonitorPtr mon)
{
2769 2770
    int nentries;
    size_t i;
2771
    char **entries = NULL;
S
Stefan Berger 已提交
2772

2773 2774 2775 2776 2777 2778 2779
    if ((nentries = qemuMonitorGetTPMModels(mon, &entries)) < 0)
        return -1;

    if (nentries > 0) {
        for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsTPMModelsToCaps); i++) {
            const char *needle = virDomainTPMModelTypeToString(
                virQEMUCapsTPMModelsToCaps[i].type);
2780
            if (virStringListHasString((const char **) entries, needle))
2781 2782 2783 2784
                virQEMUCapsSet(qemuCaps,
                               virQEMUCapsTPMModelsToCaps[i].caps);
        }
    }
2785
    virStringListFree(entries);
2786 2787 2788 2789 2790 2791 2792 2793

    if ((nentries = qemuMonitorGetTPMTypes(mon, &entries)) < 0)
        return -1;

    if (nentries > 0) {
        for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsTPMTypesToCaps); i++) {
            const char *needle = virDomainTPMBackendTypeToString(
                virQEMUCapsTPMTypesToCaps[i].type);
2794
            if (virStringListHasString((const char **) entries, needle))
2795 2796 2797
                virQEMUCapsSet(qemuCaps, virQEMUCapsTPMTypesToCaps[i].caps);
        }
    }
2798
    virStringListFree(entries);
2799 2800 2801 2802

    return 0;
}

2803

2804
static int
2805 2806
virQEMUCapsProbeQMPKVMState(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
2807 2808 2809 2810
{
    bool enabled = false;
    bool present = false;

2811
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
2812 2813 2814 2815 2816 2817
        return 0;

    if (qemuMonitorGetKVMState(mon, &enabled, &present) < 0)
        return -1;

    /* The QEMU_CAPS_KVM flag was initially set according to the QEMU
2818
     * reporting the recognition of 'query-kvm' QMP command. That merely
N
Nehal J Wani 已提交
2819
     * indicates existence of the command though, not whether KVM support
2820 2821 2822 2823 2824 2825
     * is actually available, nor whether it is enabled by default.
     *
     * If it is not present we need to clear the flag, and if it is
     * not enabled by default we need to change the flag.
     */
    if (!present) {
2826
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_KVM);
2827
    } else if (!enabled) {
2828 2829
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_KVM);
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ENABLE_KVM);
2830 2831 2832 2833 2834
    }

    return 0;
}

2835 2836 2837 2838 2839 2840 2841 2842
struct virQEMUCapsCommandLineProps {
    const char *option;
    const char *param;
    int flag;
};

static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
    { "machine", "mem-merge", QEMU_CAPS_MEM_MERGE },
2843
    { "machine", "vmport", QEMU_CAPS_MACHINE_VMPORT_OPT },
O
Osier Yang 已提交
2844
    { "drive", "discard", QEMU_CAPS_DRIVE_DISCARD },
2845
    { "drive", "detect-zeroes", QEMU_CAPS_DRIVE_DETECT_ZEROES },
2846
    { "realtime", "mlock", QEMU_CAPS_REALTIME_MLOCK },
2847
    { "boot-opts", "strict", QEMU_CAPS_BOOT_STRICT },
2848
    { "boot-opts", "reboot-timeout", QEMU_CAPS_REBOOT_TIMEOUT },
2849
    { "boot-opts", "splash-time", QEMU_CAPS_SPLASH_TIMEOUT },
2850
    { "spice", "disable-agent-file-xfer", QEMU_CAPS_SPICE_FILE_XFER_DISABLE },
2851
    { "msg", "timestamp", QEMU_CAPS_MSG_TIMESTAMP },
2852
    { "numa", NULL, QEMU_CAPS_NUMA },
2853
    { "drive", "throttling.bps-total-max", QEMU_CAPS_DRIVE_IOTUNE_MAX},
2854 2855
    { "machine", "aes-key-wrap", QEMU_CAPS_AES_KEY_WRAP },
    { "machine", "dea-key-wrap", QEMU_CAPS_DEA_KEY_WRAP },
2856
    { "chardev", "append", QEMU_CAPS_CHARDEV_FILE_APPEND },
2857
    { "spice", "gl", QEMU_CAPS_SPICE_GL },
2858
    { "chardev", "logfile", QEMU_CAPS_CHARDEV_LOGFILE },
2859
    { "name", "debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS },
2860
    { "name", "guest", QEMU_CAPS_NAME_GUEST },
2861
    { "spice", "unix", QEMU_CAPS_SPICE_UNIX },
2862
    { "drive", "throttling.bps-total-max-length", QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH },
2863 2864 2865 2866 2867 2868
};

static int
virQEMUCapsProbeQMPCommandLine(virQEMUCapsPtr qemuCaps,
                               qemuMonitorPtr mon)
{
2869
    bool found = false;
2870 2871 2872 2873 2874 2875 2876
    int nvalues;
    char **values;
    size_t i, j;

    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsCommandLine); i++) {
        if ((nvalues = qemuMonitorGetCommandLineOptionParameters(mon,
                                                                 virQEMUCapsCommandLine[i].option,
2877 2878
                                                                 &values,
                                                                 &found)) < 0)
2879
            return -1;
2880 2881 2882 2883

        if (found && !virQEMUCapsCommandLine[i].param)
            virQEMUCapsSet(qemuCaps, virQEMUCapsCommandLine[i].flag);

2884
        for (j = 0; j < nvalues; j++) {
2885
            if (STREQ_NULLABLE(virQEMUCapsCommandLine[i].param, values[j])) {
2886 2887 2888 2889
                virQEMUCapsSet(qemuCaps, virQEMUCapsCommandLine[i].flag);
                break;
            }
        }
2890
        virStringListFree(values);
2891 2892 2893 2894
    }

    return 0;
}
2895

2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914
static int
virQEMUCapsProbeQMPMigrationCapabilities(virQEMUCapsPtr qemuCaps,
                                         qemuMonitorPtr mon)
{
    char **caps = NULL;
    int ncaps;

    if ((ncaps = qemuMonitorGetMigrationCapabilities(mon, &caps)) < 0)
        return -1;

    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsMigration),
                                  virQEMUCapsMigration,
                                  ncaps, caps);
    virQEMUCapsFreeStringList(ncaps, caps);

    return 0;
}

A
Andrea Bolognani 已提交
2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934
/**
 * virQEMUCapsProbeQMPGICCapabilities:
 * @qemuCaps: QEMU binary capabilities
 * @mon: QEMU monitor
 *
 * Use @mon to obtain information about the GIC capabilities for the
 * corresponding QEMU binary, and store them in @qemuCaps.
 *
 * Returns: 0 on success, <0 on failure
 */
static int
virQEMUCapsProbeQMPGICCapabilities(virQEMUCapsPtr qemuCaps,
                                   qemuMonitorPtr mon)
{
    virGICCapability *caps = NULL;
    int ncaps;

    if ((ncaps = qemuMonitorGetGICCapabilities(mon, &caps)) < 0)
        return -1;

2935
    virQEMUCapsSetGICCapabilities(qemuCaps, caps, ncaps);
A
Andrea Bolognani 已提交
2936 2937 2938 2939

    return 0;
}

2940 2941
int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
                        qemuMonitorPtr mon)
2942
{
2943
    VIR_DEBUG("qemuCaps=%p mon=%p", qemuCaps, mon);
2944

2945
    if (qemuCaps->usedQMP)
2946 2947
        return 0;

2948
    if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
2949 2950
        return -1;

2951
    if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
2952 2953 2954 2955 2956 2957
        return -1;

    return 0;
}


2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970
static bool
virQEMUCapsCPUFilterFeatures(const char *name,
                             void *opaque ATTRIBUTE_UNUSED)
{
    if (STREQ(name, "cmt") ||
        STREQ(name, "mbm_total") ||
        STREQ(name, "mbm_local"))
        return false;

    return true;
}


2971 2972
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
J
Jiri Denemark 已提交
2973
                            virCapsPtr caps)
2974 2975 2976
{
    virCPUDefPtr cpu = NULL;

J
Jiri Denemark 已提交
2977 2978 2979 2980
    if (!caps)
        return;

    if (!virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
2981 2982
        goto error;

J
Jiri Denemark 已提交
2983
    if (caps->host.cpu && caps->host.cpu->model) {
2984 2985 2986 2987 2988 2989 2990 2991
        if (VIR_ALLOC(cpu) < 0)
            goto error;

        cpu->sockets = cpu->cores = cpu->threads = 0;
        cpu->type = VIR_CPU_TYPE_GUEST;
        cpu->mode = VIR_CPU_MODE_CUSTOM;
        cpu->match = VIR_CPU_MATCH_EXACT;

J
Jiri Denemark 已提交
2992
        if (virCPUDefCopyModelFilter(cpu, caps->host.cpu, true,
2993
                                     virQEMUCapsCPUFilterFeatures, NULL) < 0)
2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006
            goto error;
    }

    qemuCaps->hostCPUModel = cpu;
    return;

 error:
    virCPUDefFree(cpu);
    qemuCaps->hostCPUModel = NULL;
    virResetLastError();
}


3007 3008 3009 3010 3011 3012
/*
 * Parsing a doc that looks like
 *
 * <qemuCaps>
 *   <qemuctime>234235253</qemuctime>
 *   <selfctime>234235253</selfctime>
3013
 *   <selfvers>1002016</selfvers>
3014 3015 3016 3017 3018 3019
 *   <usedQMP/>
 *   <flag name='foo'/>
 *   <flag name='bar'/>
 *   ...
 *   <cpu name="pentium3"/>
 *   ...
3020
 *   <machine name="pc-1.0" alias="pc" hotplugCpus='yes' maxCpus="4"/>
3021 3022 3023
 *   ...
 * </qemuCaps>
 */
3024
int
3025 3026 3027 3028
virQEMUCapsLoadCache(virCapsPtr caps,
                     virQEMUCapsPtr qemuCaps,
                     const char *filename,
                     time_t *selfctime,
3029
                     unsigned long *selfvers)
3030 3031 3032 3033 3034 3035 3036
{
    xmlDocPtr doc = NULL;
    int ret = -1;
    size_t i;
    int n;
    xmlNodePtr *nodes = NULL;
    xmlXPathContextPtr ctxt = NULL;
J
Ján Tomko 已提交
3037
    char *str = NULL;
3038
    long long int l;
3039
    unsigned long lu;
3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063

    if (!(doc = virXMLParseFile(filename)))
        goto cleanup;

    if (!(ctxt = xmlXPathNewContext(doc))) {
        virReportOOMError();
        goto cleanup;
    }

    ctxt->node = xmlDocGetRootElement(doc);

    if (STRNEQ((const char *)ctxt->node->name, "qemuCaps")) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("unexpected root element <%s>, "
                         "expecting <qemuCaps>"),
                       ctxt->node->name);
        goto cleanup;
    }

    if (virXPathLongLong("string(./qemuctime)", ctxt, &l) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing qemuctime in QEMU capabilities XML"));
        goto cleanup;
    }
3064
    qemuCaps->ctime = (time_t)l;
3065 3066 3067 3068 3069 3070 3071 3072

    if (virXPathLongLong("string(./selfctime)", ctxt, &l) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing selfctime in QEMU capabilities XML"));
        goto cleanup;
    }
    *selfctime = (time_t)l;

3073 3074 3075 3076
    *selfvers = 0;
    if (virXPathULong("string(./selfvers)", ctxt, &lu) == 0)
        *selfvers = lu;

3077 3078 3079 3080 3081 3082 3083 3084 3085
    qemuCaps->usedQMP = virXPathBoolean("count(./usedQMP) > 0",
                                        ctxt) > 0;

    if ((n = virXPathNodeSet("./flag", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities flags"));
        goto cleanup;
    }
    VIR_DEBUG("Got flags %d", n);
3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097
    for (i = 0; i < n; i++) {
        int flag;
        if (!(str = virXMLPropString(nodes[i], "name"))) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("missing flag name in QEMU capabilities cache"));
            goto cleanup;
        }
        flag = virQEMUCapsTypeFromString(str);
        if (flag < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unknown qemu capabilities flag %s"), str);
            goto cleanup;
3098
        }
3099 3100
        VIR_FREE(str);
        virQEMUCapsSet(qemuCaps, flag);
3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115
    }
    VIR_FREE(nodes);

    if (virXPathUInt("string(./version)", ctxt, &qemuCaps->version) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing version in QEMU capabilities cache"));
        goto cleanup;
    }

    if (virXPathUInt("string(./kvmVersion)", ctxt, &qemuCaps->kvmVersion) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing version in QEMU capabilities cache"));
        goto cleanup;
    }

3116 3117 3118 3119 3120 3121
    if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
        qemuCaps->package = virXPathString("string(./package)", ctxt);
        if (!qemuCaps->package &&
            VIR_STRDUP(qemuCaps->package, "") < 0)
            goto cleanup;
    }
3122

3123 3124 3125 3126 3127 3128 3129 3130 3131 3132
    if (!(str = virXPathString("string(./arch)", ctxt))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing arch in QEMU capabilities cache"));
        goto cleanup;
    }
    if (!(qemuCaps->arch = virArchFromString(str))) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown arch %s in QEMU capabilities cache"), str);
        goto cleanup;
    }
J
Ján Tomko 已提交
3133
    VIR_FREE(str);
3134 3135 3136 3137 3138 3139 3140

    if ((n = virXPathNodeSet("./cpu", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities cpus"));
        goto cleanup;
    }
    if (n > 0) {
3141
        if (!(qemuCaps->cpuDefinitions = virDomainCapsCPUModelsNew(n)))
3142 3143 3144
            goto cleanup;

        for (i = 0; i < n; i++) {
3145
            if (!(str = virXMLPropString(nodes[i], "name"))) {
3146 3147 3148 3149
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing cpu name in QEMU capabilities cache"));
                goto cleanup;
            }
3150 3151

            if (virDomainCapsCPUModelsAddSteal(qemuCaps->cpuDefinitions,
J
Jiri Denemark 已提交
3152 3153
                                               &str,
                                               VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
3154
                goto cleanup;
3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166
        }
    }
    VIR_FREE(nodes);


    if ((n = virXPathNodeSet("./machine", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities machines"));
        goto cleanup;
    }
    if (n > 0) {
        qemuCaps->nmachineTypes = n;
3167
        if (VIR_ALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes) < 0)
3168 3169 3170
            goto cleanup;

        for (i = 0; i < n; i++) {
3171
            if (!(qemuCaps->machineTypes[i].name = virXMLPropString(nodes[i], "name"))) {
3172 3173 3174 3175
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing machine name in QEMU capabilities cache"));
                goto cleanup;
            }
3176
            qemuCaps->machineTypes[i].alias = virXMLPropString(nodes[i], "alias");
3177 3178 3179

            str = virXMLPropString(nodes[i], "maxCpus");
            if (str &&
3180
                virStrToLong_ui(str, NULL, 10, &(qemuCaps->machineTypes[i].maxCpus)) < 0) {
3181 3182 3183 3184
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed machine cpu count in QEMU capabilities cache"));
                goto cleanup;
            }
J
Ján Tomko 已提交
3185
            VIR_FREE(str);
3186 3187 3188 3189 3190

            str = virXMLPropString(nodes[i], "hotplugCpus");
            if (STREQ_NULLABLE(str, "yes"))
                qemuCaps->machineTypes[i].hotplugCpus = true;
            VIR_FREE(str);
3191 3192 3193 3194
        }
    }
    VIR_FREE(nodes);

A
Andrea Bolognani 已提交
3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260
    if ((n = virXPathNodeSet("./gic", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities gic"));
        goto cleanup;
    }
    if (n > 0) {
        unsigned int uintValue;
        bool boolValue;

        qemuCaps->ngicCapabilities = n;
        if (VIR_ALLOC_N(qemuCaps->gicCapabilities, n) < 0)
            goto cleanup;

        for (i = 0; i < n; i++) {
            virGICCapabilityPtr cap = &qemuCaps->gicCapabilities[i];

            if (!(str = virXMLPropString(nodes[i], "version"))) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing GIC version "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (virStrToLong_ui(str, NULL, 10, &uintValue) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed GIC version "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            cap->version = uintValue;
            VIR_FREE(str);

            if (!(str = virXMLPropString(nodes[i], "kernel"))) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing in-kernel GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (!(boolValue = STREQ(str, "yes")) && STRNEQ(str, "no")) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed in-kernel GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (boolValue)
                cap->implementation |= VIR_GIC_IMPLEMENTATION_KERNEL;
            VIR_FREE(str);

            if (!(str = virXMLPropString(nodes[i], "emulated"))) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing emulated GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (!(boolValue = STREQ(str, "yes")) && STRNEQ(str, "no")) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed emulated GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (boolValue)
                cap->implementation |= VIR_GIC_IMPLEMENTATION_EMULATED;
            VIR_FREE(str);
        }
    }
    VIR_FREE(nodes);

J
Jiri Denemark 已提交
3261
    virQEMUCapsInitHostCPUModel(qemuCaps, caps);
3262

3263
    ret = 0;
3264
 cleanup:
J
Ján Tomko 已提交
3265
    VIR_FREE(str);
3266 3267 3268 3269 3270 3271 3272
    VIR_FREE(nodes);
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(doc);
    return ret;
}


3273
char *
3274 3275 3276
virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
                       time_t selfCTime,
                       unsigned long selfVersion)
3277 3278
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
3279
    char *ret = NULL;
3280 3281 3282
    size_t i;

    virBufferAddLit(&buf, "<qemuCaps>\n");
3283
    virBufferAdjustIndent(&buf, 2);
3284

3285
    virBufferAsprintf(&buf, "<qemuctime>%llu</qemuctime>\n",
3286
                      (long long) qemuCaps->ctime);
3287
    virBufferAsprintf(&buf, "<selfctime>%llu</selfctime>\n",
3288
                      (long long) selfCTime);
3289
    virBufferAsprintf(&buf, "<selfvers>%lu</selfvers>\n",
3290
                      (unsigned long) selfVersion);
3291 3292

    if (qemuCaps->usedQMP)
3293
        virBufferAddLit(&buf, "<usedQMP/>\n");
3294 3295 3296

    for (i = 0; i < QEMU_CAPS_LAST; i++) {
        if (virQEMUCapsGet(qemuCaps, i)) {
3297
            virBufferAsprintf(&buf, "<flag name='%s'/>\n",
3298 3299 3300 3301
                              virQEMUCapsTypeToString(i));
        }
    }

3302
    virBufferAsprintf(&buf, "<version>%d</version>\n",
3303 3304
                      qemuCaps->version);

3305
    virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n",
3306 3307
                      qemuCaps->kvmVersion);

3308 3309 3310 3311
    if (qemuCaps->package)
        virBufferAsprintf(&buf, "<package>%s</package>\n",
                          qemuCaps->package);

3312
    virBufferAsprintf(&buf, "<arch>%s</arch>\n",
3313 3314
                      virArchToString(qemuCaps->arch));

3315 3316 3317 3318 3319
    if (qemuCaps->cpuDefinitions) {
        for (i = 0; i < qemuCaps->cpuDefinitions->nmodels; i++) {
            virDomainCapsCPUModelPtr cpu = qemuCaps->cpuDefinitions->models + i;
            virBufferEscapeString(&buf, "<cpu name='%s'/>\n", cpu->name);
        }
3320 3321 3322
    }

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
3323
        virBufferEscapeString(&buf, "<machine name='%s'",
3324 3325
                              qemuCaps->machineTypes[i].name);
        if (qemuCaps->machineTypes[i].alias)
3326
            virBufferEscapeString(&buf, " alias='%s'",
3327
                              qemuCaps->machineTypes[i].alias);
3328 3329
        if (qemuCaps->machineTypes[i].hotplugCpus)
            virBufferAddLit(&buf, " hotplugCpus='yes'");
3330
        virBufferAsprintf(&buf, " maxCpus='%u'/>\n",
3331
                          qemuCaps->machineTypes[i].maxCpus);
3332 3333
    }

A
Andrea Bolognani 已提交
3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
    for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
        virGICCapabilityPtr cap;
        bool kernel;
        bool emulated;

        cap = &qemuCaps->gicCapabilities[i];
        kernel = (cap->implementation & VIR_GIC_IMPLEMENTATION_KERNEL);
        emulated = (cap->implementation & VIR_GIC_IMPLEMENTATION_EMULATED);

        virBufferAsprintf(&buf,
                          "<gic version='%d' kernel='%s' emulated='%s'/>\n",
                          cap->version,
                          kernel ? "yes" : "no",
                          emulated ? "yes" : "no");
    }

3350
    virBufferAdjustIndent(&buf, -2);
3351 3352
    virBufferAddLit(&buf, "</qemuCaps>\n");

3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364
    if (virBufferCheckError(&buf) == 0)
        ret = virBufferContentAndReset(&buf);

    return ret;
}


static int
virQEMUCapsSaveCache(virQEMUCapsPtr qemuCaps, const char *filename)
{
    char *xml = NULL;
    int ret = -1;
3365

3366 3367 3368
    xml = virQEMUCapsFormatCache(qemuCaps,
                                 virGetSelfLastChanged(),
                                 LIBVIR_VERSION_NUMBER);
3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432

    if (virFileWriteStr(filename, xml, 0600) < 0) {
        virReportSystemError(errno,
                             _("Failed to save '%s' for '%s'"),
                             filename, qemuCaps->binary);
        goto cleanup;
    }

    VIR_DEBUG("Saved caps '%s' for '%s' with (%lld, %lld)",
              filename, qemuCaps->binary,
              (long long)qemuCaps->ctime,
              (long long)virGetSelfLastChanged());

    ret = 0;
 cleanup:
    VIR_FREE(xml);
    return ret;
}

static int
virQEMUCapsRememberCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
{
    char *capsdir = NULL;
    char *capsfile = NULL;
    int ret = -1;
    char *binaryhash = NULL;

    if (virAsprintf(&capsdir, "%s/capabilities", cacheDir) < 0)
        goto cleanup;

    if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256,
                            qemuCaps->binary,
                            &binaryhash) < 0)
        goto cleanup;

    if (virAsprintf(&capsfile, "%s/%s.xml", capsdir, binaryhash) < 0)
        goto cleanup;

    if (virFileMakePath(capsdir) < 0) {
        virReportSystemError(errno,
                             _("Unable to create directory '%s'"),
                             capsdir);
        goto cleanup;
    }

    if (virQEMUCapsSaveCache(qemuCaps, capsfile) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    VIR_FREE(binaryhash);
    VIR_FREE(capsfile);
    VIR_FREE(capsdir);
    return ret;
}


static void
virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
{
    size_t i;

    virBitmapClearAll(qemuCaps->flags);
    qemuCaps->version = qemuCaps->kvmVersion = 0;
3433
    VIR_FREE(qemuCaps->package);
3434 3435 3436
    qemuCaps->arch = VIR_ARCH_NONE;
    qemuCaps->usedQMP = false;

3437 3438
    virObjectUnref(qemuCaps->cpuDefinitions);
    qemuCaps->cpuDefinitions = NULL;
3439 3440

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
3441 3442
        VIR_FREE(qemuCaps->machineTypes[i].name);
        VIR_FREE(qemuCaps->machineTypes[i].alias);
3443 3444 3445
    }
    VIR_FREE(qemuCaps->machineTypes);
    qemuCaps->nmachineTypes = 0;
A
Andrea Bolognani 已提交
3446 3447 3448

    VIR_FREE(qemuCaps->gicCapabilities);
    qemuCaps->ngicCapabilities = 0;
3449 3450 3451

    virCPUDefFree(qemuCaps->hostCPUModel);
    qemuCaps->hostCPUModel = NULL;
3452 3453 3454 3455
}


static int
3456 3457 3458
virQEMUCapsInitCached(virCapsPtr caps,
                      virQEMUCapsPtr qemuCaps,
                      const char *cacheDir)
3459 3460 3461 3462 3463 3464
{
    char *capsdir = NULL;
    char *capsfile = NULL;
    int ret = -1;
    char *binaryhash = NULL;
    struct stat sb;
3465
    time_t qemuctime = qemuCaps->ctime;
3466
    time_t selfctime;
3467
    unsigned long selfvers;
3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499

    if (virAsprintf(&capsdir, "%s/capabilities", cacheDir) < 0)
        goto cleanup;

    if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256,
                            qemuCaps->binary,
                            &binaryhash) < 0)
        goto cleanup;

    if (virAsprintf(&capsfile, "%s/%s.xml", capsdir, binaryhash) < 0)
        goto cleanup;

    if (virFileMakePath(capsdir) < 0) {
        virReportSystemError(errno,
                             _("Unable to create directory '%s'"),
                             capsdir);
        goto cleanup;
    }

    if (stat(capsfile, &sb) < 0) {
        if (errno == ENOENT) {
            VIR_DEBUG("No cached capabilities '%s' for '%s'",
                      capsfile, qemuCaps->binary);
            ret = 0;
            goto cleanup;
        }
        virReportSystemError(errno,
                             _("Unable to access cache '%s' for '%s'"),
                             capsfile, qemuCaps->binary);
        goto cleanup;
    }

3500
    if (virQEMUCapsLoadCache(caps, qemuCaps, capsfile,
3501
                             &selfctime, &selfvers) < 0) {
3502
        VIR_WARN("Failed to load cached caps from '%s' for '%s': %s",
3503
                 capsfile, qemuCaps->binary, virGetLastErrorMessage());
3504
        virResetLastError();
3505
        goto discard;
3506 3507
    }

3508 3509 3510
    if (!virQEMUCapsIsValid(qemuCaps, qemuctime))
        goto discard;

3511
    /* Discard cache if QEMU binary or libvirtd changed */
3512
    if (selfctime != virGetSelfLastChanged() ||
3513
        selfvers != LIBVIR_VERSION_NUMBER) {
3514 3515 3516
        VIR_DEBUG("Outdated capabilities for '%s': libvirt changed "
                  "(%lld vs %lld, %lu vs %lu)",
                  qemuCaps->binary,
3517 3518
                  (long long)selfctime, (long long)virGetSelfLastChanged(),
                  selfvers, (unsigned long)LIBVIR_VERSION_NUMBER);
3519
        goto discard;
3520 3521 3522 3523 3524 3525 3526 3527
    }

    VIR_DEBUG("Loaded '%s' for '%s' ctime %lld usedQMP=%d",
              capsfile, qemuCaps->binary,
              (long long)qemuCaps->ctime, qemuCaps->usedQMP);

    ret = 1;
 cleanup:
3528
    qemuCaps->ctime = qemuctime;
3529 3530 3531 3532
    VIR_FREE(binaryhash);
    VIR_FREE(capsfile);
    VIR_FREE(capsdir);
    return ret;
3533 3534 3535 3536 3537 3538 3539 3540

 discard:
    VIR_DEBUG("Dropping cached capabilities '%s' for '%s'",
              capsfile, qemuCaps->binary);
    ignore_value(unlink(capsfile));
    virQEMUCapsReset(qemuCaps);
    ret = 0;
    goto cleanup;
3541 3542 3543
}


3544 3545
#define QEMU_SYSTEM_PREFIX "qemu-system-"

3546
static int
3547
virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid, const char *qmperr)
3548
{
3549
    virCommandPtr cmd = NULL;
3550
    bool is_kvm;
3551
    char *help = NULL;
3552 3553
    int ret = -1;
    const char *tmp;
3554

3555
    VIR_DEBUG("qemuCaps=%p", qemuCaps);
3556

3557
    tmp = strstr(qemuCaps->binary, QEMU_SYSTEM_PREFIX);
3558 3559
    if (tmp) {
        tmp += strlen(QEMU_SYSTEM_PREFIX);
3560

3561
        qemuCaps->arch = virQEMUCapsArchFromString(tmp);
3562
    } else {
3563
        qemuCaps->arch = virArchFromHost();
3564 3565
    }

3566
    cmd = virQEMUCapsProbeCommand(qemuCaps->binary, NULL, runUid, runGid);
3567 3568 3569 3570
    virCommandAddArgList(cmd, "-help", NULL);
    virCommandSetOutputBuffer(cmd, &help);

    if (virCommandRun(cmd, NULL) < 0)
3571
        goto cleanup;
3572

3573 3574 3575 3576 3577
    if (virQEMUCapsParseHelpStr(qemuCaps->binary,
                                help, qemuCaps,
                                &qemuCaps->version,
                                &is_kvm,
                                &qemuCaps->kvmVersion,
3578 3579
                                false,
                                qmperr) < 0)
3580
        goto cleanup;
3581

D
Daniel P. Berrange 已提交
3582 3583 3584 3585 3586 3587 3588
    /* x86_64 and i686 support PCI-multibus on all machine types
     * since forever. For other architectures, it has been changing
     * across releases, per machine type, so we can't simply detect
     * it here. Thus the rest of the logic is provided in a separate
     * helper virQEMUCapsHasPCIMultiBus() which keys off the machine
     * stored in virDomainDef and QEMU version number
     */
3589
    if (qemuCaps->arch == VIR_ARCH_X86_64 ||
D
Daniel P. Berrange 已提交
3590
        qemuCaps->arch == VIR_ARCH_I686)
3591
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);
D
Daniel P. Berrange 已提交
3592 3593 3594 3595 3596

    /* -no-acpi is not supported on non-x86
     * even if qemu reports it in -help */
    if (qemuCaps->arch != VIR_ARCH_X86_64 &&
        qemuCaps->arch != VIR_ARCH_I686)
3597
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_NO_ACPI);
3598

3599
    /* virQEMUCapsExtractDeviceStr will only set additional caps if qemu
3600
     * understands the 0.13.0+ notion of "-device driver,".  */
J
Ján Tomko 已提交
3601
    if (strstr(help, "-device driver,?") &&
3602 3603
        virQEMUCapsExtractDeviceStr(qemuCaps->binary,
                                    qemuCaps, runUid, runGid) < 0) {
3604
        goto cleanup;
3605
    }
3606

3607
    if (virQEMUCapsProbeCPUModels(qemuCaps, runUid, runGid) < 0)
3608
        goto cleanup;
3609

3610
    if (virQEMUCapsProbeMachineTypes(qemuCaps, runUid, runGid) < 0)
3611
        goto cleanup;
3612

3613
    ret = 0;
3614
 cleanup:
3615
    virCommandFree(cmd);
3616
    VIR_FREE(help);
3617 3618 3619 3620
    return ret;
}


3621
static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
3622 3623
                                     virDomainObjPtr vm ATTRIBUTE_UNUSED,
                                     void *opaque ATTRIBUTE_UNUSED)
3624 3625 3626 3627
{
}

static qemuMonitorCallbacks callbacks = {
3628 3629
    .eofNotify = virQEMUCapsMonitorNotify,
    .errorNotify = virQEMUCapsMonitorNotify,
3630 3631 3632 3633 3634 3635 3636
};


/* Capabilities that we assume are always enabled
 * for QEMU >= 1.2.0
 */
static void
3637
virQEMUCapsInitQMPBasic(virQEMUCapsPtr qemuCaps)
3638
{
3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_MEM_PATH);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_MONITOR_JSON);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_SDL);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_RTC);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOST_NET);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NODEFCONFIG);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_BOOT_MENU);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NAME_PROCESS);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_VGA_NONE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_AIO);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_READONLY);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_WAKEUP);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX);
O
Olivia Yin 已提交
3666
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB);
J
Ján Tomko 已提交
3667
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION);
3668 3669
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE);
3670
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY);
3671
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN);
P
Paolo Bonzini 已提交
3672
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DISPLAY);
3673 3674
}

3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693
/* Capabilities that are architecture depending
 * initialized for QEMU.
 */
static int
virQEMUCapsInitArchQMPBasic(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
{
    char *archstr = NULL;
    int ret = -1;

    if (!(archstr = qemuMonitorGetTargetArch(mon)))
        return -1;

    if ((qemuCaps->arch = virQEMUCapsArchFromString(archstr)) == VIR_ARCH_NONE) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unknown QEMU arch %s"), archstr);
        goto cleanup;
    }

D
Daniel P. Berrange 已提交
3694 3695 3696 3697 3698 3699 3700 3701
    /* x86_64 and i686 support PCI-multibus on all machine types
     * since forever. For other architectures, it has been changing
     * across releases, per machine type, so we can't simply detect
     * it here. Thus the rest of the logic is provided in a separate
     * helper virQEMUCapsHasPCIMultiBus() which keys off the machine
     * stored in virDomainDef and QEMU version number
     *
     * ACPI/HPET/KVM PIT are also x86 specific
3702 3703 3704 3705 3706
     */
    if (qemuCaps->arch == VIR_ARCH_X86_64 ||
        qemuCaps->arch == VIR_ARCH_I686) {
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI);
J
Ján Tomko 已提交
3707
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_HPET);
3708 3709 3710 3711 3712
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
    }

    ret = 0;

3713
 cleanup:
3714 3715 3716
    VIR_FREE(archstr);
    return ret;
}
3717

3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757

/**
 * virQEMUCapsQMPSchemaObjectGetType:
 * @field: name of the object containing the requested type
 * @name: name of the requested type
 * @namefield: name of the object property holding @name
 *
 * Helper that selects the type of a QMP schema object member or it's variant
 * member. Returns the type string on success or NULL on error.
 */
static const char *
virQEMUCapsQMPSchemaObjectGetType(const char *field,
                                  const char *name,
                                  const char *namefield,
                                  virJSONValuePtr elem)
{
    virJSONValuePtr arr;
    virJSONValuePtr cur;
    const char *curname;
    const char *type;
    size_t i;

    if (!(arr = virJSONValueObjectGetArray(elem, field)))
        return NULL;

    for (i = 0; i < virJSONValueArraySize(arr); i++) {
        if (!(cur = virJSONValueArrayGet(arr, i)) ||
            !(curname = virJSONValueObjectGetString(cur, namefield)) ||
            !(type = virJSONValueObjectGetString(cur, "type")))
            continue;

        if (STREQ(name, curname))
            return type;
    }

    return NULL;
}


static virJSONValuePtr
3758
virQEMUCapsQMPSchemaTraverse(const char *baseName,
3759 3760 3761 3762 3763 3764 3765
                             char **query,
                             virHashTablePtr schema)
{
    virJSONValuePtr base;
    const char *metatype;

    do {
3766
        if (!(base = virHashLookup(schema, baseName)))
3767 3768 3769 3770 3771 3772 3773 3774 3775 3776
            return NULL;

        if (!*query)
            return base;

        if (!(metatype = virJSONValueObjectGetString(base, "meta-type")))
            return NULL;

        /* flatten arrays by default */
        if (STREQ(metatype, "array")) {
3777
            if (!(baseName = virJSONValueObjectGetString(base, "element-type")))
3778 3779 3780 3781 3782
                return NULL;

            continue;
        } else if (STREQ(metatype, "object")) {
            if (**query == '+')
3783
                baseName = virQEMUCapsQMPSchemaObjectGetType("variants",
3784 3785 3786
                                                             *query + 1,
                                                             "case", base);
            else
3787
                baseName = virQEMUCapsQMPSchemaObjectGetType("members",
3788 3789 3790
                                                             *query,
                                                             "name", base);

3791
            if (!baseName)
3792 3793 3794
                return NULL;
        } else if (STREQ(metatype, "command") ||
                   STREQ(metatype, "event")) {
3795
            if (!(baseName = virJSONValueObjectGetString(base, *query)))
3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851
                return NULL;
        } else {
            /* alternates, basic types and enums can't be entered */
            return NULL;
        }

        query++;
    } while (*query);

    return base;
}


/**
 * virQEMUCapsQMPSchemaGetByPath:
 * @query: string specifying the required data type (see below)
 * @schema: hash table containing the schema data
 * @entry: filled with the located schema object requested by @query
 *
 * Retrieves the requested schema entry specified by @query to @entry. The
 * @query parameter has the following syntax which is very closely tied to the
 * qemu schema syntax entries separated by slashes with a few special characters:
 *
 * "command_or_event/attribute/subattribute/+variant_discriminator/subattribute"
 *
 * command_or_event: name of the event or attribute to introspect
 * attribute: selects whether arguments or return type should be introspected
 *            ("arg-type" or "ret-type" for commands, "arg-type" for events)
 * subattribute: specifies member name of object types
 * +variant_discriminator: In the case of unionized objects, select a
 *                         specific case to introspect.
 *
 * Array types are automatically flattened to the singular type. Alternate
 * types are currently not supported.
 *
 * The above types can be chained arbitrarily using slashes to construct any
 * path into the schema tree.
 *
 * Returns 0 on success (including if the requested schema was not found) and
 * fills @entry appropriately. On failure returns -1 and sets an appropriate
 * error message.
 */
static int
virQEMUCapsQMPSchemaGetByPath(const char *query,
                              virHashTablePtr schema,
                              virJSONValuePtr *entry)
{
    char **elems = NULL;

    *entry = NULL;

    if (!(elems = virStringSplit(query, "/", 0)))
        return -1;

    if (!*elems) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed query string"));
3852
        virStringListFree(elems);
3853 3854 3855 3856 3857
        return -1;
    }

    *entry = virQEMUCapsQMPSchemaTraverse(*elems, elems + 1, schema);

3858
    virStringListFree(elems);
3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898
    return 0;
}


static bool
virQEMUCapsQMPSchemaQueryPath(const char *query,
                              virHashTablePtr schema)
{
    virJSONValuePtr entry;

    if (virQEMUCapsQMPSchemaGetByPath(query, schema, &entry))
        return false;

    return !!entry;
}


static int
virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCapsPtr qemuCaps,
                                      qemuMonitorPtr mon)
{
    struct virQEMUCapsStringFlags *entry;
    virHashTablePtr schema;
    size_t i;

    if (!(schema = qemuMonitorQueryQMPSchema(mon)))
        return -1;

    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsQMPSchemaQueries); i++) {
        entry = virQEMUCapsQMPSchemaQueries + i;

        if (virQEMUCapsQMPSchemaQueryPath(entry->value, schema))
            virQEMUCapsSet(qemuCaps, entry->flag);
    }

    virHashFree(schema);
    return 0;
}


3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910
int
virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
                          qemuMonitorPtr mon)
{
    int ret = -1;
    int major, minor, micro;
    char *package = NULL;

    /* @mon is supposed to be locked by callee */

    if (qemuMonitorSetCapabilities(mon) < 0) {
        VIR_DEBUG("Failed to set monitor capabilities %s",
3911
                  virGetLastErrorMessage());
3912 3913 3914 3915 3916 3917 3918 3919
        ret = 0;
        goto cleanup;
    }

    if (qemuMonitorGetVersion(mon,
                              &major, &minor, &micro,
                              &package) < 0) {
        VIR_DEBUG("Failed to query monitor version %s",
3920
                  virGetLastErrorMessage());
3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934
        ret = 0;
        goto cleanup;
    }

    VIR_DEBUG("Got version %d.%d.%d (%s)",
              major, minor, micro, NULLSTR(package));

    if (major < 1 || (major == 1 && minor < 2)) {
        VIR_DEBUG("Not new enough for QMP capabilities detection");
        ret = 0;
        goto cleanup;
    }

    qemuCaps->version = major * 1000000 + minor * 1000 + micro;
3935
    qemuCaps->package = package;
3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950
    qemuCaps->usedQMP = true;

    virQEMUCapsInitQMPBasic(qemuCaps);

    if (virQEMUCapsInitArchQMPBasic(qemuCaps, mon) < 0)
        goto cleanup;

    /* USB option is supported v1.3.0 onwards */
    if (qemuCaps->version >= 1003000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT);

    /* WebSockets were introduced between 1.3.0 and 1.3.1 */
    if (qemuCaps->version >= 1003001)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET);

3951 3952 3953 3954 3955 3956
    /* -chardev spiceport is supported from 1.4.0, but usable through
     * qapi only since 1.5.0, however, it still cannot be queried
     * for as a capability */
    if (qemuCaps->version >= 1005000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEPORT);

3957 3958 3959
    if (qemuCaps->version >= 1006000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);

3960 3961 3962 3963
    /* vmport option is supported v2.2.0 onwards */
    if (qemuCaps->version >= 2002000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_VMPORT_OPT);

3964 3965 3966 3967 3968 3969
    /* -cpu ...,aarch64=off supported in v2.3.0 and onwards. But it
       isn't detectable via qmp at this point */
    if (qemuCaps->arch == VIR_ARCH_AARCH64 &&
        qemuCaps->version >= 2003000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_AARCH64_OFF);

3970 3971 3972
    /* vhost-user supports multi-queue from v2.4.0 onwards,
     * but there is no way to query for that capability */
    if (qemuCaps->version >= 2004000)
J
Ján Tomko 已提交
3973
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE);
3974

M
Michal Privoznik 已提交
3975 3976 3977 3978
    /* smm option is supported from v2.4.0 */
    if (qemuCaps->version >= 2004000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT);

3979 3980 3981 3982
    /* Since 2.4.50 ARM virt machine supports gic-version option */
    if (qemuCaps->version >= 2004050)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACH_VIRT_GIC_VERSION);

3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998
    if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPObjects(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPMachineTypes(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPTPM(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPCommandLine(qemuCaps, mon) < 0)
        goto cleanup;
3999 4000
    if (virQEMUCapsProbeQMPMigrationCapabilities(qemuCaps, mon) < 0)
        goto cleanup;
4001 4002 4003
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_QMP_SCHEMA) &&
        virQEMUCapsProbeQMPSchemaCapabilities(qemuCaps, mon) < 0)
        goto cleanup;
4004

4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015
    /* 'intel-iommu' shows up as a device since 2.2.0, but can
     * not be used with -device until 2.7.0. Before that it
     * requires -machine iommu=on. So we must clear the device
     * capability we detected on older QEMUs
     */
    if (qemuCaps->version < 2007000 &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU)) {
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU);
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU);
    }

A
Andrea Bolognani 已提交
4016 4017 4018 4019 4020 4021
    /* GIC capabilities, eg. available GIC versions */
    if ((qemuCaps->arch == VIR_ARCH_AARCH64 ||
         qemuCaps->arch == VIR_ARCH_ARMV7L) &&
        virQEMUCapsProbeQMPGICCapabilities(qemuCaps, mon) < 0)
        goto cleanup;

4022
    ret = 0;
4023
 cleanup:
4024 4025 4026
    return ret;
}

4027
static int
4028 4029 4030
virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
                   const char *libDir,
                   uid_t runUid,
4031 4032
                   gid_t runGid,
                   char **qmperr)
4033 4034 4035 4036 4037 4038 4039 4040
{
    int ret = -1;
    virCommandPtr cmd = NULL;
    qemuMonitorPtr mon = NULL;
    int status = 0;
    virDomainChrSourceDef config;
    char *monarg = NULL;
    char *monpath = NULL;
4041
    char *pidfile = NULL;
4042
    pid_t pid = 0;
4043 4044
    virDomainObjPtr vm = NULL;
    virDomainXMLOptionPtr xmlopt = NULL;
4045

4046 4047 4048
    /* the ".sock" sufix is important to avoid a possible clash with a qemu
     * domain called "capabilities"
     */
4049
    if (virAsprintf(&monpath, "%s/%s", libDir, "capabilities.monitor.sock") < 0)
4050
        goto cleanup;
4051
    if (virAsprintf(&monarg, "unix:%s,server,nowait", monpath) < 0)
4052 4053
        goto cleanup;

4054 4055
    /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
     * with a qemu domain called "capabilities"
4056 4057 4058
     * Normally we'd use runDir for pid files, but because we're using
     * -daemonize we need QEMU to be allowed to create them, rather
     * than libvirtd. So we're using libDir which QEMU can write to
4059
     */
4060
    if (virAsprintf(&pidfile, "%s/%s", libDir, "capabilities.pidfile") < 0)
4061 4062
        goto cleanup;

4063 4064 4065 4066 4067
    memset(&config, 0, sizeof(config));
    config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
    config.data.nix.path = monpath;
    config.data.nix.listen = false;

4068 4069
    virPidFileForceCleanupPath(pidfile);

4070
    VIR_DEBUG("Try to get caps via QMP qemuCaps=%p", qemuCaps);
4071

4072 4073 4074 4075 4076 4077 4078
    /*
     * We explicitly need to use -daemonize here, rather than
     * virCommandDaemonize, because we need to synchronize
     * with QEMU creating its monitor socket API. Using
     * daemonize guarantees control won't return to libvirt
     * until the socket is present.
     */
4079
    cmd = virCommandNewArgList(qemuCaps->binary,
4080 4081 4082 4083 4084 4085
                               "-S",
                               "-no-user-config",
                               "-nodefaults",
                               "-nographic",
                               "-M", "none",
                               "-qmp", monarg,
4086 4087
                               "-pidfile", pidfile,
                               "-daemonize",
4088 4089 4090
                               NULL);
    virCommandAddEnvPassCommon(cmd);
    virCommandClearCaps(cmd);
4091 4092
    virCommandSetGID(cmd, runGid);
    virCommandSetUID(cmd, runUid);
4093

4094 4095
    virCommandSetErrorBuffer(cmd, qmperr);

4096
    /* Log, but otherwise ignore, non-zero status.  */
4097 4098 4099 4100 4101
    if (virCommandRun(cmd, &status) < 0)
        goto cleanup;

    if (status != 0) {
        ret = 0;
4102 4103
        VIR_DEBUG("QEMU %s exited with status %d: %s",
                  qemuCaps->binary, status, *qmperr);
4104 4105 4106
        goto cleanup;
    }

4107 4108 4109 4110 4111 4112
    if (virPidFileReadPath(pidfile, &pid) < 0) {
        VIR_DEBUG("Failed to read pidfile %s", pidfile);
        ret = 0;
        goto cleanup;
    }

4113 4114 4115 4116 4117
    if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL)) ||
        !(vm = virDomainObjNew(xmlopt)))
        goto cleanup;

    vm->pid = pid;
4118

4119
    if (!(mon = qemuMonitorOpen(vm, &config, true, &callbacks, NULL))) {
4120
        ret = 0;
4121
        goto cleanup;
4122
    }
4123

4124
    virObjectLock(mon);
4125

4126
    if (virQEMUCapsInitQMPMonitor(qemuCaps, mon) < 0)
4127
        goto cleanup;
4128 4129 4130

    ret = 0;

4131
 cleanup:
4132
    if (mon)
4133
        virObjectUnlock(mon);
4134 4135
    qemuMonitorClose(mon);
    virCommandAbort(cmd);
4136
    virCommandFree(cmd);
4137
    VIR_FREE(monarg);
4138 4139
    if (monpath)
        ignore_value(unlink(monpath));
4140
    VIR_FREE(monpath);
M
Michal Privoznik 已提交
4141
    virDomainObjEndAPI(&vm);
4142
    virObjectUnref(xmlopt);
4143

4144
    if (pid != 0) {
4145 4146
        char ebuf[1024];

4147 4148 4149 4150 4151
        VIR_DEBUG("Killing QMP caps process %lld", (long long) pid);
        if (virProcessKill(pid, SIGKILL) < 0 && errno != ESRCH)
            VIR_ERROR(_("Failed to kill process %lld: %s"),
                      (long long) pid,
                      virStrerror(errno, ebuf, sizeof(ebuf)));
4152 4153

        VIR_FREE(*qmperr);
4154 4155
    }
    if (pidfile) {
4156 4157 4158
        unlink(pidfile);
        VIR_FREE(pidfile);
    }
4159 4160 4161 4162
    return ret;
}


4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173
#define MESSAGE_ID_CAPS_PROBE_FAILURE "8ae2f3fb-2dbe-498e-8fbd-012d40afa361"

static void
virQEMUCapsLogProbeFailure(const char *binary)
{
    virLogMetadata meta[] = {
        { .key = "MESSAGE_ID", .s = MESSAGE_ID_CAPS_PROBE_FAILURE, .iv = 0 },
        { .key = "LIBVIRT_QEMU_BINARY", .s = binary, .iv = 0 },
        { .key = NULL },
    };

4174
    virLogMessage(&virLogSelf,
4175 4176 4177 4178
                  VIR_LOG_WARN,
                  __FILE__, __LINE__, __func__,
                  meta,
                  _("Failed to probe capabilities for %s: %s"),
4179
                  binary, virGetLastErrorMessage());
4180 4181 4182
}


4183
virQEMUCapsPtr
4184
virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
4185
                                const char *binary,
4186 4187 4188 4189 4190
                                const char *libDir,
                                const char *cacheDir,
                                uid_t runUid,
                                gid_t runGid,
                                bool qmpOnly)
4191
{
4192
    virQEMUCapsPtr qemuCaps;
4193 4194
    struct stat sb;
    int rv;
4195
    char *qmperr = NULL;
4196

4197 4198 4199
    if (!(qemuCaps = virQEMUCapsNew()))
        goto error;

4200 4201
    if (VIR_STRDUP(qemuCaps->binary, binary) < 0)
        goto error;
4202 4203 4204 4205 4206 4207 4208 4209

    /* We would also want to check faccessat if we cared about ACLs,
     * but we don't.  */
    if (stat(binary, &sb) < 0) {
        virReportSystemError(errno, _("Cannot check QEMU binary %s"),
                             binary);
        goto error;
    }
4210
    qemuCaps->ctime = sb.st_ctime;
4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221

    /* Make sure the binary we are about to try exec'ing exists.
     * Technically we could catch the exec() failure, but that's
     * in a sub-process so it's hard to feed back a useful error.
     */
    if (!virFileIsExecutable(binary)) {
        virReportSystemError(errno, _("QEMU binary %s is not executable"),
                             binary);
        goto error;
    }

4222 4223
    if (!cacheDir)
        rv = 0;
4224
    else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir)) < 0)
4225 4226
        goto error;

4227
    if (rv == 0) {
4228
        if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid, &qmperr) < 0) {
4229 4230 4231 4232
            virQEMUCapsLogProbeFailure(binary);
            goto error;
        }

4233 4234 4235 4236 4237 4238 4239 4240
        if (qmpOnly && !qemuCaps->usedQMP) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Failed to probe QEMU binary with QMP: %s"),
                           qmperr ? qmperr : _("unknown error"));
            virQEMUCapsLogProbeFailure(binary);
            goto error;
        }

4241
        if (!qemuCaps->usedQMP &&
4242
            virQEMUCapsInitHelp(qemuCaps, runUid, runGid, qmperr) < 0) {
4243 4244 4245 4246
            virQEMUCapsLogProbeFailure(binary);
            goto error;
        }

4247 4248
        if (cacheDir &&
            virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0)
4249
            goto error;
4250

J
Jiri Denemark 已提交
4251
        virQEMUCapsInitHostCPUModel(qemuCaps, caps);
4252
    }
4253

4254
 cleanup:
4255
    VIR_FREE(qmperr);
4256
    return qemuCaps;
4257

4258
 error:
4259 4260
    virObjectUnref(qemuCaps);
    qemuCaps = NULL;
4261
    goto cleanup;
4262 4263
}

4264
static virQEMUCapsPtr
4265 4266
virQEMUCapsNewForBinary(virCapsPtr caps,
                        const char *binary,
4267 4268 4269 4270 4271
                        const char *libDir,
                        const char *cacheDir,
                        uid_t runUid,
                        gid_t runGid)
{
4272
    return virQEMUCapsNewForBinaryInternal(caps, binary, libDir, cacheDir,
4273 4274 4275
                                           runUid, runGid, false);
}

4276

4277 4278
bool
virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps,
J
Jiri Denemark 已提交
4279
                   time_t qemuctime)
4280
{
4281
    if (!qemuCaps->binary)
4282 4283
        return true;

J
Jiri Denemark 已提交
4284
    if (!qemuctime) {
4285 4286 4287 4288 4289 4290 4291 4292 4293
        struct stat sb;

        if (stat(qemuCaps->binary, &sb) < 0) {
            char ebuf[1024];
            VIR_DEBUG("Failed to stat QEMU binary '%s': %s",
                      qemuCaps->binary,
                      virStrerror(errno, ebuf, sizeof(ebuf)));
            return false;
        }
J
Jiri Denemark 已提交
4294
        qemuctime = sb.st_ctime;
4295 4296
    }

J
Jiri Denemark 已提交
4297
    if (qemuctime != qemuCaps->ctime) {
4298 4299 4300
        VIR_DEBUG("Outdated capabilities for '%s': QEMU binary changed "
                  "(%lld vs %lld)",
                  qemuCaps->binary,
J
Jiri Denemark 已提交
4301
                  (long long) qemuctime, (long long) qemuCaps->ctime);
4302
        return false;
4303
    }
4304

4305
    return true;
4306
}
4307 4308


4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341
struct virQEMUCapsMachineTypeFilter {
    const char *machineType;
    virQEMUCapsFlags *flags;
    size_t nflags;
};

static const struct virQEMUCapsMachineTypeFilter virQEMUCapsMachineFilter[] = {
    /* { "blah", virQEMUCapsMachineBLAHFilter,
         ARRAY_CARDINALITY(virQEMUCapsMachineBLAHFilter) }, */
    { "", NULL, 0 },
};


void
virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
                               const char *machineType)
{
    size_t i;

    if (!machineType)
        return;

    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsMachineFilter); i++) {
        const struct virQEMUCapsMachineTypeFilter *filter = &virQEMUCapsMachineFilter[i];
        size_t j;

        if (STRNEQ(filter->machineType, machineType))
            continue;

        for (j = 0; j < filter->nflags; j++)
            virQEMUCapsClear(qemuCaps, filter->flags[j]);
    }

4342 4343
    if (!virQEMUCapsGetMachineHotplugCpus(qemuCaps, machineType))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS);
4344 4345 4346
}


4347 4348
virQEMUCapsCachePtr
virQEMUCapsCacheNew(const char *libDir,
4349
                    const char *cacheDir,
4350 4351
                    uid_t runUid,
                    gid_t runGid)
4352
{
4353
    virQEMUCapsCachePtr cache;
4354

4355
    if (VIR_ALLOC(cache) < 0)
4356 4357 4358 4359 4360 4361 4362 4363 4364
        return NULL;

    if (virMutexInit(&cache->lock) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Unable to initialize mutex"));
        VIR_FREE(cache);
        return NULL;
    }

E
Eric Blake 已提交
4365
    if (!(cache->binaries = virHashCreate(10, virObjectFreeHashData)))
4366
        goto error;
4367
    if (VIR_STRDUP(cache->libDir, libDir) < 0)
4368
        goto error;
4369 4370
    if (VIR_STRDUP(cache->cacheDir, cacheDir) < 0)
        goto error;
4371

4372 4373 4374
    cache->runUid = runUid;
    cache->runGid = runGid;

4375 4376
    return cache;

4377
 error:
4378
    virQEMUCapsCacheFree(cache);
4379 4380 4381
    return NULL;
}

4382
const char *qemuTestCapsName;
4383

4384
virQEMUCapsPtr
4385 4386 4387
virQEMUCapsCacheLookup(virCapsPtr caps,
                       virQEMUCapsCachePtr cache,
                       const char *binary)
4388
{
4389
    virQEMUCapsPtr ret = NULL;
4390 4391 4392 4393 4394

    /* This is used only by test suite!!! */
    if (qemuTestCapsName)
        binary = qemuTestCapsName;

4395 4396 4397
    virMutexLock(&cache->lock);
    ret = virHashLookup(cache->binaries, binary);
    if (ret &&
4398
        !virQEMUCapsIsValid(ret, 0)) {
4399 4400 4401 4402 4403 4404 4405 4406
        VIR_DEBUG("Cached capabilities %p no longer valid for %s",
                  ret, binary);
        virHashRemoveEntry(cache->binaries, binary);
        ret = NULL;
    }
    if (!ret) {
        VIR_DEBUG("Creating capabilities for %s",
                  binary);
4407
        ret = virQEMUCapsNewForBinary(caps, binary, cache->libDir,
4408
                                      cache->cacheDir,
4409
                                      cache->runUid, cache->runGid);
4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425
        if (ret) {
            VIR_DEBUG("Caching capabilities %p for %s",
                      ret, binary);
            if (virHashAddEntry(cache->binaries, binary, ret) < 0) {
                virObjectUnref(ret);
                ret = NULL;
            }
        }
    }
    VIR_DEBUG("Returning caps %p for %s", ret, binary);
    virObjectRef(ret);
    virMutexUnlock(&cache->lock);
    return ret;
}


4426
virQEMUCapsPtr
4427 4428
virQEMUCapsCacheLookupCopy(virCapsPtr caps,
                           virQEMUCapsCachePtr cache,
4429
                           const char *binary,
4430
                           const char *machineType)
4431
{
4432
    virQEMUCapsPtr qemuCaps = virQEMUCapsCacheLookup(caps, cache, binary);
4433
    virQEMUCapsPtr ret;
4434

4435
    if (!qemuCaps)
4436 4437
        return NULL;

4438 4439
    ret = virQEMUCapsNewCopy(qemuCaps);
    virObjectUnref(qemuCaps);
4440
    virQEMUCapsFilterByMachineType(ret, machineType);
4441 4442 4443 4444
    return ret;
}


4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461
static int
virQEMUCapsCompareArch(const void *payload,
                       const void *name ATTRIBUTE_UNUSED,
                       const void *opaque)
{
    struct virQEMUCapsSearchData *data = (struct virQEMUCapsSearchData *) opaque;
    const virQEMUCaps *qemuCaps = payload;

    return qemuCaps->arch == data->arch;
}


virQEMUCapsPtr
virQEMUCapsCacheLookupByArch(virQEMUCapsCachePtr cache,
                             virArch arch)
{
    virQEMUCapsPtr ret = NULL;
4462
    virArch target;
4463 4464 4465 4466
    struct virQEMUCapsSearchData data = { .arch = arch };

    virMutexLock(&cache->lock);
    ret = virHashSearch(cache->binaries, virQEMUCapsCompareArch, &data);
4467 4468 4469 4470 4471 4472 4473 4474 4475
    if (!ret) {
        /* If the first attempt at finding capabilities has failed, try
         * again using the QEMU target as lookup key instead */
        target = virQEMUCapsFindTarget(virArchFromHost(), data.arch);
        if (target != data.arch) {
            data.arch = target;
            ret = virHashSearch(cache->binaries, virQEMUCapsCompareArch, &data);
        }
    }
4476 4477 4478
    virObjectRef(ret);
    virMutexUnlock(&cache->lock);

4479 4480
    VIR_DEBUG("Returning caps %p for arch %s", ret, virArchToString(arch));

4481 4482 4483 4484
    return ret;
}


4485
void
4486
virQEMUCapsCacheFree(virQEMUCapsCachePtr cache)
4487 4488 4489 4490
{
    if (!cache)
        return;

4491
    VIR_FREE(cache->libDir);
4492
    VIR_FREE(cache->cacheDir);
4493 4494 4495 4496
    virHashFree(cache->binaries);
    virMutexDestroy(&cache->lock);
    VIR_FREE(cache);
}
4497

4498 4499

bool
4500
virQEMUCapsSupportsChardev(const virDomainDef *def,
4501
                           virQEMUCapsPtr qemuCaps,
4502
                           virDomainChrDefPtr chr)
4503
{
J
Ján Tomko 已提交
4504
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV))
4505 4506
        return false;

4507
    if ((def->os.arch == VIR_ARCH_PPC) || ARCH_IS_PPC64(def->os.arch)) {
4508 4509 4510 4511 4512
        /* only pseries need -device spapr-vty with -chardev */
        return (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
                chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO);
    }

4513
    if ((def->os.arch != VIR_ARCH_ARMV7L) && (def->os.arch != VIR_ARCH_AARCH64))
4514
        return true;
4515

4516 4517 4518 4519 4520 4521
    /* This may not be true for all ARM machine types, but at least
     * the only supported non-virtio serial devices of vexpress and versatile
     * don't have the -chardev property wired up. */
    return (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO ||
            (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
             chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO));
4522
}
4523 4524


4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537
bool
virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
                          const virDomainDef *def)
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_VMPORT_OPT))
        return false;

    return qemuDomainMachineIsI440FX(def) ||
        qemuDomainMachineIsQ35(def) ||
        STREQ(def->os.machine, "isapc");
}


M
Michal Privoznik 已提交
4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548
bool
virQEMUCapsSupportsSMM(virQEMUCapsPtr qemuCaps,
                       const virDomainDef *def)
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT))
        return false;

    return qemuDomainMachineIsQ35(def);
}


4549 4550 4551 4552 4553 4554 4555
bool
virQEMUCapsIsMachineSupported(virQEMUCapsPtr qemuCaps,
                              const char *canonical_machine)
{
    size_t i;

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
4556
        if (STREQ(canonical_machine, qemuCaps->machineTypes[i].name))
4557 4558 4559 4560
            return true;
    }
    return false;
}
4561 4562 4563 4564 4565 4566 4567


const char *
virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
{
    if (!qemuCaps->nmachineTypes)
        return NULL;
4568
    return qemuCaps->machineTypes[0].name;
4569
}
4570 4571


4572
static int
4573
virQEMUCapsFillDomainLoaderCaps(virDomainCapsLoaderPtr capsLoader,
4574 4575
                                virFirmwarePtr *firmwares,
                                size_t nfirmwares)
4576
{
4577 4578
    size_t i;

4579
    capsLoader->supported = true;
4580

4581
    if (VIR_ALLOC_N(capsLoader->values.values, nfirmwares) < 0)
4582 4583
        return -1;

4584 4585
    for (i = 0; i < nfirmwares; i++) {
        const char *filename = firmwares[i]->name;
4586 4587 4588 4589 4590 4591

        if (!virFileExists(filename)) {
            VIR_DEBUG("loader filename=%s does not exist", filename);
            continue;
        }

4592
        if (VIR_STRDUP(capsLoader->values.values[capsLoader->values.nvalues],
4593 4594
                       filename) < 0)
            return -1;
4595
        capsLoader->values.nvalues++;
4596 4597
    }

4598
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
4599 4600
                             VIR_DOMAIN_LOADER_TYPE_ROM);

4601 4602
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
                             VIR_DOMAIN_LOADER_TYPE_PFLASH);
4603 4604


4605 4606 4607
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->readonly,
                             VIR_TRISTATE_BOOL_YES,
                             VIR_TRISTATE_BOOL_NO);
4608
    return 0;
4609 4610 4611
}


4612
static int
4613
virQEMUCapsFillDomainOSCaps(virDomainCapsOSPtr os,
4614 4615
                            virFirmwarePtr *firmwares,
                            size_t nfirmwares)
4616
{
4617
    virDomainCapsLoaderPtr capsLoader = &os->loader;
4618

4619
    os->supported = true;
4620
    if (virQEMUCapsFillDomainLoaderCaps(capsLoader, firmwares, nfirmwares) < 0)
4621 4622
        return -1;
    return 0;
4623 4624 4625
}


4626 4627 4628 4629 4630
static int
virQEMUCapsFillDomainCPUCaps(virCapsPtr caps,
                             virQEMUCapsPtr qemuCaps,
                             virDomainCapsPtr domCaps)
{
4631 4632
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
                                      VIR_CPU_MODE_HOST_PASSTHROUGH))
4633 4634
        domCaps->cpu.hostPassthrough = true;

4635 4636 4637 4638 4639 4640 4641 4642
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
                                      VIR_CPU_MODE_HOST_MODEL))
        domCaps->cpu.hostModel = virCPUDefCopy(qemuCaps->hostCPUModel);

    if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
                                      VIR_CPU_MODE_CUSTOM)) {
        virDomainCapsCPUModelsPtr filtered = NULL;
        char **models = NULL;
4643

J
Jiri Denemark 已提交
4644
        if (virCPUGetModels(domCaps->arch, &models) >= 0) {
4645 4646
            filtered = virDomainCapsCPUModelsFilter(qemuCaps->cpuDefinitions,
                                                    (const char **) models);
4647
            virStringListFree(models);
4648 4649
        }
        domCaps->cpu.custom = filtered;
4650
    }
4651 4652 4653 4654 4655

    return 0;
}


4656
static int
4657
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
4658
                                    const char *machine,
4659 4660
                                    virDomainCapsDeviceDiskPtr disk)
{
4661
    disk->supported = true;
4662 4663 4664
    /* QEMU supports all of these */
    VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice,
                             VIR_DOMAIN_DISK_DEVICE_DISK,
4665 4666
                             VIR_DOMAIN_DISK_DEVICE_CDROM,
                             VIR_DOMAIN_DISK_DEVICE_LUN);
4667 4668

    /* PowerPC pseries based VMs do not support floppy device */
4669 4670
    if (!ARCH_IS_PPC64(qemuCaps->arch) ||
        (STRNEQ(machine, "pseries") && !STRPREFIX(machine, "pseries-")))
4671
        VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice, VIR_DOMAIN_DISK_DEVICE_FLOPPY);
4672 4673 4674 4675 4676 4677 4678

    VIR_DOMAIN_CAPS_ENUM_SET(disk->bus,
                             VIR_DOMAIN_DISK_BUS_IDE,
                             VIR_DOMAIN_DISK_BUS_SCSI,
                             VIR_DOMAIN_DISK_BUS_VIRTIO,
                             /* VIR_DOMAIN_DISK_BUS_SD */);

4679
    /* PowerPC pseries based VMs do not support floppy device */
4680 4681
    if (!ARCH_IS_PPC64(qemuCaps->arch) ||
        (STRNEQ(machine, "pseries") && !STRPREFIX(machine, "pseries-")))
4682 4683
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_FDC);

4684 4685
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE))
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_USB);
4686
    return 0;
4687 4688 4689
}


4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706
static int
virQEMUCapsFillDomainDeviceGraphicsCaps(virQEMUCapsPtr qemuCaps,
                                        virDomainCapsDeviceGraphicsPtr dev)
{
    dev->supported = true;

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_SDL);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_VNC);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_SPICE);

    return 0;
}


4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718
static int
virQEMUCapsFillDomainDeviceVideoCaps(virQEMUCapsPtr qemuCaps,
                                     virDomainCapsDeviceVideoPtr dev)
{
    dev->supported = true;

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_VGA);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_CIRRUS);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_VMVGA);
4719
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL))
4720 4721 4722 4723 4724 4725 4726 4727
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_QXL);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_VIRTIO);

    return 0;
}


4728
static int
4729 4730 4731 4732 4733 4734
virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
                                       virDomainCapsDeviceHostdevPtr hostdev)
{
    bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();

4735
    hostdev->supported = true;
4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748
    /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */
    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->mode,
                             VIR_DOMAIN_HOSTDEV_MODE_SUBSYS);

    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->startupPolicy,
                             VIR_DOMAIN_STARTUP_POLICY_DEFAULT,
                             VIR_DOMAIN_STARTUP_POLICY_MANDATORY,
                             VIR_DOMAIN_STARTUP_POLICY_REQUISITE,
                             VIR_DOMAIN_STARTUP_POLICY_OPTIONAL);

    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB,
                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI);
J
Ján Tomko 已提交
4749
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC))
4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
                                 VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI);

    /* No virDomainHostdevCapsType for QEMU */
    virDomainCapsEnumClear(&hostdev->capsType);

    virDomainCapsEnumClear(&hostdev->pciBackend);
    if (supportsPassthroughVFIO &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO);
    }

J
Ján Tomko 已提交
4764
    if (supportsPassthroughKVM) {
4765 4766 4767 4768
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM);
    }
4769
    return 0;
4770 4771 4772
}


4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810
/**
 * virQEMUCapsSupportsGICVersion:
 * @qemuCaps: QEMU capabilities
 * @virtType: domain type
 * @version: GIC version
 *
 * Checks the QEMU binary with capabilities @qemuCaps supports a specific
 * GIC version for a domain of type @virtType.
 *
 * Returns: true if the binary supports the requested GIC version, false
 *          otherwise
 */
bool
virQEMUCapsSupportsGICVersion(virQEMUCapsPtr qemuCaps,
                              virDomainVirtType virtType,
                              virGICVersion version)
{
    size_t i;

    for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
        virGICCapabilityPtr cap = &(qemuCaps->gicCapabilities[i]);

        if (cap->version != version)
            continue;

        if (virtType == VIR_DOMAIN_VIRT_KVM &&
            cap->implementation & VIR_GIC_IMPLEMENTATION_KERNEL)
            return true;

        if (virtType == VIR_DOMAIN_VIRT_QEMU &&
            cap->implementation & VIR_GIC_IMPLEMENTATION_EMULATED)
            return true;
    }

    return false;
}


4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834
/**
 * virQEMUCapsFillDomainFeatureGICCaps:
 * @qemuCaps: QEMU capabilities
 * @domCaps: domain capabilities
 *
 * Take the information about GIC capabilities that has been obtained
 * using the 'query-gic-capabilities' QMP command and stored in @qemuCaps
 * and convert it to a form suitable for @domCaps.
 *
 * @qemuCaps contains complete information about the GIC capabilities for
 * the corresponding QEMU binary, stored as custom objects; @domCaps, on
 * the other hand, should only contain information about the GIC versions
 * available for the specific combination of architecture, machine type
 * and virtualization type. Moreover, a common format is used to store
 * information about enumerations in @domCaps, so further processing is
 * required.
 *
 * Returns: 0 on success, <0 on failure
 */
static int
virQEMUCapsFillDomainFeatureGICCaps(virQEMUCapsPtr qemuCaps,
                                    virDomainCapsPtr domCaps)
{
    virDomainCapsFeatureGICPtr gic = &domCaps->gic;
4835
    virGICVersion version;
4836 4837 4838 4839 4840 4841 4842 4843 4844

    if (domCaps->arch != VIR_ARCH_ARMV7L &&
        domCaps->arch != VIR_ARCH_AARCH64)
        return 0;

    if (STRNEQ(domCaps->machine, "virt") &&
        !STRPREFIX(domCaps->machine, "virt-"))
        return 0;

4845 4846 4847 4848 4849 4850
    for (version = VIR_GIC_VERSION_LAST - 1;
         version > VIR_GIC_VERSION_NONE;
         version--) {
        if (!virQEMUCapsSupportsGICVersion(qemuCaps,
                                           domCaps->virttype,
                                           version))
4851 4852 4853 4854
            continue;

        gic->supported = true;
        VIR_DOMAIN_CAPS_ENUM_SET(gic->version,
4855
                                 version);
4856 4857 4858 4859 4860 4861
    }

    return 0;
}


4862
int
4863 4864
virQEMUCapsFillDomainCaps(virCapsPtr caps,
                          virDomainCapsPtr domCaps,
4865
                          virQEMUCapsPtr qemuCaps,
4866
                          virFirmwarePtr *firmwares,
4867
                          size_t nfirmwares)
4868
{
4869
    virDomainCapsOSPtr os = &domCaps->os;
4870 4871
    virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
    virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
4872
    virDomainCapsDeviceGraphicsPtr graphics = &domCaps->graphics;
4873
    virDomainCapsDeviceVideoPtr video = &domCaps->video;
4874

4875 4876
    domCaps->maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps,
                                                     domCaps->machine);
4877
    if (domCaps->virttype == VIR_DOMAIN_VIRT_KVM) {
4878 4879 4880 4881 4882 4883
        int hostmaxvcpus;

        if ((hostmaxvcpus = virHostCPUGetKVMMaxVCPUs()) < 0)
            return -1;

        domCaps->maxvcpus = MIN(domCaps->maxvcpus, hostmaxvcpus);
4884
    }
4885

4886
    if (virQEMUCapsFillDomainOSCaps(os, firmwares, nfirmwares) < 0 ||
4887
        virQEMUCapsFillDomainCPUCaps(caps, qemuCaps, domCaps) < 0 ||
4888 4889 4890
        virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps,
                                            domCaps->machine, disk) < 0 ||
        virQEMUCapsFillDomainDeviceGraphicsCaps(qemuCaps, graphics) < 0 ||
4891
        virQEMUCapsFillDomainDeviceVideoCaps(qemuCaps, video) < 0 ||
4892 4893
        virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0 ||
        virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps) < 0)
4894 4895
        return -1;
    return 0;
4896
}